3 class Sabre_CardDAV_Backend_Std extends Sabre_CardDAV_Backend_Common
7 * @var null|Sabre_CardDAV_Backend_Std
9 private static $instance = null;
13 * @return Sabre_CardDAV_Backend_Std
15 public static function getInstance() {
16 if (self::$instance == null) {
17 self::$instance = new Sabre_CardDAV_Backend_Std();
19 return self::$instance;
26 public function __construct()
35 public function getNamespace()
37 return CARDDAV_NAMESPACE_PRIVATE;
44 public static function getBackendTypeName()
46 return t("Private Addressbooks");
50 * Returns the list of addressbooks for a specific user.
52 * @param string $principalUri
55 public function getAddressBooksForUser($principalUri)
57 $n = dav_compat_principal2namespace($principalUri);
58 if ($n["namespace"] != $this->getNamespace()) return array();
60 $addressBooks = array();
62 $books = q("SELECT * FROM %s%saddressbooks WHERE `namespace` = %d AND `namespace_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($n["namespace"]), IntVal($n["namespace_id"]));
63 foreach ($books as $row) {
64 if (in_array($row["uri"], $GLOBALS["CARDDAV_PRIVATE_SYSTEM_ADDRESSBOOKS"])) continue;
66 $addressBooks[] = array(
69 'principaluri' => $principalUri,
70 '{DAV:}displayname' => $row['displayname'],
71 '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' => $row['description'],
72 '{http://calendarserver.org/ns/}getctag' => $row['ctag'],
73 '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}supported-address-data' =>
74 new Sabre_CardDAV_Property_SupportedAddressData(),
84 * Creates a new address book
86 * @param string $principalUri
87 * @param string $url Just the 'basename' of the url.
88 * @param array $properties
89 * @throws Sabre_DAV_Exception_BadRequest
92 public function createAddressBook($principalUri, $url, array $properties)
94 $uid = dav_compat_principal2uid($principalUri);
97 'displayname' => null,
98 'description' => null,
99 'principaluri' => $principalUri,
103 foreach ($properties as $property=> $newValue) {
106 case '{DAV:}displayname' :
107 $values['displayname'] = $newValue;
109 case '{' . Sabre_CardDAV_Plugin::NS_CARDDAV . '}addressbook-description' :
110 $values['description'] = $newValue;
113 throw new Sabre_DAV_Exception_BadRequest('Unknown property: ' . $property);
118 q("INSERT INTO %s%saddressbooks (`uri`, `displayname`, `description`, `namespace`, `namespace_id`, `ctag`) VALUES ('%s', '%s', '%s', %d, %d, 1)",
119 CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($values["uri"]), dbesc($values["displayname"]), dbesc($values["description"]), CARDDAV_NAMESPACE_PRIVATE, IntVal($uid)
124 * Deletes an entire addressbook and all its contents
126 * @param int $addressBookId
127 * @throws Sabre_DAV_Exception_Forbidden
130 public function deleteAddressBook($addressBookId)
132 q("DELETE FROM %s%saddressbookobjects WHERE `id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($addressBookId));
133 q("DELETE FROM %s%saddressbooks WHERE `addressbook_id` = %d", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($addressBookId));
137 * Returns all cards for a specific addressbook id.
139 * This method should return the following properties for each card:
140 * * carddata - raw vcard data
141 * * uri - Some unique url
142 * * lastmodified - A unix timestamp
144 * It's recommended to also return the following properties:
145 * * etag - A unique etag. This must change every time the card changes.
146 * * size - The size of the card in bytes.
148 * If these last two properties are provided, less time will be spent
149 * calculating them. If they are specified, you can also ommit carddata.
150 * This may speed up certain requests, especially with large cards.
152 * @param string $addressbookId
155 public function getCards($addressbookId)
157 $r = q('SELECT `id`, `carddata`, `uri`, `lastmodified`, `etag`, `size`, `contact` FROM %s%saddressbookobjects WHERE `addressbook_id` = %d AND `manually_deleted` = 0',
158 CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($addressbookId)
165 * Returns a specfic card.
167 * The same set of properties must be returned as with getCards. The only
168 * exception is that 'carddata' is absolutely required.
170 * @param mixed $addressBookId
171 * @param string $cardUri
172 * @throws Sabre_DAV_Exception_NotFound
175 public function getCard($addressBookId, $cardUri)
177 $x = q("SELECT `id`, `carddata`, `uri`, `lastmodified`, `etag`, `size` FROM %s%saddressbookobjects WHERE `addressbook_id` = %d AND `uri` = '%s'",
178 CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($addressBookId), dbesc($cardUri));
179 if (count($x) == 0) throw new Sabre_DAV_Exception_NotFound();
184 * Creates a new card.
186 * The addressbook id will be passed as the first argument. This is the
187 * same id as it is returned from the getAddressbooksForUser method.
189 * The cardUri is a base uri, and doesn't include the full path. The
190 * cardData argument is the vcard body, and is passed as a string.
192 * It is possible to return an ETag from this method. This ETag is for the
193 * newly created resource, and must be enclosed with double quotes (that
194 * is, the string itself must contain the double quotes).
196 * You should only return the ETag if you store the carddata as-is. If a
197 * subsequent GET request on the same card does not have the same body,
198 * byte-by-byte and you did return an ETag here, clients tend to get
201 * If you don't return an ETag, you can just return null.
203 * @param string $addressBookId
204 * @param string $cardUri
205 * @param string $cardData
206 * @throws Sabre_DAV_Exception_Forbidden
209 public function createCard($addressBookId, $cardUri, $cardData)
211 $etag = md5($cardData);
212 q("INSERT INTO %s%saddressbookobjects (`carddata`, `uri`, `lastmodified`, `addressbook_id`, `etag`, `size`) VALUES ('%s', '%s', NOW(), %d, '%s', %d)",
213 CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($cardData), dbesc($cardUri), IntVal($addressBookId), dbesc($etag), strlen($cardData)
216 q('UPDATE %s%saddressbooks SET `ctag` = `ctag` + 1 WHERE `id` = %d', CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($addressBookId));
218 return '"' . $etag . '"';
225 * The addressbook id will be passed as the first argument. This is the
226 * same id as it is returned from the getAddressbooksForUser method.
228 * The cardUri is a base uri, and doesn't include the full path. The
229 * cardData argument is the vcard body, and is passed as a string.
231 * It is possible to return an ETag from this method. This ETag should
232 * match that of the updated resource, and must be enclosed with double
233 * quotes (that is: the string itself must contain the actual quotes).
235 * You should only return the ETag if you store the carddata as-is. If a
236 * subsequent GET request on the same card does not have the same body,
237 * byte-by-byte and you did return an ETag here, clients tend to get
240 * If you don't return an ETag, you can just return null.
242 * @param string $addressBookId
243 * @param string $cardUri
244 * @param string $cardData
245 * @throws Sabre_DAV_Exception_Forbidden
246 * @return string|null
248 public function updateCard($addressBookId, $cardUri, $cardData)
250 $etag = md5($cardData);
251 q("UPDATE %s%saddressbookobjects SET `carddata` = '%s', `lastmodified` = NOW(), `etag` = '%s', `size` = %d, `manually_edited` = 1 WHERE `uri` = '%s' AND `addressbook_id` = %d",
252 CALDAV_SQL_DB, CALDAV_SQL_PREFIX, dbesc($cardData), dbesc($etag), strlen($cardData), dbesc($cardUri), IntVal($addressBookId)
255 q('UPDATE %s%saddressbooks SET `ctag` = `ctag` + 1 WHERE `id` = %d', CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($addressBookId));
257 return '"' . $etag . '"';
263 * @param string $addressBookId
264 * @param string $cardUri
265 * @throws Sabre_DAV_Exception_Forbidden
268 public function deleteCard($addressBookId, $cardUri)
270 q("DELETE FROM %s%saddressbookobjects WHERE `addressbook_id` = %d AND `uri` = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($addressBookId), dbesc($cardUri));
271 q('UPDATE %s%saddressbooks SET `ctag` = `ctag` + 1 WHERE `id` = %d', CALDAV_SQL_DB, CALDAV_SQL_PREFIX, IntVal($addressBookId));