1
0
mirror of https://github.com/owncloudarchive/contacts.git synced 2024-11-29 11:24:11 +01:00
OwncloudContactsOfficial/lib/backend/abstractbackend.php
Thomas Tanghus 9abdeb75ce 2014
2014-01-26 00:40:22 +01:00

436 lines
14 KiB
PHP

<?php
/**
* ownCloud - Base class for Contacts backends
*
* @author Thomas Tanghus
* @copyright 2013-2014 Thomas Tanghus (thomas@tanghus.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Contacts\Backend;
use OCA\Contacts\VObject\VCard;
/**
* Subclass this class for address book backends
*
* The following methods MUST be implemented:
* @method array getAddressBooksForUser(array $options = array())
* @method array|null getAddressBook(string $addressbookid, array $options = array())
* @method array getContacts(string $addressbookid, array $options = array())
* @method array|null getContact(string $addressbookid, mixed $id, array $options = array())
* The following methods MAY be implemented:
* @method bool hasAddressBook(string $addressbookid)
* @method bool updateAddressBook(string $addressbookid, array $updates, array $options = array())
* @method string createAddressBook(array $properties, array $options = array())
* @method bool deleteAddressBook(string $addressbookid, array $options = array())
* @method int lastModifiedAddressBook(string $addressbookid)
* @method array numContacts(string $addressbookid)
* @method bool updateContact(string $addressbookid, string $id, VCard $contact, array $options = array())
* @method string createContact(string $addressbookid, VCard $contact, array $properties)
* @method bool deleteContact(string $addressbookid, string $id, array $options = array())
* @method int lastModifiedContact(string $addressbookid)
*/
abstract class AbstractBackend {
/**
* The name of the backend.
* @var string
*/
public $name;
/**
* The current usert.
* @var string
*/
public $userid;
protected $possibleContactPermissions = array(
\OCP\PERMISSION_CREATE => 'createContact',
\OCP\PERMISSION_READ => 'getContact',
\OCP\PERMISSION_UPDATE => 'updateContact',
\OCP\PERMISSION_DELETE => 'deleteContact',
);
protected $possibleAddressBookPermissions = array(
\OCP\PERMISSION_CREATE => 'createAddressBook',
\OCP\PERMISSION_READ => 'getAddressBook',
\OCP\PERMISSION_UPDATE => 'updateAddressBook',
\OCP\PERMISSION_DELETE => 'deleteAddressBook',
);
/**
* Sets up the backend
*
*/
public function __construct($userid = null) {
$this->userid = $userid ? $userid : \OCP\User::getUser();
}
/**
* @brief Get all possible permissions for contacts based on what the backend implements.
* @returns bitwise-or'ed actions
*
* Returns the supported actions as an int to be
* compared with \OCP\PERMISSION_CREATE etc.
*/
protected function getContactPermissions() {
$permissions = 0;
foreach($this->possibleContactPermissions AS $permission => $methodName) {
if(method_exists($this, $methodName)) {
$permissions |= $permission;
}
}
\OCP\Util::writeLog('contacts', __METHOD__.', permissions' . $permissions, \OCP\Util::DEBUG);
return $permissions;
}
/**
* @brief Get all permissions for address book based on what the backend implements.
* @returns bitwise-or'ed actions
*
* Returns the supported actions as int to be
* compared with \OCP\PERMISSION_CREATE etc.
*/
protected function getAddressBookPermissions() {
$permissions = 0;
foreach($this->possibleAddressBookPermissions AS $permission => $methodName) {
if(method_exists($this, $methodName)) {
$permissions |= $permission;
}
}
\OCP\Util::writeLog('contacts', __METHOD__.', permissions' . $permissions, \OCP\Util::DEBUG);
return $permissions;
}
/**
* @brief Check if backend implements action for contacts
* @param $actions bitwise-or'ed actions
* @returns boolean
*
* Returns the supported actions as int to be
* compared with \OCP\PERMISSION_CREATE etc.
*/
public function hasContactMethodFor($permission) {
return (bool)($this->getContactPermissions() & $permission);
}
/**
* @brief Check if backend implements action for contacts
* @param $actions bitwise-or'ed actions
* @returns boolean
*
* Returns the supported actions as int to be
* compared with \OCP\PERMISSION_CREATE etc.
*/
public function hasAddressBookMethodFor($permission) {
return (bool)($this->getAddressBookPermissions() & $permission);
}
/**
* Check if the backend has the address book
*
* This can be reimplemented in the backend to improve performance.
*
* @param string $addressbookid
* @return bool
*/
public function hasAddressBook($addressbookid) {
return count($this->getAddressBook($addressbookid)) > 0;
}
/**
* Returns the number of contacts in an address book.
* Implementations can choose to override this method to either
* get the result more effectively or to return null if the backend
* cannot determine the number.
*
* @param string $addressbookid
* @return integer|null
*/
public function numContacts($addressbookid) {
return count($this->getContacts($addressbookid));
}
/**
* Returns the list of addressbooks for a specific user.
*
* The returned arrays MUST contain a unique 'id' for the
* backend and a 'displayname', and it MAY contain a
* 'description'.
*
* @param array $options - Optional (backend specific options)
* @return array
*/
public abstract function getAddressBooksForUser(array $options = array());
/**
* Get an addressbook's properties
*
* The returned array MUST contain string: 'displayname',string: 'backend'
* and integer: 'permissions' value using there ownCloud CRUDS constants
* (which MUST be at least \OCP\PERMISSION_READ).
* Currently the only ones supported are 'displayname' and
* 'description', but backends can implement additional.
*
* @param string $addressbookid
* @param array $options - Optional (backend specific options)
* @return array|null $properties
*/
public abstract function getAddressBook($addressbookid, array $options = array());
/**
* Updates an addressbook's properties
*
* The $properties array contains the changes to be made.
*
* Currently the only ones supported are 'displayname' and
* 'description', but backends can implement additional.
*
* @param string $addressbookid
* @param array $properties
* @param array $options - Optional (backend specific options)
* @return bool
public function updateAddressBook($addressbookid, array $properties, array $options = array());
*/
/**
* Creates a new address book
*
* Classes that doesn't support adding address books MUST NOT implement this method.
*
* Currently the only ones supported are 'displayname' and
* 'description', but backends can implement additional.
* 'displayname' MUST be present.
*
* @param array $properties
* @param array $options - Optional (backend specific options)
* @return string|false The ID if the newly created AddressBook or false on error.
public function createAddressBook(array $properties, array $options = array());
*/
/**
* Deletes an entire address book and all its contents
*
* Classes that doesn't support deleting address books MUST NOT implement this method.
*
* @param string $addressbookid
* @param array $options - Optional (backend specific options)
* @return bool
public function deleteAddressBook($addressbookid, array $options = array());
*/
/**
* @brief Get the last modification time for an address book.
*
* Must return a UNIX time stamp or null if the backend
* doesn't support it.
*
* @param string $addressbookid
* @returns int | null
*/
public function lastModifiedAddressBook($addressbookid) {
}
/**
* @brief 'touch' an address book.
*
* If implemented this method must mark the address books
* modification date so lastModifiedAddressBook() can be
* used to invalidate the cache.
*
* @param string $addressbookid
*/
public function setModifiedAddressBook($addressbookid) {
}
/**
* Returns all contacts for a specific addressbook id.
*
* The returned array MUST contain the unique ID a string value 'id', a string
* value 'displayname', a string value 'owner' and an integer 'permissions' value using there
* ownCloud CRUDS constants (which MUST be at least \OCP\PERMISSION_READ), and SHOULD
* contain the properties of the contact formatted as a vCard 3.0
* https://tools.ietf.org/html/rfc2426 mapped to 'carddata' or as an
* \OCA\Contacts\VObject\VCard object mapped to 'vcard'.
*
* Example:
*
* array(
* 0 => array('id' => '4e111fef5df', 'owner' => 'foo', 'permissions' => 1, 'displayname' => 'John Q. Public', 'vcard' => $vobject),
* 1 => array('id' => 'bbcca2d1535', 'owner' => 'bar', 'permissions' => 32, 'displayname' => 'Jane Doe', 'carddata' => $data)
* );
*
* For contacts that contain loads of data, the 'carddata' or 'vcard' MAY be omitted
* as it can be fetched later.
*
* The following options are supported in the $options array:
*
* - 'limit': An integer value for the number of contacts to fetch in each call.
* - 'offset': The offset to start at.
* - 'omitdata': Whether to fetch the entire carddata or vcard.
*
* @param string $addressbookid
* @param array $options - Optional options
* @return array
*/
public abstract function getContacts($addressbookid, array $options = array());
/**
* Returns a specfic contact.
*
* Same as getContacts except that either 'carddata' or 'vcard' is mandatory.
*
* @param string $addressbookid
* @param mixed $id
* @param array $options - Optional options
* @return array|null
*/
public abstract function getContact($addressbookid, $id, array $options = array());
/**
* Creates a new contact
*
* Classes that doesn't support adding contacts MUST NOT implement this method.
*
* @param string $addressbookid
* @param VCard $contact
* @param array $options - Optional options
* @return string|bool The identifier for the new contact or false on error.
public function createContact($addressbookid, $contact, array $options = array());
*/
/**
* Updates a contact
*
* Classes that doesn't support updating contacts MUST NOT implement this method.
*
* @param string $addressbookid
* @param mixed $id
* @param VCard $contact
* @param array $options - Optional options
* @return bool
public function updateContact($addressbookid, $id, $carddata, array $options = array());
*/
/**
* Deletes a contact
*
* Classes that doesn't support deleting contacts MUST NOT implement this method.
*
* @param string $addressbookid
* @param mixed $id
* @param array $options - Optional options
* @return bool
public function deleteContact($addressbookid, $id, array $options = array());
*/
/**
* @brief Get the last modification time for a contact.
*
* Must return a UNIX time stamp or null if the backend
* doesn't support it.
*
* @param string $addressbookid
* @param mixed $id
* @returns int | null
*/
public function lastModifiedContact($addressbookid, $id) {
}
/**
* Creates a unique key for inserting into oc_preferences.
* As IDs can have any length and the key field is limited to 64 chars,
* the IDs are transformed to the first 8 chars of their md5 hash.
*
* @param string $addressBookId.
* @param string $contactId.
* @return string
*/
protected function combinedKey($addressBookId = null, $contactId = null) {
$key = $this->name;
if(!is_null($addressBookId)) {
$key .= '_' . substr(md5($addressBookId), 0, 8);
if(!is_null($contactId)) {
$key .= '_' . substr(md5($contactId), 0, 8);
}
} else if(!is_null($contactId)) {
throw new \BadMethodCallException(
__METHOD__ . ' cannot be called with a contact ID but no address book ID'
);
}
return $key;
}
/**
* @brief Query whether a backend or an address book is active
* @param string $addressbookid If null it checks whether the backend is activated.
* @return boolean
*/
public function isActive($addressBookId = null) {
$key = $this->combinedKey($addressBookId);
$key = 'active_' . $key;
return !!(\OCP\Config::getUserValue($this->userid, 'contacts', $key, 1));
}
/**
* @brief Activate a backend or an address book
* @param bool active
* @param string $addressbookid If null it activates the backend.
* @return boolean
*/
public function setActive($active, $addressBookId = null) {
$key = $this->combinedKey($addressBookId);
$key = 'active_' . $key;
$this->setModifiedAddressBook($addressBookId);
return \OCP\Config::setUserValue($this->userid, 'contacts', $key, (int)$active);
}
/**
* @brief get all the preferences for the addressbook
* @param string $id
* @return array Format array('param1' => 'value', 'param2' => 'value')
*/
public function getPreferences($addressBookId) {
$key = $this->combinedKey($addressBookId);
$key = 'prefs_' . $key;
$data = \OCP\Config::getUserValue($this->userid, 'contacts', $key, false);
return $data ? json_decode($data) : array();
}
/**
* @brief sets the preferences for the addressbook given in parameter
* @param string $id
* @param array the preferences, format array('param1' => 'value', 'param2' => 'value')
* @return boolean
*/
public function setPreferences($addressbookid, array $params) {
$key = $this->combinedKey($addressBookId);
$key = 'prefs_' . $key;
$data = json_encode($params);
return $data
? \OCP\Config::setUserValue($this->userid, 'contacts', $key, $data)
: false;
}
}