Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F1880248
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
93 KB
Subscribers
None
View Options
diff --git a/action/ajax.php b/action/ajax.php
--- a/action/ajax.php
+++ b/action/ajax.php
@@ -1,274 +1,274 @@
<?php
/**
* DokuWiki DAVCard PlugIn - Ajax component
* @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
* @author Andreas Böhler <dev@aboehler.at>
*/
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 '<div class="plugin_davcard_popup_container">';
foreach($contactdata['photo'] as $data)
{
if(isset($data['type']))
$type = $data['type'];
else
$type = '';
echo '<div class="plugin_davcard_popup_image">';
$imgdata = base64_encode($data['photo']);
$pattern = '/^(?:[;\/?:@&=+$,]|(?:[^\W_]|[-_.!~*\()\[\] ])|(?:%[\da-fA-F]{2}))*$/';
// PNG images
if($type == 'png')
{
$imgdata = 'data:image/png;base64,'.$imgdata;
echo '<img src="'.hsc($imgdata).'" alt="contact image" />';
}
// JPEG images
elseif(($type == 'jpeg') || ($type == 'jpg'))
{
$imgdata = 'data:image/jpeg;base64,'.$imgdata;
echo '<img src="'.hsc($imgdata).'" alt="contact image" />';
}
// GIF images
elseif($type == 'gif')
{
$imgdata = 'data:image/gif;base64,'.$imgdata;
echo '<img src="'.hsc($imgdata).'" alt="contact image" />';
}
// URLs (no type given)
elseif(preg_match( $pattern, $string ) == 1)
{
echo '<img src="'.hsc($data['photo']).'" alt="contact image" />';
}
echo '</div>';
}
echo '<div class="plugin_davcard_popup_content">';
$contactname = explode(';', $contactdata['structuredname']);
if(count($contactname) > 1)
{
$cardpattern = str_replace('<DCLASTNAME>', $contactname[0], $cardpattern);
$cardpattern = str_replace('<DCFIRSTNAME>', $contactname[1], $cardpattern);
}
if(count($contactdata['addr']) > 0)
{
foreach($contactdata['addr'] as $data)
{
if(isset($data['type']) && ($data['type'] == 'work'))
$prefix = 'WORK';
else
$prefix = 'PRIVATE';
$cardpattern = str_replace('<DC'.$prefix.'STREET>', $data['address'][2], $cardpattern);
$cardpattern = str_replace('<DC'.$prefix.'CITY>', $data['address'][3], $cardpattern);
$cardpattern = str_replace('<DC'.$prefix.'ZIP>', $data['address'][5], $cardpattern);
$cardpattern = str_replace('<DC'.$prefix.'COUNTRY>', $data['address'][6], $cardpattern);
}
}
if(count($contactdata['tel']) > 0)
{
$telArr = array();
foreach($contactdata['tel'] as $data)
{
if(isset($data['type']))
$type = $data['type'];
else
$type = 'other';
$type = $data['type'];
$telArr[] = $this->getLang('tel'.$type).': '.$data['number'];
}
$telStr = implode(' \\\\ ', $telArr);
$cardpattern = str_replace('<DCPHONE>', $telStr, $cardpattern);
}
if(count($contactdata['mail']) > 0)
{
$mailArr = array();
foreach($contactdata['mail'] as $data)
{
$mailArr[] = '[['.$data['mail'].']]';
}
$mailStr = implode(' \\\\ ', $mailArr);
$cardpattern = str_replace('<DCEMAIL>', $mailStr, $cardpattern);
}
if($contactdata['birthday'] != '')
{
$date = DateTime::createFromFormat('Ymd', $contactdata['birthday']);
$dateStr = $date->format($this->getConf('date_format'));
$cardpattern = str_replace('<DCBIRTHDAY>', $dateStr, $cardpattern);
}
if($contactdata['note'] != '')
{
$notestr = str_replace('\n', ' \\ ', $contactdata['note']);
$cardpattern = str_replace('<DCNOTE>', $notestr, $cardpattern);
}
if($contactdata['title'] != '')
{
$cardpattern = str_replace('<DCTITLE>', $contactdata['title'], $cardpattern);
}
if($contactdata['url'] != '')
{
$url = $contactdata['url'];
if(strpos($url, '://') === false)
$url = 'http://'.$url;
$url = '[['.$url.']]';
$cardpattern = str_replace('<DCWEBSITE>', $url, $cardpattern);
}
$replace_match = '/^.*<DC.*>.*$(?:\r\n|\n)?/m';
$cardpattern = preg_replace($replace_match, '', $cardpattern);
echo $this->render_text($cardpattern);
echo '</div>';
echo '</div>';
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 @@
<?php
/**
* Helper Class for the DAVCard plugin
* This helper does the actual work.
* @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();
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 @@
<?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 (%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('<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: 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('<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: 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(
'<div><table>' +
- // FIXME: '<tr><td>' + LANG.plugins.davcard['calendar'] + '</td><td><select id="dw_davcal__editevent_calendar"></select></td></tr>' +
+ '<tr><td>' + LANG.plugins.davcard['addressbook'] + '</td><td><select id="dw_davcard__addressbook"></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['phone'] + '</td><td><table id="dw_davcard__editentry_phones"><tbody><tr><td><select id="dw_davcard__editentry_phones_select"></select></td><td><input type="text" id="dw_davcard__editentry_phone_edit"></td><td><a href="#" id="dw_davcard__editentry_phone_add">' + LANG.plugins.davcard['add_phone'] + '</a></td></tr></tbody></table></td></tr>' +
'<tr><td>' + LANG.plugins.davcard['email'] + '</td><td><table id="dw_davcard__editentry_emails"><tbody><tr><td><input type="text" id="dw_davcard__editentry_email_edit"></td><td><a href="#" id="dw_davcard__editentry_email_add">' + LANG.plugins.davcard['add_mail'] + '</a></td></tr></tbody></table></td></tr>' +
'<tr><td>' + LANG.plugins.davcard['addresses'] + '</td><td><table id="dw_davcard__editentry_addresses"><tbody>' +
'<tr><td rowspan="5"><select id="dw_davcard__editentry_addresses_select"></select></td><td>' + LANG.plugins.davcard['street'] + '</td><td><input type="text" id="dw_davcard__editentry_addresses_street"></td></tr>' +
'<tr><td>' + LANG.plugins.davcard['zipcode'] + '</td><td><input type="text" id="dw_davcard__editentry_addresses_zipcode"></td></tr>' +
'<tr><td>' + LANG.plugins.davcard['city'] + '</td><td><input type="text" id="dw_davcard__editentry_addresses_city"></td></tr>' +
'<tr><td>' + LANG.plugins.davcard['country'] + '</td><td><input type="text" id="dw_davcard__editentry_addresses_country"></td></tr>' +
'<tr><td><a href="#" id="dw_davcard__editentry_addresses_add">' + LANG.plugins.davcard['add_address'] + '</a></td></tr></tbody></table></td></tr>' +
'</tbody></table></td></tr>' +
'</table>' +
'</div>' +
'<div id="dw_davcard__ajaxedit"></div>'
)
.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('<option value="work">' + dw_davcard__modals.phoneTypeToString('work') + '</option>');
$dropdown.append('<option value="cell">' + dw_davcard__modals.phoneTypeToString('cell') + '</option>');
$dropdown.append('<option value="home">' + dw_davcard__modals.phoneTypeToString('home') + '</option>');
$dropdown = jQuery('#dw_davcard__editentry_addresses_select');
$dropdown.append('<option value="work">' + dw_davcard__modals.addressTypeToString('work') + '</option>');
$dropdown.append('<option value="home">' + dw_davcard__modals.addressTypeToString('home') + '</option>');
+
+ $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('<option value="' + jQuery(this).val() + '"' + sel + '>' + jQuery(this).text() + '</option>');
+ }
+ });
+
+ 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<entry['tel'].length; i++)
{
var type = 'other';
if('type' in entry['tel'][i])
var type = entry['tel'][i]['type'];
var val = entry['tel'][i]['number'];
var typeText = dw_davcard__modals.phoneTypeToString(type);
dw_davcard__modals.addPhone(type, typeText, val);
}
for(var i=0; i<entry['addr'].length; i++)
{
var type = 'other';
if('type' in entry['addr'][i])
type = entry['addr'][i]['type'];
var street = entry['addr'][i]['address'][2];
var zipcode = entry['addr'][i]['address'][5];
var country = entry['addr'][i]['address'][6];
var city = entry['addr'][i]['address'][3];
var typeText = dw_davcard__modals.addressTypeToString(type);
dw_davcard__modals.addAddress(type, typeText, street, zipcode, city, country);
}
for(var i=0; i<entry['mail'].length; i++)
{
var type = 'other';
if('type' in entry['mail'][i])
type = entry['mail'][i]['type'];
var mail = entry['mail'][i]['mail'];
dw_davcard__modals.addMail(type, mail);
}
}
// Resize the dialog if it's higher than the window
if(jQuery('#dw_davcard__edit').height() > 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 = '<tr class="dw_davcard__editentry_phone_row"><td class="dw_davcard__editentry_phone_row_type" data-type="' + type + '">' + typeText + '</td><td class="dw_davcard__editentry_phone_row_number">' + number + '</td><td><a class="deletePhoneNumber" href="#">' + LANG.plugins.davcard['delete'] + '</a></td></tr>';
jQuery('#dw_davcard__editentry_phones > tbody:last').append(row);
dw_davcard__modals.attachPhoneDeleteHandlers();
},
addMail: function(type, mail) {
var row = '<tr class="dw_davcard__editentry_email_row"><td class="dw_davcard__editentry_email_row_data" data-type="' + type + '">' + mail + '</td><td><a class="deleteEmail" href="#">' + LANG.plugins.davcard['delete'] + '</a></td></tr>';
jQuery('#dw_davcard__editentry_emails > tbody:last').append(row);
dw_davcard__modals.attachMailDeleteHandlers();
},
addAddress: function(type, typeText, street, zipcode, city, country)
{
var row = '<tr class="dw_davcard__editentry_addresses_row"><td class="dw_davcard__editentry_addresses_row_data" data-type="' + type + '" data-city="' + city + '" data-zipcode="' + zipcode + '" data-country="' + country + '" data-street="' + street + '">' + typeText + '</td><td colspan="2"><strong>' + LANG.plugins.davcard['street'] + ': </strong>' + street + '<br>' +
'<strong>' + LANG.plugins.davcard['city'] + ': </strong>' + zipcode + ' ' + city + '<br>' +
'<strong>' + LANG.plugins.davcard['country'] + ': </strong>' + country + '<br>' +
'<a class="deleteAddress" href="#">' + LANG.plugins.davcard['delete'] + '</a></td></tr>';
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('<div>' + LANG.plugins.davcard['loading'] +
'<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" /></div>'
)
.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(
'<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
--- a/syntax/book.php
+++ b/syntax/book.php
@@ -1,313 +1,323 @@
<?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' => 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 .= '<div class="davcardAddressbookAddNew"><a href="#" class="davcardAddressbookAddNew">'.$this->getLang('add_new').'</a></div>';
- }
- // FIXME: Add new is not yet permission checked and does not support
- // included address books!
+
+ $addressbooklist = array();
+
+ $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 .= '<table class="davcardAddressbookTable">';
$R->doc .= '<tr><th>'.$this->getLang('name').'</th><th>'.$this->getLang('address').'</th><th>'.$this->getLang('phone').'</th><th>'.$this->getLang('email').'</th></tr>';
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 .= '<tr><td><a href="#" class="plugin_davcard_edit_vcard" data-davcardid="'.$id.'" data-davcarduri="'.$entry['uri'].'" data-write="'.($write ? 'true' : 'false').'">'.$entry['formattedname'].'</a></td><td>';
if(count($contactdata['addr']) > 0)
{
$R->doc .= '<span class="adr">';
foreach($contactdata['addr'] as $dat)
{
if(isset($dat['type']))
$type = $dat['type'];
else
$type = 'other';
$R->doc .= '<span class="type">'.$this->getLang('adr'.strtolower($type)).'</span>';
if($dat['address'][2] != '')
{
$R->doc .= '<span class="street-address">'.$dat['address'][2].'</span><br>';
}
if($dat['address'][5] != '')
{
$R->doc .= '<span class="postal-code">'.$dat['address'][5].' </span>';
}
if($dat['address'][3] != '')
{
$R->doc .= '<span class="locality">'.$dat['address'][3].'</span><br>';
}
if($dat['address'][6] != '')
{
$R->doc .= '<span class="country-name">'.$dat['address'][6].'</span>';
}
}
$R->doc .= '</span>';
}
$R->doc .= '</td><td>';
if(count($contactdata['tel']) > 0)
{
$R->doc .= '<span class="tel">';
foreach($contactdata['tel'] as $dat)
{
if(isset($dat['type']))
$type = $dat['type'];
else
$type = 'other';
$R->doc .= '<span class="type">'.$this->getLang('tel'.strtolower($type)).' </span>';
$R->doc .= $dat['number'].'<br>';
}
$R->doc .= '</span>';
}
$R->doc .= '</td><td>';
if(count($contactdata['mail']) > 0)
{
foreach($contactdata['mail'] as $dat)
{
$R->doc .= '<span class="email">'.$dat['mail'].'</span><br>';
}
}
$R->doc .= '</td></tr>';
}
}
$R->doc .= '</table>';
+ $R->doc .= '<div id="davcardAddressbookList" class="davcardAddressbookList" style="display:none">';
+ $R->doc .= '<select id="davcardAddressbookDropdown">';
+ foreach($addressbooklist as $addrbk)
+ {
+ $R->doc .= '<option value="'.$addrbk['id'].'" data-write="'.$addrbk['write'].'">'.$addrbk['name'].'</option>';
+ }
+ $R->doc .= '</select></div>';
$R->doc .= '</div>';
}
/**
* 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 @@
<?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');
$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 .= '<a class="url fn plugin_davcard_url" href="#" data-davcarduri="'
.$contactdata['uri'].'" data-davcardid="'.$data['id'].'" data-write="'.$contactdata['write'].'">'.$contactdata['formattedname'];
$R->doc .= '<span class="plugin_davcard_popup vcard">';
if(count($contactdata['addr']) > 0)
{
$R->doc .= '<span class="adr">';
foreach($contactdata['addr'] as $dat)
{
if(isset($data['type']))
$type = $dat['type'];
else
$type = 'other';
$R->doc .= '<span class="type">'.$this->getLang('adr'.strtolower($type)).'</span>';
if($dat['address'][2] != '')
{
$R->doc .= '<span class="street-address">'.$dat['address'][2].'</span><br>';
}
if($dat['address'][5] != '')
{
$R->doc .= '<span class="postal-code">'.$dat['address'][5].' </span>';
}
if($dat['address'][3] != '')
{
$R->doc .= '<span class="locality">'.$dat['address'][3].'</span><br>';
}
if($dat['address'][6] != '')
{
$R->doc .= '<span class="country-name">'.$dat['address'][6].'</span>';
}
}
$R->doc .= '</span>';
}
if(count($contactdata['tel']) > 0)
{
$R->doc .= '<span class="tel">';
foreach($contactdata['tel'] as $dat)
{
if(isset($dat['type']))
$type = $dat['type'];
else
$type = 'other';
$R->doc .= '<span class="type">'.$this->getLang('tel'.strtolower($type)).' </span>';
$R->doc .= $dat['number'].'<br>';
}
$R->doc .= '</span>';
}
if(count($contactdata['mail']) > 0)
{
$R->doc .= '<span class="email_outer"><span class="email_type">EMail</span>';
foreach($contactdata['mail'] as $dat)
{
$R->doc .= '<span class="email">'.$dat['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, 3:23 AM (1 d, 13 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
524712
Default Alt Text
(93 KB)
Attached To
rDAVCARD DokuWiki davcard PlugIn
Event Timeline
Log In to Comment