Page MenuHomePhabricator

No OneTemporary

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

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)

Event Timeline