diff --git a/action/ajax.php b/action/ajax.php
--- a/action/ajax.php
+++ b/action/ajax.php
@@ -1,274 +1,274 @@
*/
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');
- $acl = auth_quickaclcheck($id);
+ $acl = $this->hlp->checkAddressbookPermission($id);
if($acl > AUTH_READ)
{
$write = true;
}
elseif($acl < AUTH_READ)
{
$data['result'] = false;
$data['html'] = $this->getLang('no_permission');
// Overwrite $action to bypass switch statement below
$action = 'invalid';
}
else
{
$write = false;
}
// Parse the requested action
switch($action)
{
// Add a new Contact
case 'newContact':
if($write && ($this->hlp->addContactEntryToAddressbookForPage($id, $user, $params) === true))
{
$data['result'] = true;
}
else
{
$data['result'] = false;
if(!$write)
$data['html'] = $this->getLang('no_permission');
else
$data['html'] = $this->getLang('error_adding');
}
break;
// Retrieve contact details
case 'getContactDetails':
$contactdata = $this->hlp->getContactByUri($id, $params['uri']);
if($contactdata['result'] === true)
{
// When we support pictures for editing contacts,
// we need to use the following line:
// $contactdata['photo'] = base64_encode($contactdata['photo']);
// For now, we just save bandwidth :)
unset($contactdata['photo']);
$data['result'] = true;
$data['contactdata'] = $contactdata;
}
else
{
$data['result'] = false;
$data['html'] = sprintf($this->getLang('contact_not_found'), 'ID='.$id.' URI='.$params['uri']);
}
break;
// Edit a contact
case 'editContact':
if($write && ($this->hlp->editContactEntryToAddressbookForPage($id, $user, $params['uri'], $params) === true))
{
$data['result'] = true;
}
else
{
$data['result'] = false;
if(!$write)
$data['html'] = $this->getLang('no_permission');
else
$data['html'] = $this->getLang('error_editing');
}
break;
// Delete a Contact
case 'deleteContact':
if($write && ($this->hlp->deleteContactEntryToAddressbookForPage($id, $user, $params['uri']) === true))
{
$data['result'] = true;
}
else
{
$data['result'] = false;
if(!$write)
$data['html'] = $this->getLang('no_permission');
else
$data['html'] = $this->getLang('error_deleting');
}
break;
// Get AJAX popup
case 'getContactAjax':
$contactdata = $this->hlp->getContactByUri($id, $params['uri']);
$cardpattern = $this->getConf('popup_content');
if($contactdata['result'] === false)
{
echo hsc($contactdata['formattedname']);
return;
}
echo '
';
return;
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/helper.php b/helper.php
--- a/helper.php
+++ b/helper.php
@@ -1,830 +1,862 @@
*/
// 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() {
}
/** Establish and initialize the database if not already done
* @return sqlite interface or false
*/
private function getDB()
{
if($this->sqlite === null)
{
$this->sqlite = plugin_load('helper', 'sqlite');
if(!$this->sqlite)
{
dbglog('This plugin requires the sqlite plugin. Please install it.');
msg('This plugin requires the sqlite plugin. Please install it.', -1);
return false;
}
- if(!$this->sqlite->init('dvacard', DOKU_PLUGIN.'davcard/db/'))
+ if(!$this->sqlite->init('davcard', DOKU_PLUGIN.'davcard/db/'))
{
$this->sqlite = null;
dbglog('Error initialising the SQLite DB for davcard');
return false;
}
}
return $this->sqlite;
}
/**
* Retrieve a contact by specifying details like the name
*
* @param int $id The address book ID
* @param string $type The type to look for
* @param array $params The parameter array
*
* @return array An array containing the results
*/
private function getContactByDetails($id, $type, $params = array())
{
$write = false;
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 array('formattedname' => $this->getLang('settings_not_found'), 'result' => false);
if($settings['type'] !== 'contacts')
return array('formattedname' => $this->getLang('wrong_type'), 'result' => false);
$entries = $wdc->getAddressbookEntries($connectionId);
$write = $settings['write'];
}
else
{
$acl = auth_quickaclcheck($id);
if($acl > AUTH_READ)
{
$write = true;
}
elseif($acl < AUTH_READ)
{
return array('formattedname' => $this->getLang('no_permission'), 'result' => false);
}
else
{
$write = false;
}
$addressbookid = $this->getAddressbookIdForPage($id);
$entries = $this->getAddressbookEntries($addressbookid);
}
foreach($entries as $entry)
{
switch($type)
{
case 'structuredname':
$contactdata = explode(';', strtolower($entry['structuredname']));
if(count($contactdata) < 2) // We need at least first and last name
return array('formattedname' => sprintf($this->getLang('contact_not_found'), $params['firstname']. ' '.$params['lastname']), 'result' => false);
if(($params['lastname'] != '') &&
($contactdata[0] === $params['lastname'])
|| $params['lastname'] === '')
{
// last name matched or no last name given
if(($params['firstname'] != '') &&
($contactdata[1] === $params['firstname'])
|| $params['firstname'] === '')
{
// first name matched too or no first name given
$info = $this->parseVcard($entry['contactdata'], $entry['uri'], $write);
return $info;
}
}
break;
case 'formattedname':
if(trim(strtolower($entry['formattedname'])) == $params['formattedname'])
{
$info = $this->parseVcard($entry['contactdata'], $entry['uri'], $write);
return $info;
}
break;
case 'email':
$info = $this->parseVcard($entry['contactdata'], $entry['uri'], $write);
foreach($info['mail'] as $data)
{
if(trim(strtolower($data['mail'])) === $params['email'])
return $info;
}
break;
}
}
return array('formattedname' => sprintf($this->getLang('contact_not_found'), $this->getLang('invalid_options')), 'result' => false);
}
/**
* Retreive all address book entries
*
* @param int $id The addressbook ID to retrieve
*
* @return array All address book entries
*/
public function getAddressbookEntries($id)
{
$sqlite = $this->getDB();
if(!$sqlite)
return false;
$query = "SELECT contactdata, uri, formattedname, structuredname FROM addressbookobjects WHERE addressbookid = ? ORDER BY formattedname ASC";
$res = $sqlite->query($query, $id);
return $sqlite->res2arr($res);
}
/**
* Retrieve a contact by the structured name
*
* @param string $id The addressbook ID to work with
* @param string $firstname The contact's first name
* @param string $lastname The contact's last name
*
* @return array The contact's details
*/
public function getContactByStructuredName($id, $firstname = '', $lastname = '')
{
return $this->getContactByDetails($id, 'structuredname',
array('firstname' => strtolower($firstname), 'lastname' => strtolower($lastname)));
}
/**
* Retrieve a contact by e-mail address
*
* @param string $id The address book ID
* @param string $email The E-Mail address
*
* @return array The contact's details
*/
public function getContactByEmail($id, $email)
{
// FIXME: Maybe it's a good idea to save the e-mail in the database as well!
return $this->getContactByDetails($id, 'email', array('email' => strtolower($email)));
}
/**
* Retrieve a contact by formatted name
*
* @param string $id The address book ID
* @param string $name The contact's formatted name
*
* @return array The contact's details
*/
public function getContactByFormattedName($id, $name)
{
return $this->getContactByDetails($id, 'formattedname', array('formattedname' => strtolower($name)));
}
/**
* Retrieve a contact object by its URI
*
* @param string $ID The address book ID
* @param string $uri The object URI
*
* @return array An array containing the result
*/
public function getContactByUri($id, $uri)
{
$write = false;
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 array('formattedname' => $this->getLang('settings_not_found'), 'result' => false);
if($settings['type'] !== 'contacts')
return array('formattedname' => $this->getLang('wrong_type'), 'result' => false);
$row = $wdc->getAddressbookEntryByUri($connectionId, $uri);
$write = $settings['write'];
}
else
{
$acl = auth_quickaclcheck($id);
if($acl > AUTH_READ)
{
$write = true;
}
elseif($acl < AUTH_READ)
{
return array('formattedname' => $this->getLang('no_permission'), 'result' => false);
}
else
{
$write = false;
}
$addressbookid = $this->getAddressbookIdForPage($id);
$row = $this->getAddressbookEntryByUri($addressbookid, $uri);
}
if($row === false)
return array('formattedname' => sprintf($this->getLang('contact_not_found'), 'ID='.$id.' URI='.$uri), 'result' => false);
$info = $this->parseVcard($row['contactdata'], $row['uri'], $write);
$info['result'] = true;
return $info;
}
/**
* Retrieve an address book entry by URI (low-level version)
*
* @param int $id The address book ID
* @param string $uri The object URI
*
* @return array The contact's details
*/
private function getAddressbookEntryByUri($id, $uri)
{
$sqlite = $this->getDB();
if(!$sqlite)
return false;
$query = "SELECT contactdata, addressbookid, etag, uri, formattedname, structuredname FROM addressbookobjects WHERE addressbookid = ? AND uri = ?";
$res = $sqlite->query($query, $id, $uri);
return $sqlite->res2row($res);
}
/**
* Set the addressbook name for a given page
*
* @param string $name The name to set
* @param string $description The address book description
* @param int $id (optional) The page ID
* @param string $userid (optional) The user's ID
*
* @return boolean true on success, otherwise false
*/
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);
$sqlite = $this->getDB();
if(!$sqlite)
return false;
$query = "UPDATE addressbooks SET displayname = ?, description = ? WHERE id = ?";
$res = $sqlite->query($query, $name, $description, $bookid);
if($res !== false)
return true;
return false;
}
/**
* Get the address book ID associated with a given page
*
* @param string $id (optional) The page ID
*
* @return mixed The address book ID or false
*/
public function getAddressbookIdForPage($id = null)
{
if(is_null($id))
{
global $ID;
$id = $ID;
}
$sqlite = $this->getDB();
if(!$sqlite)
return false;
$query = "SELECT addressbookid FROM pagetoaddressbookmapping WHERE page = ?";
$res = $sqlite->query($query, $id);
$row = $sqlite->res2row($res);
if(isset($row['addressbookid']))
{
$addrbkid = $row['addressbookid'];
return $addrbkid;
}
return false;
}
/**
* Create a new address book for a given page
*
* @param string $name The name of the new address book
* @param string $description The address book's description
* @param string $id (optional) The page ID
* @param string $userid (optional) The user's ID
*
* @return boolean True on success, otherwise 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-');
}
}
$sqlite = $this->getDB();
if(!$sqlite)
return false;
$values = array('principals/'.$userid,
$name,
str_replace(array('/', ' ', ':'), '_', $id),
$description,
1);
$query = "INSERT INTO addressbooks (principaluri, displayname, uri, description, synctoken) ".
"VALUES (?, ?, ?, ?, ?)";
$res = $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 = $sqlite->query($query, $values);
$row = $sqlite->res2row($res);
// Update the pagetocalendarmapping table with the new calendar ID
if(isset($row['id']))
{
$query = "INSERT INTO pagetoaddressbookmapping (page, addressbookid) VALUES (?, ?)";
$res = $sqlite->query($query, $id, $row['id']);
return ($res !== false);
}
return false;
}
/**
* Delete a contact entry from an address book by URI
*
* @param string $id The address book ID
* @param string $user The user's ID
* @param string $uri The object URI to delete
*
* @return boolean True on success, otherwise false
*/
public function deleteContactEntryToAddressbookForPage($id, $user, $uri)
{
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 array('formattedname' => $this->getLang('settings_not_found'), 'result' => false);
if($settings['type'] !== 'contacts')
return array('formattedname' => $this->getLang('wrong_type'), 'result' => false);
return $wdc->deleteAddressbookEntry($connectionId, $uri);
}
$sqlite = $this->getDB();
if(!$sqlite)
return false;
$addressbookid = $this->getAddressbookIdForPage($id);
$query = "DELETE FROM addressbookobjects WHERE uri = ? AND addressbookid = ?";
$res = $sqlite->query($query, $uri, $addressbookid);
if($res !== false)
{
$this->updateSyncTokenLog($addressbookid, $uri, 'deleted');
return true;
}
return false;
}
/**
* Edit a contact for a given address book
*
* @param string $id The address book ID
* @param string $user The user name
* @param string $uri The object URI
* @param array $params The new address book parameters
*
* @return boolean True on success, otherwise false
*/
public function editContactEntryToAddressbookForPage($id, $user, $uri, $params)
{
require_once(DOKU_PLUGIN.'davcard/vendor/autoload.php');
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 array('formattedname' => $this->getLang('settings_not_found'), 'result' => false);
if($settings['type'] !== 'contacts')
return array('formattedname' => $this->getLang('wrong_type'), 'result' => false);
$row = $wdc->getAddressbookEntryByUri($connectionId, $uri);
}
else
{
$addressbookid = $this->getAddressbookIdForPage($id);
$row = $this->getAddressbookEntryByUri($addressbookid, $uri);
}
$vcard = \Sabre\VObject\Reader::read($row['contactdata']);
$vcard->remove('ADR');
$vcard->remove('TEL');
$vcard->remove('EMAIL');
if(isset($params['phones']))
{
foreach($params['phones'] as $data)
{
$vcard->add('TEL', $data['number'], array('type' => $data['type']));
}
}
if(isset($params['email']))
{
foreach($params['email'] as $data)
{
$vcard->add('EMAIL', $data['mail'], array('type' => $data['type']));
}
}
if(isset($params['addresses']))
{
foreach($params['addresses'] as $data)
{
$vcard->add('ADR', array('', '', $data['street'], $data['city'], '', $data['zipcode'], $data['country']), array('type' => $data['type']));
}
}
$structuredname = explode(';', (string)$vcard->N);
$structuredname[0] = $params['lastname'];
$structuredname[1] = $params['firstname'];
$formattedname = $params['firstname'].' '.$params['lastname']; // FIXME: Make this configurable?
$vcard->N = $structuredname;
$vcard->FN = $formattedname;
$contactdata = $vcard->serialize();
if(strpos($id, 'webdav://') === 0)
{
return $wdc->editAddressbookEntry($connectionId, $uri, $contactdata);
}
else
{
$sqlite = $this->getDB();
if(!$sqlite)
return false;
$now = new \DateTime();
$query = "UPDATE addressbookobjects SET contactdata = ?, lastmodified = ?, etag = ?, size = ?, formattedname = ?, structuredname = ? WHERE addressbookid = ? AND uri = ?";
$res = $sqlite->query($query,
$contactdata,
$now->getTimestamp(),
md5($contactdata),
strlen($contactdata),
$formattedname,
implode(';', $structuredname),
$addressbookid,
$uri
);
if($res !== false)
{
$this->updateSyncTokenLog($addressbookid, $uri, 'modified');
return true;
}
}
return false;
}
/**
* Add a new contact entry to an address book page
*
* @param string $id The page ID
* @param string $user The user ID
* @param array $params The entry's parameters
*
* @return boolean True on success, otherwise 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;
$vcard->N = $structuredname;
if(isset($params['phones']))
{
foreach($params['phones'] as $data)
{
$vcard->add('TEL', $data['number'], array('type' => $data['type']));
}
}
if(isset($params['email']))
{
foreach($params['email'] as $data)
{
$vcard->add('EMAIL', $data['mail'], array('type' => $data['type']));
}
}
if(isset($params['addresses']))
{
foreach($params['addresses'] as $data)
{
$vcard->add('ADR', array('', '', $data['street'], $data['city'], '', $data['zipcode'], $data['country']), array('type' => $data['type']));
}
}
$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
{
$sqlite = $this->getDB();
if(!$sqlite)
return false;
$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 = $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;
}
}
return false;
}
/**
* Parse a VCard and extract important contact information
*
* @param string $card The VCard data
* @param string $uri The object URI
* @param boolean $write Writable
*
* @return array An array with parsed data
*/
public function parseVcard($card, $uri, $write)
{
require_once(DOKU_PLUGIN.'davcard/vendor/autoload.php');
$vObject = \Sabre\VObject\Reader::read($card);
$formattedname = '';
$structuredname = '';
$tel = array();
$addr = array();
$mail = array();
$photo = array();
$birthday = '';
$note = '';
$title = '';
$url = '';
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[] = array('type' => strtolower((string)$number['TYPE']), 'number' => (string)$number);
else
$tel[] = array('number' => (string)$number);
}
}
if(isset($vObject->ADR))
{
foreach($vObject->ADR as $adr)
{
if(isset($adr['TYPE']))
$addr[] = array('type' => strtolower((string)$adr['TYPE']), 'address' => $adr->getParts());
else
$addr[] = array('address' => $adr->getParts());
}
}
if(isset($vObject->EMAIL))
{
foreach($vObject->EMAIL as $email)
{
if(isset($email['TYPE']))
$mail[] = array('type' => strtolower((string)$email['TYPE']), 'mail' => (string)$email);
else
$mail[] = array('mail' => (string)$email);
}
}
if(isset($vObject->PHOTO))
{
if(isset($vObject->PHOTO['TYPE']))
{
$photo[] = array('type' => strtolower((string)$vObject->PHOTO['TYPE']), 'photo' => (string)$vObject->PHOTO);
}
else
$photo[] = array('photo' => (string)$vObject->PHOTO);
}
if(isset($vObject->BDAY))
{
$birthday = (string)$vObject->BDAY;
$birthday = str_replace('-', '', $birthday);
}
if(isset($vObject->NOTE))
{
$note = (string)$vObject->NOTE;
}
if(isset($vObject->TITLE))
{
$title = (string)$vObject->TITLE;
}
if(isset($vObject->URL))
{
$url = (string)$vObject->URL;
}
return array(
'formattedname' => $formattedname,
'structuredname' => $structuredname,
'tel' => $tel,
'mail' => $mail,
'addr' => $addr,
'uri' => $uri,
'photo' => $photo,
'birthday' => $birthday,
'note' => $note,
'title' => $title,
'url' => $url,
'result' => true,
'write' => $write
);
}
/**
* Retrieve the settings of a given address book
*
* @param int $addressbookid The addressbook's ID
*
* @return array The settings
*/
public function getAddressbookSettings($addressbookid)
{
$sqlite = $this->getDB();
if(!$sqlite)
return false;
$query = "SELECT id, principaluri, displayname, uri, description, synctoken FROM addressbooks WHERE id= ? ";
$res = $sqlite->query($query, $addressbookid);
$row = $sqlite->res2row($res);
return $row;
}
/**
* Retrieve the current synctoken for an address book
*
* @param int $addressbookid The addressbook's ID
*
* @return string The current synctoken
*/
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;
}
/**
* Update the synctoken log for a given address book
*
* @param string $addressbookid The addressbook ID to work with
* @param string $uri The object URI that was modified
* @param string $operation The operation that was performed
*
* @return boolean True on success, otherwise 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
);
$sqlite = $this->getDB();
if(!$sqlite)
return false;
$query = "INSERT INTO addressbookchanges (uri, synctoken, addressbookid, operation) VALUES(?, ?, ?, ?)";
$res = $sqlite->query($query, $uri, $currentToken, $addressbookid, $operationCode);
if($res === false)
return false;
$currentToken++;
$query = "UPDATE addressbooks SET synctoken = ? WHERE id = ?";
$res = $sqlite->query($query, $currentToken, $addressbookid);
return ($res !== false);
}
+
+ /**
+ * Check the permission of a user for a given addressbook ID
+ *
+ * @param string $id The addressbook ID to check
+ * @return int AUTH_* constants
+ */
+ public function checkAddressbookPermission($id)
+ {
+ if(strpos($id, 'webdav://') === 0)
+ {
+ $wdc =& plugin_load('helper', 'webdavclient');
+ if(is_null($wdc))
+ return AUTH_NONE;
+ $connectionId = str_replace('webdav://', '', $id);
+ $settings = $wdc->getConnection($connectionId);
+ if($settings === false)
+ return AUTH_NONE;
+ if($settings['write'] === '1')
+ return AUTH_CREATE;
+ return AUTH_READ;
+ }
+ else
+ {
+ $addr = $this->getAddressbookIdForPage($id);
+ // We return AUTH_READ if the calendar does not exist. This makes
+ // davcard happy when there are just included addressbooks
+ if($addr === false)
+ return AUTH_READ;
+ return auth_quickaclcheck($id);
+ }
+ }
}
diff --git a/lang/en/lang.php b/lang/en/lang.php
--- a/lang/en/lang.php
+++ b/lang/en/lang.php
@@ -1,80 +1,82 @@
*/
$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 (%s) was not found';
$lang['error_adding'] = 'Error adding contact';
$lang['error_editing'] = 'Error editing contact';
$lang['error_deleting'] = 'Error deleting contact';
$lang['invalid_options'] = 'invalid options given';
-$lang['no_permission'] = 'You do not have permission to read this address book';
+$lang['no_permission'] = 'You do not have permission for this address book';
$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['telother'] = 'Other';
$lang['adrintl'] = 'International';
$lang['adrpostal'] = 'Postal';
$lang['adrparcel'] = 'Parcel';
$lang['adrwork'] = 'Work';
$lang['adrdom'] = 'Domestic';
$lang['adrhome'] = 'Home';
$lang['adrpref'] = 'preferred';
$lang['adrother'] = 'Other';
$lang['created_by_davcard'] = 'Created by DAVCard';
$lang['add_new'] = 'Add new entry';
$lang['edit'] = 'Edit';
$lang['name'] = 'Name';
$lang['address'] = 'Address';
$lang['phone'] = 'Phone';
$lang['email'] = 'E-Mail';
$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']['delete'] = 'Delete';
$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']['add_phone'] = 'Add Phonenumber';
$lang['js']['add_mail'] = 'Add Mail';
$lang['js']['addresses'] = 'Addresses';
$lang['js']['street'] = 'Street';
$lang['js']['country'] = 'Country';
$lang['js']['email'] = 'Email';
$lang['js']['loading'] = 'Loading...';
$lang['js']['error_loading'] = 'Error loading contact data from server!';
$lang['js']['workphone'] = 'Work Phone';
$lang['js']['otherphone'] = 'Other Phone';
$lang['js']['work'] = 'Work';
$lang['js']['home'] = 'Home';
$lang['js']['add_address'] = 'Add address';
$lang['js']['other_address'] = 'Other Address';
+$lang['js']['addressbook'] = 'Addressbook';
+
diff --git a/plugin.info.txt b/plugin.info.txt
--- a/plugin.info.txt
+++ b/plugin.info.txt
@@ -1,7 +1,7 @@
base davcard
author Andreas Boehler
email dev@aboehler.at
-date 2016-12-13
+date 2017-02-21
name Addressbook PlugIn with CardDAV client support
desc Show contact information from a CardDAV address book (needs webdavclient)
url http://www.dokuwiki.org/plugin:davcard
diff --git a/script.js b/script.js
--- a/script.js
+++ b/script.js
@@ -1,745 +1,765 @@
jQuery(function() {
var links = 0;
// Remove the CSS-only popup and replace it with a jQuery/AJAX popup
jQuery('div.dokuwiki a.plugin_davcard_url span.plugin_davcard_popup').each(function() {
jQuery(this).addClass('plugin_davcard_nopopup');
jQuery(this).removeClass('plugin_davcard_popup');
var $link = jQuery(this).parents('a.plugin_davcard_url');
if(!$link)
return;
$link.davcard_popup_id = 'plugin_davcard_popup_'+(links++);
$link.mouseover(function () {
$link.davcard_timer = window.setTimeout(
function () {
dw_davcard__modals.showOverlay($link);
$link.davcard_timer = null;
},
300
);
});
// Attach edit event dialog to link
$link.click(
function(e)
{
dw_davcard__modals.attachEditDialog($link);
e.preventDefault();
return '';
}
);
$link.mouseout(function () {
$link = jQuery(this);
if ($link.davcard_timer)
window.clearTimeout($link.davcard_timer);
$link.davcard_timer = null;
});
});
// Attach to addressbook links
var addressbookpage = jQuery('#davcardAddressbookList').data('addressbookpage');
if(!addressbookpage) return;
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.id = addressbookpage;
dw_davcard__modals.showEditContactDialog(null, false, true);
e.preventDefault();
return '';
}
);
}
);
jQuery('div.dokuwiki a.plugin_davcard_edit_vcard').each(function() {
var $link = jQuery(this);
// Attach edit event dialog to link
$link.click(
function(e)
{
dw_davcard__modals.attachEditDialog($link);
e.preventDefault();
return '';
}
);
});
});
/**
* This holds all modal windows that DAVCard uses.
*/
var dw_davcard__modals = {
$editContactDialog: null,
$confirmDialog: null,
$loadingDialog: null,
page: JSINFO['id'],
id: null,
uri: null,
action: null,
completeCb: null,
msg: null,
attachEditDialog : function($link) {
dw_davcard__modals.showLoadingDialog();
dw_davcard__modals.id = $link.data('davcardid');
var write = $link.data('write');
jQuery.post(
DOKU_BASE + 'lib/exe/ajax.php',
{
call: 'plugin_davcard',
id: $link.data('davcardid'),
page: dw_davcard__modals.page,
action: 'getContactDetails',
params: {
uri: $link.data('davcarduri'),
},
sectok: JSINFO.plugin.davcard['sectok']
},
function(data)
{
var result = data['result'];
if(result === true)
{
dw_davcard__modals.hideLoadingDialog();
dw_davcard__modals.showEditContactDialog(data['contactdata'], true, write);
}
else
{
dw_davcard__modals.hideLoadingDialog();
dw_davcard__modals.msg = LANG.plugins.davcard['error_loading'];
dw_davcard__modals.showDialog(false);
}
}
);
},
showEditContactDialog : function(entry, edit, write) {
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 addrArray = new Array();
var mailArray = new Array();
var phoneArray = new Array();
+ var pageid = jQuery("#dw_davcard__addressbook option:selected").val();
jQuery("tr.dw_davcard__editentry_phone_row").each(function() {
var type = jQuery(this).children("td.dw_davcard__editentry_phone_row_type").data('type');
var phone = jQuery(this).children("td.dw_davcard__editentry_phone_row_number").html();
var phoneRow = { };
phoneRow['type'] = type;
phoneRow['number'] = phone;
phoneArray.push(phoneRow);
});
jQuery("tr.dw_davcard__editentry_email_row").each(function() {
var type = jQuery(this).children("td.dw_davcard__editentry_email_row_data").data('type');
var email = jQuery(this).children("td.dw_davcard__editentry_email_row_data").html();
mailRow = { };
mailRow['type'] = type;
mailRow['mail'] = email;
mailArray.push(mailRow);
});
jQuery("tr.dw_davcard__editentry_addresses_row").each(function() {
var $rowData = jQuery(this).children("td.dw_davcard__editentry_addresses_row_data");
var type = $rowData.data('type');
var city = $rowData.data('city');
var street = $rowData.data('street');
var zipcode = $rowData.data('zipcode');
var country = $rowData.data('country');
var addrRow = { };
addrRow['type'] = type;
addrRow['city'] = city;
addrRow['street'] = street;
addrRow['zipcode'] = zipcode;
addrRow['country'] = country;
addrArray.push(addrRow);
});
postArray['phones'] = phoneArray;
postArray['email'] = mailArray;
postArray['addresses'] = addrArray;
postArray['uri'] = entry['uri'];
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(' ');
jQuery.post(
DOKU_BASE + 'lib/exe/ajax.php',
{
call: 'plugin_davcard',
- id: dw_davcard__modals.id,
+ id: pageid,
page: dw_davcard__modals.page,
action: 'editContact',
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['delete']] = function() {
dw_davcard__modals.action = 'deleteContact';
dw_davcard__modals.uri = entry['uri'];
dw_davcard__modals.msg = LANG.plugins.davcard['really_delete_this_entry'];
dw_davcard__modals.completeCb = function(data) {
var result = data['result'];
jQuery('#dw_davcard__ajaxedit').html(data['html']);
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 addrArray = new Array();
var mailArray = new Array();
var phoneArray = new Array();
+ var pageid = jQuery("#dw_davcard__addressbook option:selected").val();
jQuery("tr.dw_davcard__editentry_phone_row").each(function() {
var type = jQuery(this).children("td.dw_davcard__editentry_phone_row_type").data('type');
var phone = jQuery(this).children("td.dw_davcard__editentry_phone_row_number").html();
var phoneRow = { };
phoneRow['type'] = type;
phoneRow['number'] = phone;
phoneArray.push(phoneRow);
});
jQuery("tr.dw_davcard__editentry_email_row").each(function() {
var type = jQuery(this).children("td.dw_davcard__editentry_email_row_data").data('type');
var email = jQuery(this).children("td.dw_davcard__editentry_email_row_data").html();
mailRow = { };
mailRow['type'] = type;
mailRow['mail'] = email;
mailArray.push(mailRow);
});
jQuery("tr.dw_davcard__editentry_addresses_row").each(function() {
var $rowData = jQuery(this).children("td.dw_davcard__editentry_addresses_row_data");
var type = $rowData.data('type');
var city = $rowData.data('city');
var street = $rowData.data('street');
var zipcode = $rowData.data('zipcode');
var country = $rowData.data('country');
var addrRow = { };
addrRow['type'] = type;
addrRow['city'] = city;
addrRow['street'] = street;
addrRow['zipcode'] = zipcode;
addrRow['country'] = country;
addrArray.push(addrRow);
});
postArray['phones'] = phoneArray;
postArray['email'] = mailArray;
postArray['addresses'] = addrArray;
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(' ');
jQuery.post(
DOKU_BASE + 'lib/exe/ajax.php',
{
call: 'plugin_davcard',
- id: dw_davcard__modals.id,
+ 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();
}
}
);
};
}
// Remove create/edit buttons if we are read only
if(!write)
{
delete dialogButtons['create'];
delete dialogButtons['edit'];
}
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(
'' +
'
'
)
.parent()
.attr('id','dw_davcard__edit')
.css({'overflow-y': 'auto'})
.show()
.appendTo('.dokuwiki:first');
// attach event handlers
jQuery('#dw_davcard__edit .ui-dialog-titlebar-close').click(function(){
dw_davcard__modals.hideEditContactDialog();
});
// Populate Dropdowns
var $dropdown = jQuery('#dw_davcard__editentry_phones_select');
$dropdown.append('' + dw_davcard__modals.phoneTypeToString('work') + ' ');
$dropdown.append('' + dw_davcard__modals.phoneTypeToString('cell') + ' ');
$dropdown.append('' + dw_davcard__modals.phoneTypeToString('home') + ' ');
$dropdown = jQuery('#dw_davcard__editentry_addresses_select');
$dropdown.append('' + dw_davcard__modals.addressTypeToString('work') + ' ');
$dropdown.append('' + dw_davcard__modals.addressTypeToString('home') + ' ');
+
+ $dropdown = jQuery('#dw_davcard__addressbook');
+ jQuery('#davcardAddressbookList option').each(function() {
+ var sel = '';
+ if(edit && dw_davcard__modals.id == jQuery(this).val())
+ sel = ' selected="selected"';
+ if(edit || (!edit && (jQuery(this).data('write') == "1" || jQuery(this).data('write') == "true")))
+ {
+ $dropdown.append('' + jQuery(this).text() + ' ');
+ }
+ });
+
+ if(edit)
+ {
+ $dropdown.prop('disabled', true);
+ }
+
+
dw_davcard__modals.attachPhoneDeleteHandlers();
dw_davcard__modals.attachMailDeleteHandlers();
dw_davcard__modals.attachAddressDeleteHandlers();
jQuery('#dw_davcard__editentry_phone_add').on("click", function(e)
{
e.preventDefault();
var number = jQuery('#dw_davcard__editentry_phone_edit').val();
if(number == '')
return false;
var type = jQuery('#dw_davcard__editentry_phones_select option:selected').val();
var typeText = jQuery('#dw_davcard__editentry_phones_select option:selected').text();
jQuery('#dw_davcard__editentry_phone_edit').val('');
dw_davcard__modals.addPhone(type, typeText, number);
return false;
});
jQuery('#dw_davcard__editentry_email_add').on("click", function(e)
{
e.preventDefault();
var mail = jQuery('#dw_davcard__editentry_email_edit').val();
if(mail == '')
return false;
jQuery('#dw_davcard__editentry_email_edit').val('');
dw_davcard__modals.addMail('internet', mail);
return false;
});
jQuery('#dw_davcard__editentry_addresses_add').on("click", function(e)
{
e.preventDefault();
var street = jQuery('#dw_davcard__editentry_addresses_street').val();
var zipcode = jQuery('#dw_davcard__editentry_addresses_zipcode').val();
var country = jQuery('#dw_davcard__editentry_addresses_country').val();
var city = jQuery('#dw_davcard__editentry_addresses_city').val();
var type = jQuery('#dw_davcard__editentry_addresses_select option:selected').val();
var typeText = jQuery('#dw_davcard__editentry_addresses_select option:selected').text();
if(street == '' && zipcode == '' && country == '' && city == '')
return false;
jQuery('#dw_davcard__editentry_addresses_street').val('');
jQuery('#dw_davcard__editentry_addresses_city').val('');
jQuery('#dw_davcard__editentry_addresses_country').val('');
jQuery('#dw_davcard__editentry_addresses_zipcode').val('');
dw_davcard__modals.addAddress(type, typeText, street, zipcode, city, country);
return false;
});
if(edit)
{
var name = entry['structuredname'].split(';');
jQuery('#dw_davcard__lastname_edit').val(name[0]);
jQuery('#dw_davcard__firstname_edit').val(name[1]);
for(var i=0; i jQuery(window).height())
{
jQuery('#dw_davcard__edit').height(jQuery(window).height() * 0.9);
}
jQuery('#dw_davcard__edit').position({
my: "center",
at: "center",
of: window
});
},
addressTypeToString: function(type)
{
var ret = '';
switch(type)
{
case 'work':
ret = LANG.plugins.davcard['work'];
break;
case 'home':
ret = LANG.plugins.davcard['home'];
break;
default:
ret = LANG.plugins.davcard['other_address'];
break;
}
return ret;
},
phoneTypeToString: function(type)
{
var ret = '';
switch(type)
{
case 'work':
ret = LANG.plugins.davcard['workphone'];
break;
case 'cell':
ret = LANG.plugins.davcard['cellphone'];
break;
case 'home':
ret = LANG.plugins.davcard['phone'];
break;
default:
ret = LANG.plugins.davcard['otherphone'];
break;
}
return ret;
},
addPhone: function(type, typeText, number)
{
var row = '' + typeText + ' ' + number + ' ' + LANG.plugins.davcard['delete'] + ' ';
jQuery('#dw_davcard__editentry_phones > tbody:last').append(row);
dw_davcard__modals.attachPhoneDeleteHandlers();
},
addMail: function(type, mail) {
var row = '' + mail + ' ' + LANG.plugins.davcard['delete'] + ' ';
jQuery('#dw_davcard__editentry_emails > tbody:last').append(row);
dw_davcard__modals.attachMailDeleteHandlers();
},
addAddress: function(type, typeText, street, zipcode, city, country)
{
var row = '' + typeText + ' ' + LANG.plugins.davcard['street'] + ': ' + street + ' ' +
'' + LANG.plugins.davcard['city'] + ': ' + zipcode + ' ' + city + ' ' +
'' + LANG.plugins.davcard['country'] + ': ' + country + ' ' +
'' + LANG.plugins.davcard['delete'] + ' ';
jQuery('#dw_davcard__editentry_addresses > tbody:last').append(row);
dw_davcard__modals.attachAddressDeleteHandlers();
},
attachAddressDeleteHandlers: function()
{
jQuery("#dw_davcard__editentry_addresses .deleteAddress").on("click", function(e)
{
e.preventDefault();
var tr = jQuery(this).closest('tr');
tr.css("background-color", "#FF3700");
tr.fadeOut(400, function()
{
tr.remove();
});
return false;
});
},
attachPhoneDeleteHandlers: function()
{
jQuery("#dw_davcard__editentry_phones .deletePhoneNumber").on("click", function(e)
{
e.preventDefault();
var tr = jQuery(this).closest('tr');
tr.css("background-color", "#FF3700");
tr.fadeOut(400, function()
{
tr.remove();
});
return false;
});
},
attachMailDeleteHandlers: function()
{
jQuery("#dw_davcard__editentry_emails .deleteEmail").on("click", function(e)
{
e.preventDefault();
var tr = jQuery(this).closest('tr');
tr.css("background-color", "#FF3700");
tr.fadeOut(400, function()
{
tr.remove();
});
return false;
});
},
showLoadingDialog: function() {
if(dw_davcard__modals.$loadingDialog)
return;
var dialogButtons = {};
var title = '';
title = LANG.plugins.davcard['loading'];
dialogButtons[LANG.plugins.davcard['cancel']] = function() {
dw_davcard__modals.hideLoadingDialog();
};
dw_davcard__modals.$loadingDialog = 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('' + LANG.plugins.davcard['loading'] +
'
'
)
.parent()
.attr('id','dw_davcard__loading')
.show()
.appendTo('.dokuwiki:first');
jQuery('#dw_davcard__loading').position({
my: "center",
at: "center",
of: window
});
// attach event handlers
jQuery('#dw_davcard__loading .ui-dialog-titlebar-close').click(function(){
dw_davcard__modals.hideDialog();
});
},
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;
},
hideLoadingDialog: function() {
dw_davcard__modals.$loadingDialog.empty();
dw_davcard__modals.$loadingDialog.remove();
dw_davcard__modals.$loadingDialog = null;
},
showOverlay: function($link)
{
if(!$link.davcard_popup)
{
$link.davcard_popup = dw_page.insituPopup($link, $link.davcard_popup_id);
$link.davcard_popup.addClass('plugin_davcard_popup_overlay');
$link.davcard_popup.load(
DOKU_BASE + 'lib/exe/ajax.php',
{
call: 'plugin_davcard',
sectok: JSINFO.plugin.davcard['sectok'],
action: 'getContactAjax',
id: $link.data('davcardid'),
params: {
uri: $link.data('davcarduri'),
}
}
);
}
$link.davcard_popup.show();
},
showDialog : function(confirm)
{
if(dw_davcard__modals.$confirmDialog)
return;
var dialogButtons = {};
var title = '';
if(confirm)
{
title = LANG.plugins.davcard['confirmation'];
dialogButtons[LANG.plugins.davcard['yes']] = function() {
jQuery.post(
DOKU_BASE + 'lib/exe/ajax.php',
{
call: 'plugin_davcard',
id: dw_davcard__modals.id,
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(
'' + dw_davcard__modals.msg + '
'
)
.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
--- a/syntax/book.php
+++ b/syntax/book.php
@@ -1,313 +1,323 @@
*/
// 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' => array(),
'filter' => array(),
);
foreach($options as $option)
{
list($key, $val) = explode('=', $option);
$key = strtolower(trim($key));
$val = trim($val);
switch($key)
{
case 'filter':
list($k, $v) = explode(':', strtolower($val), 2);
$data['filter'][$k] = $v;
break;
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;
// Add webdavclient information so that we can disable caching if need be
foreach($data['id'] as $addrbkid)
{
if(strpos($addrbkid, 'webdav://') === 0)
{
$connectionId = str_replace('webdav://', '', $addrbkid);
if(!is_array($meta['webdavclient']))
$meta['webdavclient'] = array();
if(!in_array($addrbkid, $meta['webdavclient']))
$meta['webdavclient'][] = $connectionId;
}
}
p_set_metadata($ID, array('plugin_davcard' => $meta));
return $data;
}
/**
* Create output
*/
function render($format, Doku_Renderer $R, $data)
{
global $ID;
if($format !== 'xhtml')
return false;
- if(in_array($ID, $data['id']))
- {
- $R->doc .= '';
- }
- // FIXME: Add new is not yet permission checked and does not support
- // included address books!
+
+ $addressbooklist = array();
+
+ $R->doc .= '';
$R->doc .= '';
$R->doc .= '
';
$R->doc .= ''.$this->getLang('name').' '.$this->getLang('address').' '.$this->getLang('phone').' '.$this->getLang('email').' ';
foreach($data['id'] as $id)
{
$write = false;
if(strpos($id, 'webdav://') === 0)
{
$wdc =& plugin_load('helper', 'webdavclient');
if(is_null($wdc))
{
echo $this->getLang('no_wdc');
continue;
}
$connectionId = str_replace('webdav://', '', $id);
$settings = $wdc->getConnection($connectionId);
-
if($settings === false)
{
echo $this->getLang('settings_not_found');
continue;
}
if($settings['type'] !== 'contacts')
{
echo $this->getLang('wrong_type');
continue;
}
+ $name = $settings['displayname'];
$entries = $wdc->getAddressbookEntries($connectionId);
$write = $settings['write'];
}
else
{
$acl = auth_quickaclcheck($id);
if($acl > AUTH_READ)
{
$write = true;
}
elseif($acl < AUTH_READ)
{
continue;
}
else
{
$write = false;
}
$addressbookid = $this->hlp->getAddressbookIdForPage($id);
+ $name = $this->hlp->getAddressBookSettings($addressbookid);
+ $name = $name['displayname'];
$entries = $this->hlp->getAddressbookEntries($addressbookid);
}
+
+ $addressbooklist[] = array('id' => $id, 'name' => $name, 'write' => $write);
+
foreach($entries as $entry)
{
$contactdata = $this->hlp->parseVcard($entry['contactdata'], $entry['uri'], $write);
if(!$this->contactFilterMatch($data['filter'], $contactdata))
continue;
$R->doc .= ''.$entry['formattedname'].' ';
if(count($contactdata['addr']) > 0)
{
$R->doc .= '';
foreach($contactdata['addr'] as $dat)
{
if(isset($dat['type']))
$type = $dat['type'];
else
$type = 'other';
$R->doc .= ''.$this->getLang('adr'.strtolower($type)).' ';
if($dat['address'][2] != '')
{
$R->doc .= ''.$dat['address'][2].' ';
}
if($dat['address'][5] != '')
{
$R->doc .= ''.$dat['address'][5].' ';
}
if($dat['address'][3] != '')
{
$R->doc .= ''.$dat['address'][3].' ';
}
if($dat['address'][6] != '')
{
$R->doc .= ''.$dat['address'][6].' ';
}
}
$R->doc .= ' ';
}
$R->doc .= ' ';
if(count($contactdata['tel']) > 0)
{
$R->doc .= '';
foreach($contactdata['tel'] as $dat)
{
if(isset($dat['type']))
$type = $dat['type'];
else
$type = 'other';
$R->doc .= ''.$this->getLang('tel'.strtolower($type)).' ';
$R->doc .= $dat['number'].' ';
}
$R->doc .= ' ';
}
$R->doc .= ' ';
if(count($contactdata['mail']) > 0)
{
foreach($contactdata['mail'] as $dat)
{
$R->doc .= ''.$dat['mail'].' ';
}
}
$R->doc .= ' ';
}
}
$R->doc .= '
';
+ $R->doc .= '
';
+ $R->doc .= '';
+ foreach($addressbooklist as $addrbk)
+ {
+ $R->doc .= ''.$addrbk['name'].' ';
+ }
+ $R->doc .= '
';
$R->doc .= '
';
}
/**
* Check if a contact matches a given filter pattern
*
* @param array $filter The filter array
* @param array $contactdata The contact's data to match
*
* @return true on success, otherwise false
*/
private function contactFilterMatch($filter, $contactdata)
{
if(empty($filter))
return true;
foreach($filter as $type => $params)
{
$params = '/'.$params.'/i';
switch($type)
{
case 'name':
if(preg_match($params, $contactdata['formattedname']) !== 1)
return false;
break;
case 'mail':
$found = false;
foreach($contactdata['mail'] as $dat)
{
if(preg_match($params, $dat['mail']) === 1)
$found = true;
}
if(!$found)
return false;
break;
case 'address':
$found = false;
foreach($contactdata['addr'] as $dat)
{
foreach($dat['address'] as $da)
{
if(preg_match($params, $da) === 1)
$found = true;
}
}
if(!$found)
return false;
break;
case 'tel':
$found = false;
foreach($contactdata['tel'] as $dat)
{
if(preg_match($params, $dat['number']) === 1)
$found = true;
}
if(!$found)
return false;
break;
}
}
return true;
}
}
// 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,215 +1,207 @@
*/
// 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');
$this->Lexer->addSpecialPattern('\{\{davcardclient>[^}]*\}\}',$mode,'plugin_davcard_card');
}
/**
* Handle the match
*/
function handle($match, $state, $pos, Doku_Handler $handler){
global $ID;
$data = array('name' => '',
'id' => $ID,
'firstname' => '',
'lastname' => '',
'email' => '',
'uri' => '',
);
if(strpos($match, '{{davcardclient') === 0)
{
$options = trim(substr($match,16,-2));
$defaultId = $this->getConf('default_client_id');
if(isset($defaultId) && ($defaultId != ''))
{
$data['id'] = $defaultId;
}
}
else
{
$options = trim(substr($match,10,-2));
}
$options = explode(',', $options);
foreach($options as $option)
{
list($key, $val) = explode('=', $option);
$key = strtolower(trim($key));
$val = trim($val);
switch($key)
{
default:
$data[$key] = $val;
}
}
- // FIXME: This is nonsense
- if($data['id'] === '')
- {
- 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();
$srch = '';
if($data['name'] !== '')
{
$contactdata = $this->hlp->getContactByFormattedName($data['id'], $data['name']);
$srch = $data['name'];
}
elseif(($data['firstname'] !== '') || ($data['lastname'] !== ''))
{
$contactdata = $this->hlp->getContactByStructuredName($data['id'], $data['firstname'], $data['lastname']);
$srch = $data['firstname'].' '.$data['lastname'];
}
elseif(($data['email'] !== ''))
{
$contactdata = $this->hlp->getContactByEmail($data['id'], $data['email']);
$srch = 'E-Mail = '.$data['email'];
}
elseif(($data['uri'] !== ''))
{
$contactdata = $this->hlp->getContactByUri($data['id'], $data['uri']);
$srch = 'URI = '.$data['uri'];
}
if($contactdata['result'] === false)
{
$R->doc .= sprintf($this->getLang('contact_not_found'), $srch);
return;
}
$R->doc .= ''.$contactdata['formattedname'];
$R->doc .= '';
$R->doc .= ' ';
}
}
// vim:ts=4:sw=4:et:enc=utf-8: