Page MenuHomePhabricator

helper.php
No OneTemporary

helper.php

<?php
/**
* Helper Class for the DAVCard plugin
* This helper does the actual work.
*
*/
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
class helper_plugin_davcard extends DokuWiki_Plugin {
protected $sqlite = null;
/**
* Constructor to load the configuration
*/
public function helper_plugin_davcard() {
$this->sqlite =& plugin_load('helper', 'sqlite');
global $conf;
if(!$this->sqlite)
{
if($conf['allowdebug'])
dbglog('This plugin requires the sqlite plugin. Please install it.');
msg('This plugin requires the sqlite plugin. Please install it.');
return;
}
if(!$this->sqlite->init('davcard', DOKU_PLUGIN.'davcard/db/'))
{
if($conf['allowdebug'])
dbglog('Error initialising the SQLite DB for DAVCard');
return;
}
}
private function getContactByDetails($id, $type, $params = array())
{
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'));
if($settings['type'] !== 'contacts')
return array('formattedname' => $this->getLang('wrong_type'));
$entries = $wdc->getAddressbookEntries($connectionId);
}
else
{
$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 lat name
return array('formattedname' => $this->getLang('contact_not_found'));
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']);
return $info;
}
}
break;
case 'formattedname':
if(trim(strtolower($entry['formattedname'])) == $params['formattedname'])
{
$info = $this->parseVcard($entry['contactdata'], $entry['uri']);
return $info;
}
break;
case 'email':
$info = $this->parseVcard($entry['contactdata'], $entry['uri']);
foreach($info['mail'] as $data)
{
if($data['mail'] === strtolower($params['email']))
return $info;
}
break;
}
}
return array('formattedname' => $this->getLang('contact_not_found'));
}
public function getAddressbookEntries($id)
{
$query = "SELECT contactdata, uri, formattedname, structuredname FROM addressbookobjects WHERE addressbookid = ? ORDER BY formattedname ASC";
$res = $this->sqlite->query($query, $id);
return $this->sqlite->res2arr($res);
}
public function getContactByStructuredName($id, $firstname = '', $lastname = '')
{
return $this->getContactByDetails($id, 'structuredname',
array('firstname' => strtolower($firstname), 'lastname' => strtolower($lastname)));
}
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)));
}
public function getContactByFormattedName($id, $name)
{
return $this->getContactByDetails($id, 'formattedname', array('formattedname' => strtolower($name)));
}
public function getContactByUri($id, $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);
$row = $wdc->getAddressbookEntryByUri($connectionId, $uri);
}
else
{
$addressbookid = $this->getAddressbookIdForPage($id);
$row = $this->getAddressbookEntryByUri($addressbookid, $uri);
}
if($row === false)
return array('formattedname' => $this->getLang('contact_not_found'), 'result' => false);
$info = $this->parseVcard($row['contactdata'], $row['uri']);
$info['result'] = true;
return $info;
}
private function getAddressbookEntryByUri($id, $uri)
{
$query = "SELECT contactdata, addressbookid, etag, uri, formattedname, structuredname FROM addressbookobjects WHERE addressbookid = ? AND uri = ?";
$res = $this->sqlite->query($query, $id, $uri);
return $this->sqlite->res2row($res);
}
public function setAddressbookNameForPage($name, $description, $id = null, $userid = null)
{
if(is_null($id))
{
global $ID;
$id = $ID;
}
if(is_null($userid))
{
if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
{
$userid = $_SERVER['REMOTE_USER'];
}
else
{
$userid = uniqid('davcard-');
}
}
$bookid = $this->getAddressbookIdForPage($id);
if($bookid === false)
return $this->createAddressbookForPage($name, $description, $id, $userid);
$query = "UPDATE addressbooks SET displayname = ?, description = ? WHERE id = ?";
$res = $this->sqlite->query($query, $name, $description, $bookid);
if($res !== false)
return true;
return false;
}
public function getAddressbookIdForPage($id = null)
{
if(is_null($id))
{
global $ID;
$id = $ID;
}
$query = "SELECT addressbookid FROM pagetoaddressbookmapping WHERE page = ?";
$res = $this->sqlite->query($query, $id);
$row = $this->sqlite->res2row($res);
if(isset($row['addressbookid']))
{
$calid = $row['addressbookid'];
return $calid;
}
return false;
}
public function createAddressbookForPage($name, $description, $id = null, $userid = null)
{
if(is_null($id))
{
global $ID;
$id = $ID;
}
if(is_null($userid))
{
if(isset($_SERVER['REMOTE_USER']) && !is_null($_SERVER['REMOTE_USER']))
{
$userid = $_SERVER['REMOTE_USER'];
}
else
{
$userid = uniqid('davcard-');
}
}
$values = array('principals/'.$userid,
$name,
str_replace(array('/', ' ', ':'), '_', $id),
$description,
1);
$query = "INSERT INTO addressbooks (principaluri, displayname, uri, description, synctoken) ".
"VALUES (?, ?, ?, ?, ?)";
$res = $this->sqlite->query($query, $values);
if($res === false)
return false;
// Get the new addressbook ID
$query = "SELECT id FROM addressbooks WHERE principaluri = ? AND displayname = ? AND ".
"uri = ? AND description = ? AND synctoken = ?";
$res = $this->sqlite->query($query, $values);
$row = $this->sqlite->res2row($res);
// Update the pagetocalendarmapping table with the new calendar ID
if(isset($row['id']))
{
$query = "INSERT INTO pagetoaddressbookmapping (page, addressbookid) VALUES (?, ?)";
$res = $this->sqlite->query($query, $id, $row['id']);
return ($res !== false);
}
return false;
}
public function 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);
}
$addressbookid = $this->getAddressbookIdForPage($id);
dbglog($addressbookid);
dbglog($uri);
$query = "DELETE FROM addressbookobjects WHERE uri = ? AND addressbookid = ?";
dbglog($query);
$res = $this->sqlite->query($query, $uri, $addressbookid);
if($res !== false)
{
$this->updateSyncTokenLog($addressbookid, $uri, 'deleted');
return true;
}
return 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
{
$now = new \DateTime();
$query = "UPDATE addressbookobjects SET contactdata = ?, lastmodified = ?, etag = ?, size = ?, formattedname = ?, structuredname = ? WHERE addressbookid = ? AND uri = ?";
$res = $this->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;
}
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
{
$addressbookid = $this->getAddressbookIdForPage($id);
$uri = uniqid('dokuwiki-').'.vcf';
$now = new \DateTime();
$query = "INSERT INTO addressbookobjects (contactdata, uri, addressbookid, lastmodified, etag, size, formattedname, structuredname) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
$res = $this->sqlite->query($query,
$contactdata,
$uri,
$addressbookid,
$now->getTimestamp(),
md5($contactdata),
strlen($contactdata),
$formattedname,
implode(';', $structuredname)
);
// If successfully, update the sync token database
if($res !== false)
{
$this->updateSyncTokenLog($addressbookid, $uri, 'added');
return true;
}
}
return false;
}
public function parseVcard($card, $uri)
{
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,
);
}
public function getAddressbookSettings($addressbookid)
{
$query = "SELECT id, principaluri, displayname, uri, description, synctoken FROM addressbooks WHERE id= ? ";
$res = $this->sqlite->query($query, $addressbookid);
$row = $this->sqlite->res2row($res);
return $row;
}
public function getSyncTokenForAddressbook($addressbookid)
{
$row = $this->getAddressbookSettings($addressbookid);
if(isset($row['synctoken']))
return $row['synctoken'];
return false;
}
/**
* Helper function to convert the operation name to
* an operation code as stored in the database
*
* @param string $operationName The operation name
*
* @return mixed The operation code or false
*/
public function operationNameToOperation($operationName)
{
switch($operationName)
{
case 'added':
return 1;
break;
case 'modified':
return 2;
break;
case 'deleted':
return 3;
break;
}
return false;
}
private function updateSyncTokenLog($addressbookid, $uri, $operation)
{
$currentToken = $this->getSyncTokenForAddressbook($addressbookid);
$operationCode = $this->operationNameToOperation($operation);
if(($operationCode === false) || ($currentToken === false))
return false;
$values = array($uri,
$currentToken,
$addressbookid,
$operationCode
);
$query = "INSERT INTO addressbookchanges (uri, synctoken, addressbookid, operation) VALUES(?, ?, ?, ?)";
$res = $this->sqlite->query($query, $uri, $currentToken, $addressbookid, $operationCode);
if($res === false)
return false;
$currentToken++;
$query = "UPDATE addressbooks SET synctoken = ? WHERE id = ?";
$res = $this->sqlite->query($query, $currentToken, $addressbookid);
return ($res !== false);
}
}

File Metadata

Mime Type
text/x-php
Expires
Tue, Dec 24, 12:33 AM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
912074
Default Alt Text
helper.php (19 KB)

Event Timeline