Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F1880445
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
38 KB
Subscribers
None
View Options
diff --git a/action/ajax.php b/action/ajax.php
new file mode 100644
--- /dev/null
+++ b/action/ajax.php
@@ -0,0 +1,88 @@
+<?php
+
+/**
+ * DokuWiki DAVCard PlugIn - Ajax component
+ */
+
+if(!defined('DOKU_INC')) die();
+
+class action_plugin_davcard_ajax extends DokuWiki_Action_Plugin {
+
+ /**
+ * @var helper_plugin_davcard
+ */
+ private $hlp = null;
+
+ function __construct() {
+ $this->hlp =& plugin_load('helper','davcard');
+ }
+
+ function register(Doku_Event_Handler $controller) {
+ $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call_unknown');
+ }
+
+ function handle_ajax_call_unknown(&$event, $param) {
+ if($event->data != 'plugin_davcard') return;
+
+ $event->preventDefault();
+ $event->stopPropagation();
+ global $INPUT;
+
+ $action = trim($INPUT->post->str('action'));
+ $id = trim($INPUT->post->str('id'));
+ $page = trim($INPUT->post->str('page'));
+ $params = $INPUT->post->arr('params');
+ if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
+ $user = $_SERVER['REMOTE_USER'];
+ else
+ $user = null;
+
+ if(!checkSecurityToken())
+ {
+ echo "CSRF Attack.";
+ return;
+ }
+
+ $data = array();
+
+ $data['result'] = false;
+ $data['html'] = $this->getLang('unknown_error');
+
+ // Parse the requested action
+ switch($action)
+ {
+ // Add a new Contact
+ case 'newContact':
+ if($this->hlp->addContactEntryToAddressbookForPage($id, $user, $params) === true)
+ {
+ $data['result'] = true;
+ }
+ else
+ {
+ $data['result'] = false;
+ $data['html'] = $this->getLang('error_adding');
+ }
+ break;
+
+ // Edit a contact
+ case 'editContact':
+
+ break;
+ // Delete a Contact
+ case 'deleteContact':
+
+ break;
+ }
+
+ // If we are still here, JSON output is requested
+
+ //json library of DokuWiki
+ require_once DOKU_INC . 'inc/JSON.php';
+ $json = new JSON();
+
+ //set content type
+ header('Content-Type: application/json');
+ echo $json->encode($data);
+ }
+
+}
diff --git a/db/latest.version b/db/latest.version
new file mode 100644
--- /dev/null
+++ b/db/latest.version
@@ -0,0 +1,1 @@
+1
\ No newline at end of file
diff --git a/db/update0001.sql b/db/update0001.sql
new file mode 100644
--- /dev/null
+++ b/db/update0001.sql
@@ -0,0 +1,36 @@
+CREATE TABLE addressbookobjects (
+ id integer primary key asc,
+ contactdata blob,
+ uri text,
+ addressbookid integer,
+ lastmodified integer,
+ etag text,
+ size integer,
+ formattedname text,
+ structuredname text
+);
+
+CREATE TABLE addressbookchanges (
+ id integer primary key asc,
+ uri text,
+ synctoken integer,
+ addressbookid integer,
+ operation integer
+);
+
+CREATE INDEX addressbookid_synctoken ON addressbookchanges (addressbookid, synctoken);
+
+CREATE TABLE pagetoaddressbookmapping (
+ id integer primary key asc,
+ page text,
+ addressbookid integer
+);
+
+CREATE TABLE addressbooks (
+ id integer primary key asc,
+ principaluri text,
+ displayname text,
+ uri text,
+ synctoken integer,
+ description text
+);
diff --git a/helper.php b/helper.php
--- a/helper.php
+++ b/helper.php
@@ -1,114 +1,379 @@
<?php
/**
* Helper Class for the DAVCard plugin
* This helper does the actual work.
*
*/
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
class helper_plugin_davcard extends DokuWiki_Plugin {
+ protected $sqlite = null;
+
+
/**
* Constructor to load the configuration
*/
public function helper_plugin_davcard() {
+ $this->sqlite =& plugin_load('helper', 'sqlite');
+ global $conf;
+
+ if(!$this->sqlite)
+ {
+ if($conf['allowdebug'])
+ dbglog('This plugin requires the sqlite plugin. Please install it.');
+ msg('This plugin requires the sqlite plugin. Please install it.');
+ return;
+ }
+ if(!$this->sqlite->init('davcard', DOKU_PLUGIN.'davcard/db/'))
+ {
+ if($conf['allowdebug'])
+ dbglog('Error initialising the SQLite DB for DAVCard');
+ return;
+ }
}
- public function getContactByName($id, $name)
+ public function getContactByStructuredName($id, $firstname = '', $lastname = '')
+ {
+ if(strpos($id, 'webdav://') === 0)
+ {
+ $wdc =& plugin_load('helper', 'webdavclient');
+ if(is_null($wdc))
+ return $this->getLang('no_wdc');
+ $connectionId = str_replace('webdav://', '', $id);
+ $settings = $wdc->getConnection($connectionId);
+
+ if($settings === false)
+ return $this->getLang('settings_not_found');
+ if($settings['type'] !== 'contacts')
+ return $this->getLang('wrong_type');
+
+ $entries = $wdc->getAddressbookEntries($connectionId);
+ foreach($entries as $entry)
+ {
+ $contactdata = explode(';', $entry['structuredname']);
+ if(count($contactdata) != 5) // There MUST be five entries
+ continue;
+ if(($lastname != '') && ($contactdata[0] === $lastname) || $lastname === '')
+ {
+ // last name matched or no last name given
+ if(($firstname != '') && ($contactdata[1] === $firstname) || $firstname === '')
+ {
+ // first name matched too or no first name given
+ $info = $this->parseVcard($entry['contactdata']);
+ return $info;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public function getContactByFormattedName($id, $name)
{
if(strpos($id, 'webdav://') === 0)
{
$wdc =& plugin_load('helper', 'webdavclient');
if(is_null($wdc))
return $this->getLang('no_wdc');
$connectionId = str_replace('webdav://', '', $id);
$settings = $wdc->getConnection($connectionId);
if($settings === false)
return $this->getLang('settings_not_found');
if($settings['type'] !== 'contacts')
return $this->getLang('wrong_type');
$entries = $wdc->getAddressbookEntries($connectionId);
foreach($entries as $entry)
{
if(trim($entry['formattedname']) == $name)
{
$info = $this->parseVcard($entry['contactdata']);
return $info;
}
}
}
return false;
}
public function getContactByUri($id)
{
}
+ public function setAddressbookNameForPage($name, $description, $id = null, $userid = null)
+ {
+ if(is_null($id))
+ {
+ global $ID;
+ $id = $ID;
+ }
+ if(is_null($userid))
+ {
+ if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
+ {
+ $userid = $_SERVER['REMOTE_USER'];
+ }
+ else
+ {
+ $userid = uniqid('davcard-');
+ }
+ }
+ $bookid = $this->getAddressbookIdForPage($id);
+ if($bookid === false)
+ return $this->createAddressbookForPage($name, $description, $id, $userid);
+
+ $query = "UPDATE addressbooks SET displayname = ?, description = ? WHERE id = ?";
+ $res = $this->sqlite->query($query, $name, $description, $bookid);
+ if($res !== false)
+ return true;
+ return false;
+ }
+
+ public function getAddressbookIdForPage($id = null)
+ {
+ if(is_null($id))
+ {
+ global $ID;
+ $id = $ID;
+ }
+
+ $query = "SELECT addressbookid FROM pagetoaddressbookmapping WHERE page = ?";
+ $res = $this->sqlite->query($query, $id);
+ $row = $this->sqlite->res2row($res);
+ if(isset($row['addressbookid']))
+ {
+ $calid = $row['addressbookid'];
+ return $calid;
+ }
+ return false;
+ }
+
+ public function createAddressbookForPage($name, $description, $id = null, $userid = null)
+ {
+ if(is_null($id))
+ {
+ global $ID;
+ $id = $ID;
+ }
+ if(is_null($userid))
+ {
+ if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
+ {
+ $userid = $_SERVER['REMOTE_USER'];
+ }
+ else
+ {
+ $userid = uniqid('davcard-');
+ }
+ }
+ $values = array('principals/'.$userid,
+ $name,
+ str_replace(array('/', ' ', ':'), '_', $id),
+ $description,
+ 1);
+ $query = "INSERT INTO addressbooks (principaluri, displayname, uri, description, synctoken) ".
+ "VALUES (?, ?, ?, ?, ?)";
+ $res = $this->sqlite->query($query, $values);
+ if($res === false)
+ return false;
+
+ // Get the new addressbook ID
+ $query = "SELECT id FROM addressbooks WHERE principaluri = ? AND displayname = ? AND ".
+ "uri = ? AND description = ? AND synctoken = ?";
+ $res = $this->sqlite->query($query, $values);
+ $row = $this->sqlite->res2row($res);
+
+ // Update the pagetocalendarmapping table with the new calendar ID
+ if(isset($row['id']))
+ {
+ $query = "INSERT INTO pagetoaddressbookmapping (page, addressbookid) VALUES (?, ?)";
+ $res = $this->sqlite->query($query, $id, $row['id']);
+ return ($res !== false);
+ }
+
+ return false;
+ }
+
+ public function addContactEntryToAddressbookForPage($id, $user, $params)
+ {
+ require_once(DOKU_PLUGIN.'davcard/vendor/autoload.php');
+
+ $vcard = new \Sabre\VObject\Component\VCard();
+ $formattedname = $params['firstname'].' '.$params['lastname']; // FIXME: Make this configurable?
+ $structuredname = array($params['lastname'], $params['firstname'], '', '', '');
+ $vcard->FN = $formattedname;
+ if($params['cellphone'] != '')
+ {
+ $vcard->add('TEL', $params['cellphone'], array('type' => 'cell'));
+ }
+ if($params['phone'] != '')
+ {
+ $vcard->add('TEL', $params['phone'], array('type' => 'home'));
+ }
+ $vcard->N = $structuredname;
+
+ $vcard->add('ADR', array('', '', $params['street'], $params['city'], '', $params['zipcode'], $params['country']), array('type' => 'home'));
+
+ $contactdata = $vcard->serialize();
+
+ if(strpos($id, 'webdav://') === 0)
+ {
+ $wdc =& plugin_load('helper', 'webdavclient');
+ if(is_null($wdc))
+ return false;
+ $connectionId = str_replace('webdav://', '', $id);
+ return $wdc->addAddressbookEntry($connectionId, $contactdata);
+ }
+ else
+ {
+ $addressbookid = $this->getAddressbookIdForPage($id);
+ $uri = uniqid('dokuwiki-').'.vcf';
+ $now = new \DateTime();
+ $query = "INSERT INTO addressbookobjects (contactdata, uri, addressbookid, lastmodified, etag, size, formattedname, structuredname) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
+ $res = $this->sqlite->query($query,
+ $contactdata,
+ $uri,
+ $addressbookid,
+ $now->getTimestamp(),
+ md5($contactdata),
+ strlen($contactdata),
+ $formattedname,
+ implode(';', $structuredname)
+ );
+ // If successfully, update the sync token database
+ if($res !== false)
+ {
+ $this->updateSyncTokenLog($addressbookid, $uri, 'added');
+ return true;
+ }
+ }
+ }
+
private function parseVcard($card)
{
require_once(DOKU_PLUGIN.'davcard/vendor/autoload.php');
$vObject = \Sabre\VObject\Reader::read($card);
$formattedname = '';
$structuredname = '';
$tel = array();
$addr = array();
$mail = array();
if(isset($vObject->FN))
$formattedname = (string)$vObject->FN;
if(isset($vObject->N))
$structuredname = join(';', $vObject->N->getParts());
if(isset($vObject->TEL))
{
foreach($vObject->TEL as $number)
{
if(isset($number['TYPE']))
$tel[(string)$number['TYPE']] = (string)$number;
else
$tel[] = (string)$number;
}
}
if(isset($vObject->ADR))
{
foreach($vObject->ADR as $adr)
{
if(isset($adr['TYPE']))
$addr[(string)$adr['TYPE']] = $adr->getParts();
else
$addr[] = $adr->getParts();
}
}
if(isset($vObject->EMAIL))
{
foreach($vObject->EMAIL as $email)
{
if(isset($email['TYPE']))
$mail[(string)$email['TYPE']] = (string)$email;
else
$mail[] = (string)$email;
}
}
return array(
'formattedname' => $formattedname,
'structuredname' => $structuredname,
'tel' => $tel,
'mail' => $mail,
'addr' => $addr
);
}
+
+ public function getAddressbookSettings($addressbookid)
+ {
+ $query = "SELECT id, principaluri, displayname, uri, description, synctoken FROM addressbooks WHERE id= ? ";
+ $res = $this->sqlite->query($query, $addressbookid);
+ $row = $this->sqlite->res2row($res);
+ return $row;
+ }
+
+ public function getSyncTokenForAddressbook($addressbookid)
+ {
+ $row = $this->getAddressbookSettings($addressbookid);
+ if(isset($row['synctoken']))
+ return $row['synctoken'];
+ return false;
+ }
+
+ /**
+ * Helper function to convert the operation name to
+ * an operation code as stored in the database
+ *
+ * @param string $operationName The operation name
+ *
+ * @return mixed The operation code or false
+ */
+ public function operationNameToOperation($operationName)
+ {
+ switch($operationName)
+ {
+ case 'added':
+ return 1;
+ break;
+ case 'modified':
+ return 2;
+ break;
+ case 'deleted':
+ return 3;
+ break;
+ }
+ return false;
+ }
+ private function updateSyncTokenLog($addressbookid, $uri, $operation)
+ {
+ $currentToken = $this->getSyncTokenForAddressbook($addressbookid);
+ $operationCode = $this->operationNameToOperation($operation);
+ if(($operationCode === false) || ($currentToken === false))
+ return false;
+ $values = array($uri,
+ $currentToken,
+ $addressbookid,
+ $operationCode
+ );
+ $query = "INSERT INTO addressbookchanges (uri, synctoken, addressbookid, operation) VALUES(?, ?, ?, ?)";
+ $res = $this->sqlite->query($query, $uri, $currentToken, $addressbookid, $operationCode);
+ if($res === false)
+ return false;
+ $currentToken++;
+ $query = "UPDATE addressbooks SET synctoken = ? WHERE id = ?";
+ $res = $this->sqlite->query($query, $currentToken, $addressbookid);
+ return ($res !== false);
+ }
}
diff --git a/lang/en/lang.php b/lang/en/lang.php
--- a/lang/en/lang.php
+++ b/lang/en/lang.php
@@ -1,34 +1,58 @@
<?php
/**
* English language file for DAVCard
*
* @author Andreas Böhler <dev@aboehler.at>
*/
$lang['unknown_error'] = 'Unknown Error';
$lang['id_name_not_set'] = 'Either ID or Name must be set';
$lang['loading_via_ajax'] = 'Loadig Contact Data...';
$lang['no_wdc'] = 'Loading webdavclient PlugIn failed.';
$lang['settings_not_found'] = 'The requested WebDAV connection was not found';
$lang['wrong_type'] = 'The requested WebDAV connection is not of type contact';
$lang['contact_not_found'] = 'The requested contact was not found';
+$lang['error_adding'] = 'Error adding contact';
$lang['telvoice'] = 'Voice';
$lang['telhome'] = 'Home';
$lang['telmsg'] = 'Message';
$lang['telwork'] = 'Work';
$lang['telpref'] = 'preferred';
$lang['telfax'] = 'Fax';
$lang['telcell'] = 'Cell';
$lang['telvideo'] = 'Video';
$lang['telpager'] = 'Pager';
$lang['telbbs'] = 'BBS';
$lang['telmodem'] = 'Modem';
$lang['telcar'] = 'Car';
$lang['telisdn'] = 'ISDN';
$lang['telpcs'] = 'PCS';
$lang['adrintl'] = 'International';
$lang['adrpostal'] = 'Postal';
$lang['adrparcel'] = 'Parcel';
$lang['adrwork'] = 'Work';
$lang['adrdom'] = 'Domestic';
$lang['adrhome'] = 'Home';
$lang['adrpref'] = 'preferred';
+$lang['created_by_davcard'] = 'Created by DAVCard';
+$lang['add_new'] = 'Add new entry';
+$lang['edit'] = 'Edit';
+$lang['js']['confirmation'] = 'Confirmation';
+$lang['js']['yes'] = 'Yes';
+$lang['js']['no'] = 'No';
+$lang['js']['cancel'] = 'Cancel';
+$lang['js']['create'] = 'Create';
+$lang['js']['info'] = 'Info';
+$lang['js']['ok'] = 'OK';
+$lang['js']['edit'] = 'Edit';
+$lang['js']['edit_entry'] = 'Edit Entry';
+$lang['js']['create_entry'] = 'Create Entry';
+$lang['js']['really_delete_this_entry'] = 'Really delete this entry?';
+$lang['js']['firstname'] = 'First Name';
+$lang['js']['lastname'] = 'Last Name';
+$lang['js']['city'] = 'City';
+$lang['js']['zipcode'] = 'Zip Code';
+$lang['js']['cellphone'] = 'Cell Phone';
+$lang['js']['phone'] = 'Phone';
+$lang['js']['street'] = 'Street';
+$lang['js']['country'] = 'Country';
+$lang['js']['email'] = 'Email';
diff --git a/script.js b/script.js
new file mode 100644
--- /dev/null
+++ b/script.js
@@ -0,0 +1,285 @@
+jQuery(function() {
+
+ // Attach to addressbook links
+ var addressbookpage = jQuery('#davcardAddressbookList').data('addressbookpage');
+ if(!addressbookpage) return;
+ dw_davcard__modals.page = addressbookpage;
+
+ jQuery('div.davcardAddressbookAddNew a').each(function() {
+ var $link = jQuery(this);
+ var href = $link.attr('href');
+ if (!href) return;
+
+ $link.click(
+ function(e) {
+ dw_davcard__modals.showEditContactDialog(null, false);
+ e.preventDefault();
+ return '';
+ }
+ );
+ }
+ );
+});
+
+/**
+ * This holds all modal windows that DAVCal uses.
+ */
+var dw_davcard__modals = {
+ $editContactDialog: null,
+ $confirmDialog: null,
+ page: null,
+ uri: null,
+ action: null,
+ completeCb: null,
+ msg: null,
+
+ showEditContactDialog : function(entry, edit) {
+ if(dw_davcard__modals.$editContactDialog)
+ return;
+
+ var title = '';
+ var dialogButtons = {};
+
+ if(edit)
+ {
+ title = LANG.plugins.davcard['edit_entry'];
+ dialogButtons[LANG.plugins.davcard['edit']] = function() {
+
+ var postArray = { };
+ var pageid = dw_davcard__modals.page;
+
+ jQuery("input.dw_davcard__editcontact").each(function() {
+ if(jQuery(this).attr('type') == 'checkbox')
+ {
+ postArray[jQuery(this).prop('name')] = jQuery(this).prop('checked') ? 1 : 0;
+ }
+ else
+ {
+ postArray[jQuery(this).prop('name')] = jQuery(this).val();
+ }
+ });
+ jQuery('#dw_davcard__ajaxedit').html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />');
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'plugin_davcard',
+ id: pageid,
+ page: dw_davcard__modals.page,
+ action: 'editContact',
+ params: postArray,
+ sectok: JSINFO.plugin.davcal['sectok']
+ },
+ function(data)
+ {
+ var result = data['result'];
+ var html = data['html'];
+ jQuery('#dw_davcard__ajaxedit').html(html);
+ if(result === true)
+ {
+ dw_davcard__modals.hideEditContactDialog();
+ location.reload();
+ }
+ }
+ );
+ };
+ dialogButtons[LANG.plugins.davcal['delete']] = function() {
+ dw_davcard__modals.action = 'deleteContact';
+ dw_davcard__modals.msg = LANG.plugins.davcard['really_delete_this_entry'];
+ dw_davcard__modals.completeCb = function(data) {
+ var result = data['result'];
+ if(result === true)
+ {
+ dw_davcard__modals.hideEditContactDialog();
+ location.reload();
+ }
+ };
+ dw_davcard__modals.showDialog(true);
+ };
+ }
+ else
+ {
+ title = LANG.plugins.davcard['create_entry'];
+ dialogButtons[LANG.plugins.davcard['create']] = function() {
+
+ var postArray = { };
+ var pageid = dw_davcard__modals.page;
+
+ jQuery("input.dw_davcard__editcontact").each(function() {
+ if(jQuery(this).attr('type') == 'checkbox')
+ {
+ postArray[jQuery(this).prop('name')] = jQuery(this).prop('checked') ? 1 : 0;
+ }
+ else
+ {
+ postArray[jQuery(this).prop('name')] = jQuery(this).val();
+ }
+ });
+ jQuery('#dw_davcard__ajaxedit').html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />');
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'plugin_davcard',
+ id: pageid,
+ page: dw_davcard__modals.page,
+ action: 'newContact',
+ params: postArray,
+ sectok: JSINFO.plugin.davcard['sectok']
+ },
+ function(data)
+ {
+ var result = data['result'];
+ var html = data['html'];
+ jQuery('#dw_davcard__ajaxedit').html(html);
+ if(result === true)
+ {
+ dw_davcard__modals.hideEditContactDialog();
+ location.reload();
+ }
+ }
+ );
+ };
+ }
+ dialogButtons[LANG.plugins.davcard['cancel']] = function() {
+ dw_davcard__modals.hideEditContactDialog();
+ };
+ dw_davcard__modals.$editContactDialog = jQuery(document.createElement('div'))
+ .dialog({
+ autoOpen: false,
+ draggable: true,
+ // fix for dragging: http://stackoverflow.com/questions/17247486/jquery-ui-dialog-dragging-issues
+ drag: function(event, ui) {
+ var fixPix = jQuery(document).scrollTop();
+ iObj = ui.position;
+ iObj.top = iObj.top - fixPix;
+ jQuery(this).closest(".ui-dialog").css("top", iObj.top + "px");
+ },
+ title: title,
+ resizable: true,
+ buttons: dialogButtons,
+ })
+ .html(
+ '<div><table>' +
+ // FIXME: '<tr><td>' + LANG.plugins.davcal['calendar'] + '</td><td><select id="dw_davcal__editevent_calendar"></select></td></tr>' +
+ '<tr><td>' + LANG.plugins.davcard['firstname'] + '</td><td><input type="text" id="dw_davcard__firstname_edit" name="firstname" class="dw_davcard__editcontact"></td></tr>' +
+ '<tr><td>' + LANG.plugins.davcard['lastname'] + '</td><td><input type="text" id="dw_davcard__lastname_edit" name="lastname" class="dw_davcard__editcontact"></td></tr>' +
+ '<tr><td>' + LANG.plugins.davcard['cellphone'] + '</td><td><input type="text" id="dw_davcard__cellphone_edit" name="cellphone" class="dw_davcard__editcontact"></td></tr>' +
+ '<tr><td>' + LANG.plugins.davcard['phone'] + '</td><td><input type="text" id="dw_davcard__phone_edit" name="phone" class="dw_davcard__editcontact"></td></tr>' +
+ '<tr><td>' + LANG.plugins.davcard['email'] + '</td><td><input type="text" id="dw_davcard__email_edit" name="email" class="dw_davcard__editcontact"></td></tr>' +
+ '<tr><td>' + LANG.plugins.davcard['street'] + '</td><td><input type="text" id="dw_davcard__street_edit" name="street" class="dw_davcard__editcontact"></td></tr>' +
+ '<tr><td>' + LANG.plugins.davcard['zipcode'] + '</td><td><input type="text" id="dw_davcard__zipcode_edit" name="zipcode" class="dw_davcard__editcontact"></td></tr>' +
+ '<tr><td>' + LANG.plugins.davcard['city'] + '</td><td><input type="text" id="dw_davcard__city_edit" name="city" class="dw_davcard__editcontact"></td></tr>' +
+ '<tr><td>' + LANG.plugins.davcard['country'] + '</td><td><input type="text" id="dw_davcard__country_edit" name="country" class="dw_davcard__editcontact"></td></tr>' +
+ '</table>' +
+ '<input type="hidden" name="uri" id="dw_davcard__uid_edit" class="dw_davcard__editcontact">' +
+ '</div>' +
+ '<div id="dw_davcard__ajaxedit"></div>'
+ )
+ .parent()
+ .attr('id','dw_davcard__edit')
+ .show()
+ .appendTo('.dokuwiki:first');
+
+ jQuery('#dw_davcard__edit').position({
+ my: "center",
+ at: "center",
+ of: window
+ });
+
+ // attach event handlers
+ jQuery('#dw_davcard__edit .ui-dialog-titlebar-close').click(function(){
+ dw_davcard__modals.hideEditContactDialog();
+ });
+
+
+ },
+
+ hideEditContactDialog : function() {
+ dw_davcard__modals.$editContactDialog.empty();
+ dw_davcard__modals.$editContactDialog.remove();
+ dw_davcard__modals.$editContactDialog = null;
+ },
+
+ hideDialog: function() {
+ dw_davcard__modals.$dialog.empty();
+ dw_davcard__modals.$dialog.remove();
+ dw_davcard__modals.$dialog = null;
+ },
+
+ showDialog : function(confirm)
+ {
+ if(dw_davcard__modals.$confirmDialog)
+ return;
+
+ var dialogButtons = {};
+ var title = '';
+ if(confirm)
+ {
+ title = LANG.plugins.davcard['confirmation'];
+ var pageid = dw_davcard__modals.page;
+
+ dialogButtons[LANG.plugins.davcard['yes']] = function() {
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'plugin_davcard',
+ id: pageid,
+ page: dw_davcard__modals.page,
+ action: dw_davcard__modals.action,
+ params: {
+ uri: dw_davcard__modals.uri
+ },
+ sectok: JSINFO.plugin.davcard['sectok']
+ },
+ function(data)
+ {
+ dw_davcard__modals.completeCb(data);
+ }
+ );
+ dw_davcard__modals.hideDialog();
+ };
+ dialogButtons[LANG.plugins.davcard['cancel']] = function() {
+ dw_davcard__modals.hideDialog();
+ };
+ }
+ else
+ {
+ title = LANG.plugins.davcard['info'];
+ dialogButtons[LANG.plugins.davcard['ok']] = function() {
+ dw_davcard__modals.hideDialog();
+ };
+ }
+ dw_davcard__modals.$dialog = jQuery(document.createElement('div'))
+ .dialog({
+ autoOpen: false,
+ draggable: true,
+ //fix for dragging: http://stackoverflow.com/questions/17247486/jquery-ui-dialog-dragging-issues
+ drag: function(event, ui) {
+ var fixPix = jQuery(document).scrollTop();
+ iObj = ui.position;
+ iObj.top = iObj.top - fixPix;
+ jQuery(this).closest(".ui-dialog").css("top", iObj.top + "px");
+ },
+ title: title,
+ resizable: true,
+ buttons: dialogButtons,
+ })
+ .html(
+ '<div>' + dw_davcard__modals.msg + '</div>'
+ )
+ .parent()
+ .attr('id','dw_davcard__confirm')
+ .show()
+ .appendTo('.dokuwiki:first');
+
+ jQuery('#dw_davcard__confirm').position({
+ my: "center",
+ at: "center",
+ of: window
+ });
+ // attach event handlers
+ jQuery('#dw_davcard__confirm .ui-dialog-titlebar-close').click(function(){
+ dw_davcard__modals.hideDialog();
+ });
+ },
+
+};
\ No newline at end of file
diff --git a/syntax/book.php b/syntax/book.php
new file mode 100644
--- /dev/null
+++ b/syntax/book.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * DokuWiki Plugin DAVCard (Book Syntax Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Andreas Böhler <dev@aboehler.at>
+ */
+
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_davcard_book extends DokuWiki_Syntax_Plugin {
+
+ protected $hlp = null;
+
+ // Load the helper plugin
+ public function syntax_plugin_davcard_book() {
+ $this->hlp =& plugin_load('helper', 'davcard');
+ }
+
+
+ /**
+ * What kind of syntax are we?
+ */
+ function getType(){
+ return 'substition';
+ }
+
+ /**
+ * What about paragraphs?
+ */
+ function getPType(){
+ return 'normal';
+ }
+
+ /**
+ * Where to sort in?
+ */
+ function getSort(){
+ return 165;
+ }
+
+ /**
+ * Connect pattern to lexer
+ */
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('\{\{davcardbook>[^}]*\}\}',$mode,'plugin_davcard_book');
+ }
+
+ /**
+ * Handle the match
+ */
+ function handle($match, $state, $pos, Doku_Handler $handler){
+ global $ID;
+ $options = trim(substr($match,14,-2));
+ $options = explode(',', $options);
+ $data = array('name' => $ID,
+ 'description' => $this->getLang('created_by_davcard'),
+ 'id' => '',
+ );
+ foreach($options as $option)
+ {
+ list($key, $val) = explode('=', $option);
+ $key = strtolower(trim($key));
+ $val = trim($val);
+ switch($key)
+ {
+ case 'id':
+ if(!in_array($val, $data['id']))
+ $data['id'][] = $val;
+ break;
+ default:
+ $data[$key] = $val;
+ }
+ }
+ // Handle the default case when the user didn't enter a different ID
+ if(empty($data['id']))
+ {
+ $data['id'] = array($ID);
+ }
+ // Only update the addressbook name/description if the ID matches the page ID.
+ // Otherwise, the addressbook is included in another page and we don't want
+ // to interfere with its data.
+ if(in_array($ID, $data['id']))
+ {
+ if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
+ $username = $_SERVER['REMOTE_USER'];
+ else
+ $username = uniqid('davcard-');
+ $this->hlp->setAddressbookNameForPage($data['name'], $data['description'], $ID, $username);
+ }
+
+ $meta = p_get_metadata($ID, 'plugin_davcard');
+ if(is_null($meta))
+ $meta = array();
+ $meta['addressbooks'] = $data;
+ p_set_metadata($ID, array('plugin_davcard' => $meta));
+ }
+
+ /**
+ * Create output
+ */
+ function render($format, Doku_Renderer $R, $data)
+ {
+ global $ID;
+ if($format !== 'xhtml')
+ return false;
+
+ // FIXME: Check if the user has write permissions on the page!
+ // Should we force per-user caching?
+
+ $R->doc .= '<div class="davcardAddressbookAddNew"><a href="#" class="davcardAddressbookAddNew">'.$this->getLang('add_new').'</a></div>';
+
+ $R->doc .= '<div id="davcardAddressbookList" data-addressbookpage="'.$ID.'">';
+
+ $R->doc .= '</div>';
+
+ }
+
+
+
+}
+
+// vim:ts=4:sw=4:et:enc=utf-8:
diff --git a/syntax/card.php b/syntax/card.php
--- a/syntax/card.php
+++ b/syntax/card.php
@@ -1,164 +1,173 @@
<?php
/**
* DokuWiki Plugin DAVCard (Contact Syntax Component)
*
* @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
* @author Andreas Böhler <dev@aboehler.at>
*/
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
class syntax_plugin_davcard_card extends DokuWiki_Syntax_Plugin {
protected $hlp = null;
// Load the helper plugin
public function syntax_plugin_davcard_card() {
$this->hlp =& plugin_load('helper', 'davcard');
}
/**
* What kind of syntax are we?
*/
function getType(){
return 'substition';
}
/**
* What about paragraphs?
*/
function getPType(){
return 'normal';
}
/**
* Where to sort in?
*/
function getSort(){
return 165;
}
/**
* Connect pattern to lexer
*/
function connectTo($mode) {
$this->Lexer->addSpecialPattern('\{\{davcard>[^}]*\}\}',$mode,'plugin_davcard_card');
}
/**
* Handle the match
*/
function handle($match, $state, $pos, Doku_Handler $handler){
global $ID;
$options = trim(substr($match,10,-2));
$options = explode(',', $options);
$data = array('name' => '',
'id' => '',
+ 'firstname' => '',
+ 'lastname' => '',
);
foreach($options as $option)
{
list($key, $val) = explode('=', $option);
$key = strtolower(trim($key));
$val = trim($val);
switch($key)
{
default:
$data[$key] = $val;
}
}
- if($data['id'] === '' && $data['name'] === '')
+ if($data['id'] === '')
{
- msg($this->getLang('id_name_not_set'), -1);
+ if(($data['name'] === '') || (($data['firstname'] === '') && ($data['lastname'] === '')))
+ {
+ msg($this->getLang('id_name_not_set'), -1);
+ }
}
return $data;
}
/**
* Create output
*/
function render($format, Doku_Renderer $R, $data) {
if($format == 'metadata')
{
if(strpos($data['id'], 'webdav://') === 0)
{
$connectionId = str_replace('webdav://', '', $data['id']);
$R->meta['plugin_davcard']['webdavclient'][] = $connectionId;
return true;
}
}
if($format != 'xhtml')
return false;
$contactdata = array();
if(strpos($data['id'], 'webdav://') === 0)
{
if($data['name'] !== '')
{
- $contactdata = $this->hlp->getContactByName($data['id'], $data['name']);
+ $contactdata = $this->hlp->getContactByFormattedName($data['id'], $data['name']);
+ }
+ elseif(($data['firstname'] !== '') || ($data['lastname'] !== ''))
+ {
+ $contactdata = $this->hlp->getContactByStructuredName($data['id'], $data['firstname'], $data['lastname']);
}
}
$R->doc .= '<a class="url fn plugin_davcard_url" href="#">'.$contactdata['formattedname'];
$R->doc .= '<span class="plugin_davcard_popup vcard">';
if(count($contactdata['addr']) > 0)
{
$R->doc .= '<span class="adr">';
foreach($contactdata['addr'] as $type => $addr)
{
$R->doc .= '<span class="type">'.$this->getLang('adr'.strtolower($type)).'</span>';
if($addr[2] != '')
{
$R->doc .= '<span class="street-address">'.$addr[2].'</span><br>';
}
if($addr[5] != '')
{
$R->doc .= '<span class="postal-code">'.$addr[5].' </span>';
}
if($addr[3] != '')
{
$R->doc .= '<span class="locality">'.$addr[3].'</span><br>';
}
if($addr[6] != '')
{
$R->doc .= '<span class="country-name">'.$addr[6].'</span>';
}
}
$R->doc .= '</span>';
}
if(count($contactdata['tel']) > 0)
{
$R->doc .= '<span class="tel">';
foreach($contactdata['tel'] as $type => $number)
{
$R->doc .= '<span class="type">'.$this->getLang('tel'.strtolower($type)).' </span>';
$R->doc .= $number.'<br>';
}
$R->doc .= '</span>';
}
if(count($contactdata['mail']) > 0)
{
- $R->doc .= '<span class="email_outer"><span class="email_type">EMail:</span>';
+ $R->doc .= '<span class="email_outer"><span class="email_type">EMail</span>';
foreach($contactdata['mail'] as $type => $mail)
{
$R->doc .= '<span class="email">'.$mail.'</span><br>';
}
$R->doc .= '</span>';
}
$R->doc .= '</span>';
$R->doc .= '</a>';
}
}
// vim:ts=4:sw=4:et:enc=utf-8:
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Jan 24, 5:12 AM (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
532485
Default Alt Text
(38 KB)
Attached To
rDAVCARD DokuWiki davcard PlugIn
Event Timeline
Log In to Comment