ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Sabre\CalDAV\Backend\PDO Class Reference

PDO CalDAV backend. More...

+ Inheritance diagram for Sabre\CalDAV\Backend\PDO:
+ Collaboration diagram for Sabre\CalDAV\Backend\PDO:

Public Member Functions

 __construct (\PDO $pdo)
 Creates the backend. More...
 
 getCalendarsForUser ($principalUri)
 Returns a list of calendars for a principal. More...
 
 createCalendar ($principalUri, $calendarUri, array $properties)
 Creates a new calendar for a principal. More...
 
 updateCalendar ($calendarId, \Sabre\DAV\PropPatch $propPatch)
 Updates properties for a calendar. More...
 
 deleteCalendar ($calendarId)
 Delete a calendar and all it's objects. More...
 
 getCalendarObjects ($calendarId)
 Returns all calendar objects within a calendar. More...
 
 getCalendarObject ($calendarId, $objectUri)
 Returns information from a single calendar object, based on it's object uri. More...
 
 getMultipleCalendarObjects ($calendarId, array $uris)
 Returns a list of calendar objects. More...
 
 createCalendarObject ($calendarId, $objectUri, $calendarData)
 Creates a new calendar object. More...
 
 updateCalendarObject ($calendarId, $objectUri, $calendarData)
 Updates an existing calendarobject, based on it's uri. More...
 
 deleteCalendarObject ($calendarId, $objectUri)
 Deletes an existing calendar object. More...
 
 calendarQuery ($calendarId, array $filters)
 Performs a calendar-query on the contents of this calendar. More...
 
 getCalendarObjectByUID ($principalUri, $uid)
 Searches through all of a users calendars and calendar objects to find an object with a specific UID. More...
 
 getChangesForCalendar ($calendarId, $syncToken, $syncLevel, $limit=null)
 The getChanges method returns all the changes that have happened, since the specified syncToken in the specified calendar. More...
 
 getSubscriptionsForUser ($principalUri)
 Returns a list of subscriptions for a principal. More...
 
 createSubscription ($principalUri, $uri, array $properties)
 Creates a new subscription for a principal. More...
 
 updateSubscription ($subscriptionId, DAV\PropPatch $propPatch)
 Updates a subscription. More...
 
 deleteSubscription ($subscriptionId)
 Deletes a subscription. More...
 
 getSchedulingObject ($principalUri, $objectUri)
 Returns a single scheduling object. More...
 
 getSchedulingObjects ($principalUri)
 Returns all scheduling objects for the inbox collection. More...
 
 deleteSchedulingObject ($principalUri, $objectUri)
 Deletes a scheduling object. More...
 
 createSchedulingObject ($principalUri, $objectUri, $objectData)
 Creates a new scheduling object. More...
 
 updateInvites ($calendarId, array $sharees)
 Updates the list of shares. More...
 
 getInvites ($calendarId)
 Returns the list of people whom a calendar is shared with. More...
 
 setPublishStatus ($calendarId, $value)
 Publishes a calendar. More...
 
- Public Member Functions inherited from Sabre\CalDAV\Backend\AbstractBackend
 updateCalendar ($calendarId, \Sabre\DAV\PropPatch $propPatch)
 Updates properties for a calendar. More...
 
 getMultipleCalendarObjects ($calendarId, array $uris)
 Returns a list of calendar objects. More...
 
 calendarQuery ($calendarId, array $filters)
 Performs a calendar-query on the contents of this calendar. More...
 
 getCalendarObjectByUID ($principalUri, $uid)
 Searches through all of a users calendars and calendar objects to find an object with a specific UID. More...
 

Data Fields

const MAX_DATE = '2038-01-01'
 We need to specify a max date, because we need to stop somewhere More...
 
 $calendarTableName = 'calendars'
 
 $calendarInstancesTableName = 'calendarinstances'
 
 $calendarObjectTableName = 'calendarobjects'
 
 $calendarChangesTableName = 'calendarchanges'
 
 $schedulingObjectTableName = 'schedulingobjects'
 
 $calendarSubscriptionsTableName = 'calendarsubscriptions'
 
 $propertyMap
 
 $subscriptionPropertyMap
 

Protected Member Functions

 getDenormalizedData ($calendarData)
 Parses some information from calendar objects, used for optimized calendar-queries. More...
 
 addChange ($calendarId, $objectUri, $operation)
 Adds a change record to the calendarchanges table. More...
 
- Protected Member Functions inherited from Sabre\CalDAV\Backend\AbstractBackend
 validateFilterForObject (array $object, array $filters)
 This method validates if a filter (as passed to calendarQuery) matches the given object. More...
 

Protected Attributes

 $pdo
 

Detailed Description

PDO CalDAV backend.

This backend is used to store calendar-data in a PDO database, such as sqlite or MySQL

Author
Evert Pot (http://evertpot.com/) http://sabre.io/license/ Modified BSD License

Definition at line 21 of file PDO.php.

Constructor & Destructor Documentation

◆ __construct()

Sabre\CalDAV\Backend\PDO::__construct ( \PDO  $pdo)

Creates the backend.

Parameters
\PDO$pdo

Definition at line 126 of file PDO.php.

References Sabre\CalDAV\Backend\PDO\$pdo.

126  {
127 
128  $this->pdo = $pdo;
129 
130  }

Member Function Documentation

◆ addChange()

Sabre\CalDAV\Backend\PDO::addChange (   $calendarId,
  $objectUri,
  $operation 
)
protected

Adds a change record to the calendarchanges table.

Parameters
mixed$calendarId
string$objectUri
int$operation1 = add, 2 = modify, 3 = delete.
Returns
void

Definition at line 1040 of file PDO.php.

References $stmt.

Referenced by Sabre\CalDAV\Backend\PDO\createCalendarObject(), Sabre\CalDAV\Backend\PDO\deleteCalendarObject(), Sabre\CalDAV\Backend\PDO\updateCalendar(), and Sabre\CalDAV\Backend\PDO\updateCalendarObject().

1040  {
1041 
1042  $stmt = $this->pdo->prepare('INSERT INTO ' . $this->calendarChangesTableName . ' (uri, synctoken, calendarid, operation) SELECT ?, synctoken, ?, ? FROM ' . $this->calendarTableName . ' WHERE id = ?');
1043  $stmt->execute([
1044  $objectUri,
1045  $calendarId,
1046  $operation,
1047  $calendarId
1048  ]);
1049  $stmt = $this->pdo->prepare('UPDATE ' . $this->calendarTableName . ' SET synctoken = synctoken + 1 WHERE id = ?');
1050  $stmt->execute([
1051  $calendarId
1052  ]);
1053 
1054  }
$stmt
+ Here is the caller graph for this function:

◆ calendarQuery()

Sabre\CalDAV\Backend\PDO::calendarQuery (   $calendarId,
array  $filters 
)

Performs a calendar-query on the contents of this calendar.

The calendar-query is defined in RFC4791 : CalDAV. Using the calendar-query it is possible for a client to request a specific set of object, based on contents of iCalendar properties, date-ranges and iCalendar component types (VTODO, VEVENT).

This method should just return a list of (relative) urls that match this query.

The list of filters are specified as an array. The exact array is documented by .

Note that it is extremely likely that getCalendarObject for every path returned from this method will be called almost immediately after. You may want to anticipate this to speed up these requests.

This method provides a default implementation, which parses all the iCalendar objects in the specified calendar.

This default may well be good enough for personal use, and calendars that aren't very large. But if you anticipate high usage, big calendars or high loads, you are strongly adviced to optimize certain paths.

The best way to do so is override this method and to optimize specifically for 'common filters'.

Requests that are extremely common are:

  • requests for just VEVENTS
  • requests for just VTODO
  • requests with a time-range-filter on a VEVENT.

..and combinations of these requests. It may not be worth it to try to handle every possible situation and just rely on the (relatively easy to use) CalendarQueryValidator to handle the rest.

Note that especially time-range-filters may be difficult to parse. A time-range filter specified on a VEVENT must for instance also handle recurrence rules correctly. A good example of how to interpret all these filters can also simply be found in . This class is as correct as possible, so it gives you a good idea on what type of stuff you need to think of.

This specific implementation (for the PDO) backend optimizes filters on specific components, and VEVENT time-ranges.

Parameters
mixed$calendarId
array$filters
Returns
array

Implements Sabre\CalDAV\Backend\BackendInterface.

Definition at line 786 of file PDO.php.

References $query, $result, $row, $stmt, $values, and Sabre\CalDAV\Backend\AbstractBackend\validateFilterForObject().

786  {
787 
788  if (!is_array($calendarId)) {
789  throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
790  }
791  list($calendarId, $instanceId) = $calendarId;
792 
793  $componentType = null;
794  $requirePostFilter = true;
795  $timeRange = null;
796 
797  // if no filters were specified, we don't need to filter after a query
798  if (!$filters['prop-filters'] && !$filters['comp-filters']) {
799  $requirePostFilter = false;
800  }
801 
802  // Figuring out if there's a component filter
803  if (count($filters['comp-filters']) > 0 && !$filters['comp-filters'][0]['is-not-defined']) {
804  $componentType = $filters['comp-filters'][0]['name'];
805 
806  // Checking if we need post-filters
807  if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['time-range'] && !$filters['comp-filters'][0]['prop-filters']) {
808  $requirePostFilter = false;
809  }
810  // There was a time-range filter
811  if ($componentType == 'VEVENT' && isset($filters['comp-filters'][0]['time-range'])) {
812  $timeRange = $filters['comp-filters'][0]['time-range'];
813 
814  // If start time OR the end time is not specified, we can do a
815  // 100% accurate mysql query.
816  if (!$filters['prop-filters'] && !$filters['comp-filters'][0]['comp-filters'] && !$filters['comp-filters'][0]['prop-filters'] && (!$timeRange['start'] || !$timeRange['end'])) {
817  $requirePostFilter = false;
818  }
819  }
820 
821  }
822 
823  if ($requirePostFilter) {
824  $query = "SELECT uri, calendardata FROM " . $this->calendarObjectTableName . " WHERE calendarid = :calendarid";
825  } else {
826  $query = "SELECT uri FROM " . $this->calendarObjectTableName . " WHERE calendarid = :calendarid";
827  }
828 
829  $values = [
830  'calendarid' => $calendarId,
831  ];
832 
833  if ($componentType) {
834  $query .= " AND componenttype = :componenttype";
835  $values['componenttype'] = $componentType;
836  }
837 
838  if ($timeRange && $timeRange['start']) {
839  $query .= " AND lastoccurence > :startdate";
840  $values['startdate'] = $timeRange['start']->getTimeStamp();
841  }
842  if ($timeRange && $timeRange['end']) {
843  $query .= " AND firstoccurence < :enddate";
844  $values['enddate'] = $timeRange['end']->getTimeStamp();
845  }
846 
847  $stmt = $this->pdo->prepare($query);
848  $stmt->execute($values);
849 
850  $result = [];
851  while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
852  if ($requirePostFilter) {
853  if (!$this->validateFilterForObject($row, $filters)) {
854  continue;
855  }
856  }
857  $result[] = $row['uri'];
858 
859  }
860 
861  return $result;
862 
863  }
$result
$stmt
$values
$query
$row
validateFilterForObject(array $object, array $filters)
This method validates if a filter (as passed to calendarQuery) matches the given object.
+ Here is the call graph for this function:

◆ createCalendar()

Sabre\CalDAV\Backend\PDO::createCalendar (   $principalUri,
  $calendarUri,
array  $properties 
)

Creates a new calendar for a principal.

If the creation was a success, an id must be returned that can be used to reference this calendar in other methods, such as updateCalendar.

Parameters
string$principalUri
string$calendarUri
array$properties
Returns
string

Implements Sabre\CalDAV\Backend\BackendInterface.

Definition at line 232 of file PDO.php.

References $stmt, $values, and Sabre\CalDAV\Plugin\NS_CALDAV.

232  {
233 
234  $fieldNames = [
235  'principaluri',
236  'uri',
237  'transparent',
238  'calendarid',
239  ];
240  $values = [
241  ':principaluri' => $principalUri,
242  ':uri' => $calendarUri,
243  ':transparent' => 0,
244  ];
245 
246 
247  $sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set';
248  if (!isset($properties[$sccs])) {
249  // Default value
250  $components = 'VEVENT,VTODO';
251  } else {
252  if (!($properties[$sccs] instanceof CalDAV\Xml\Property\SupportedCalendarComponentSet)) {
253  throw new DAV\Exception('The ' . $sccs . ' property must be of type: \Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet');
254  }
255  $components = implode(',', $properties[$sccs]->getValue());
256  }
257  $transp = '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp';
258  if (isset($properties[$transp])) {
259  $values[':transparent'] = $properties[$transp]->getValue() === 'transparent' ? 1 : 0;
260  }
261  $stmt = $this->pdo->prepare("INSERT INTO " . $this->calendarTableName . " (synctoken, components) VALUES (1, ?)");
262  $stmt->execute([$components]);
263 
264  $calendarId = $this->pdo->lastInsertId(
265  $this->calendarTableName . '_id_seq'
266  );
267 
268  $values[':calendarid'] = $calendarId;
269 
270  foreach ($this->propertyMap as $xmlName => $dbName) {
271  if (isset($properties[$xmlName])) {
272 
273  $values[':' . $dbName] = $properties[$xmlName];
274  $fieldNames[] = $dbName;
275  }
276  }
277 
278  $stmt = $this->pdo->prepare("INSERT INTO " . $this->calendarInstancesTableName . " (" . implode(', ', $fieldNames) . ") VALUES (" . implode(', ', array_keys($values)) . ")");
279 
280  $stmt->execute($values);
281 
282  return [
283  $calendarId,
284  $this->pdo->lastInsertId($this->calendarInstancesTableName . '_id_seq')
285  ];
286 
287  }
$stmt
$values
const NS_CALDAV
This is the official CalDAV namespace.
Definition: Plugin.php:33

◆ createCalendarObject()

Sabre\CalDAV\Backend\PDO::createCalendarObject (   $calendarId,
  $objectUri,
  $calendarData 
)

Creates a new calendar object.

The object uri is only the basename, or filename and not a full path.

It is possible return an etag from this function, which will be used in the response to this PUT request. Note that the ETag must be surrounded by double-quotes.

However, you should only really return this ETag if you don't mangle the calendar-data. If the result of a subsequent GET to this object is not the exact same as this request body, you should omit the ETag.

Parameters
mixed$calendarId
string$objectUri
string$calendarData
Returns
string|null

Implements Sabre\CalDAV\Backend\BackendInterface.

Definition at line 561 of file PDO.php.

References $stmt, Sabre\CalDAV\Backend\PDO\addChange(), and Sabre\CalDAV\Backend\PDO\getDenormalizedData().

561  {
562 
563  if (!is_array($calendarId)) {
564  throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
565  }
566  list($calendarId, $instanceId) = $calendarId;
567 
568  $extraData = $this->getDenormalizedData($calendarData);
569 
570  $stmt = $this->pdo->prepare('INSERT INTO ' . $this->calendarObjectTableName . ' (calendarid, uri, calendardata, lastmodified, etag, size, componenttype, firstoccurence, lastoccurence, uid) VALUES (?,?,?,?,?,?,?,?,?,?)');
571  $stmt->execute([
572  $calendarId,
573  $objectUri,
574  $calendarData,
575  time(),
576  $extraData['etag'],
577  $extraData['size'],
578  $extraData['componentType'],
579  $extraData['firstOccurence'],
580  $extraData['lastOccurence'],
581  $extraData['uid'],
582  ]);
583  $this->addChange($calendarId, $objectUri, 1);
584 
585  return '"' . $extraData['etag'] . '"';
586 
587  }
$stmt
addChange($calendarId, $objectUri, $operation)
Adds a change record to the calendarchanges table.
Definition: PDO.php:1040
getDenormalizedData($calendarData)
Parses some information from calendar objects, used for optimized calendar-queries.
Definition: PDO.php:640
+ Here is the call graph for this function:

◆ createSchedulingObject()

Sabre\CalDAV\Backend\PDO::createSchedulingObject (   $principalUri,
  $objectUri,
  $objectData 
)

Creates a new scheduling object.

This should land in a users' inbox.

Parameters
string$principalUri
string$objectUri
string$objectData
Returns
void

Implements Sabre\CalDAV\Backend\SchedulingSupport.

Definition at line 1329 of file PDO.php.

References $stmt.

1329  {
1330 
1331  $stmt = $this->pdo->prepare('INSERT INTO ' . $this->schedulingObjectTableName . ' (principaluri, calendardata, uri, lastmodified, etag, size) VALUES (?, ?, ?, ?, ?, ?)');
1332  $stmt->execute([$principalUri, $objectData, $objectUri, time(), md5($objectData), strlen($objectData)]);
1333 
1334  }
$stmt

◆ createSubscription()

Sabre\CalDAV\Backend\PDO::createSubscription (   $principalUri,
  $uri,
array  $properties 
)

Creates a new subscription for a principal.

If the creation was a success, an id must be returned that can be used to reference this subscription in other methods, such as updateSubscription.

Parameters
string$principalUri
string$uri
array$properties
Returns
mixed

Implements Sabre\CalDAV\Backend\SubscriptionSupport.

Definition at line 1139 of file PDO.php.

References $stmt, and $values.

1139  {
1140 
1141  $fieldNames = [
1142  'principaluri',
1143  'uri',
1144  'source',
1145  'lastmodified',
1146  ];
1147 
1148  if (!isset($properties['{http://calendarserver.org/ns/}source'])) {
1149  throw new Forbidden('The {http://calendarserver.org/ns/}source property is required when creating subscriptions');
1150  }
1151 
1152  $values = [
1153  ':principaluri' => $principalUri,
1154  ':uri' => $uri,
1155  ':source' => $properties['{http://calendarserver.org/ns/}source']->getHref(),
1156  ':lastmodified' => time(),
1157  ];
1158 
1159  foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) {
1160  if (isset($properties[$xmlName])) {
1161 
1162  $values[':' . $dbName] = $properties[$xmlName];
1163  $fieldNames[] = $dbName;
1164  }
1165  }
1166 
1167  $stmt = $this->pdo->prepare("INSERT INTO " . $this->calendarSubscriptionsTableName . " (" . implode(', ', $fieldNames) . ") VALUES (" . implode(', ', array_keys($values)) . ")");
1168  $stmt->execute($values);
1169 
1170  return $this->pdo->lastInsertId(
1171  $this->calendarSubscriptionsTableName . '_id_seq'
1172  );
1173 
1174  }
$stmt
$values

◆ deleteCalendar()

Sabre\CalDAV\Backend\PDO::deleteCalendar (   $calendarId)

Delete a calendar and all it's objects.

Parameters
mixed$calendarId
Returns
void

If the user is the owner of the calendar, we delete all data and all instances.

If it was an instance of a shared calendar, we only delete that instance.

Implements Sabre\CalDAV\Backend\BackendInterface.

Definition at line 354 of file PDO.php.

References $stmt.

354  {
355 
356  if (!is_array($calendarId)) {
357  throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
358  }
359  list($calendarId, $instanceId) = $calendarId;
360 
361  $stmt = $this->pdo->prepare('SELECT access FROM ' . $this->calendarInstancesTableName . ' where id = ?');
362  $stmt->execute([$instanceId]);
363  $access = (int)$stmt->fetchColumn();
364 
365  if ($access === \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER) {
366 
371  $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ?');
372  $stmt->execute([$calendarId]);
373 
374  $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarChangesTableName . ' WHERE calendarid = ?');
375  $stmt->execute([$calendarId]);
376 
377  $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarInstancesTableName . ' WHERE calendarid = ?');
378  $stmt->execute([$calendarId]);
379 
380  $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarTableName . ' WHERE id = ?');
381  $stmt->execute([$calendarId]);
382 
383  } else {
384 
389  $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarInstancesTableName . ' WHERE id = ?');
390  $stmt->execute([$instanceId]);
391 
392  }
393 
394 
395  }
$stmt

◆ deleteCalendarObject()

Sabre\CalDAV\Backend\PDO::deleteCalendarObject (   $calendarId,
  $objectUri 
)

Deletes an existing calendar object.

The object uri is only the basename, or filename and not a full path.

Parameters
mixed$calendarId
string$objectUri
Returns
void

Implements Sabre\CalDAV\Backend\BackendInterface.

Definition at line 720 of file PDO.php.

References $stmt, and Sabre\CalDAV\Backend\PDO\addChange().

720  {
721 
722  if (!is_array($calendarId)) {
723  throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
724  }
725  list($calendarId, $instanceId) = $calendarId;
726 
727  $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ? AND uri = ?');
728  $stmt->execute([$calendarId, $objectUri]);
729 
730  $this->addChange($calendarId, $objectUri, 3);
731 
732  }
$stmt
addChange($calendarId, $objectUri, $operation)
Adds a change record to the calendarchanges table.
Definition: PDO.php:1040
+ Here is the call graph for this function:

◆ deleteSchedulingObject()

Sabre\CalDAV\Backend\PDO::deleteSchedulingObject (   $principalUri,
  $objectUri 
)

Deletes a scheduling object.

Parameters
string$principalUri
string$objectUri
Returns
void

Implements Sabre\CalDAV\Backend\SchedulingSupport.

Definition at line 1314 of file PDO.php.

References $stmt.

1314  {
1315 
1316  $stmt = $this->pdo->prepare('DELETE FROM ' . $this->schedulingObjectTableName . ' WHERE principaluri = ? AND uri = ?');
1317  $stmt->execute([$principalUri, $objectUri]);
1318 
1319  }
$stmt

◆ deleteSubscription()

Sabre\CalDAV\Backend\PDO::deleteSubscription (   $subscriptionId)

Deletes a subscription.

Parameters
mixed$subscriptionId
Returns
void

Implements Sabre\CalDAV\Backend\SubscriptionSupport.

Definition at line 1235 of file PDO.php.

References $stmt.

1235  {
1236 
1237  $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarSubscriptionsTableName . ' WHERE id = ?');
1238  $stmt->execute([$subscriptionId]);
1239 
1240  }
$stmt

◆ getCalendarObject()

Sabre\CalDAV\Backend\PDO::getCalendarObject (   $calendarId,
  $objectUri 
)

Returns information from a single calendar object, based on it's object uri.

The object uri is only the basename, or filename and not a full path.

The returned array must have the same keys as getCalendarObjects. The 'calendardata' object is required here though, while it's not required for getCalendarObjects.

This method must return null if the object did not exist.

Parameters
mixed$calendarId
string$objectUri
Returns
array|null

Implements Sabre\CalDAV\Backend\BackendInterface.

Definition at line 470 of file PDO.php.

References $row, and $stmt.

470  {
471 
472  if (!is_array($calendarId)) {
473  throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
474  }
475  list($calendarId, $instanceId) = $calendarId;
476 
477  $stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size, calendardata, componenttype FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ? AND uri = ?');
478  $stmt->execute([$calendarId, $objectUri]);
479  $row = $stmt->fetch(\PDO::FETCH_ASSOC);
480 
481  if (!$row) return null;
482 
483  return [
484  'id' => $row['id'],
485  'uri' => $row['uri'],
486  'lastmodified' => (int)$row['lastmodified'],
487  'etag' => '"' . $row['etag'] . '"',
488  'size' => (int)$row['size'],
489  'calendardata' => $row['calendardata'],
490  'component' => strtolower($row['componenttype']),
491  ];
492 
493  }
$stmt
$row

◆ getCalendarObjectByUID()

Sabre\CalDAV\Backend\PDO::getCalendarObjectByUID (   $principalUri,
  $uid 
)

Searches through all of a users calendars and calendar objects to find an object with a specific UID.

This method should return the path to this object, relative to the calendar home, so this path usually only contains two parts:

calendarpath/objectpath.ics

If the uid is not found, return null.

This method should only consider * objects that the principal owns, so any calendars owned by other principals that also appear in this collection should be ignored.

Parameters
string$principalUri
string$uid
Returns
string|null

Implements Sabre\CalDAV\Backend\BackendInterface.

Definition at line 884 of file PDO.php.

References $query, $row, and $stmt.

884  {
885 
886  $query = <<<SQL
887 SELECT
888  calendar_instances.uri AS calendaruri, calendarobjects.uri as objecturi
889 FROM
890  $this->calendarObjectTableName AS calendarobjects
891 LEFT JOIN
892  $this->calendarInstancesTableName AS calendar_instances
893  ON calendarobjects.calendarid = calendar_instances.calendarid
894 WHERE
895  calendar_instances.principaluri = ?
896  AND
897  calendarobjects.uid = ?
898 SQL;
899 
900  $stmt = $this->pdo->prepare($query);
901  $stmt->execute([$principalUri, $uid]);
902 
903  if ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
904  return $row['calendaruri'] . '/' . $row['objecturi'];
905  }
906 
907  }
$stmt
$query
$row

◆ getCalendarObjects()

Sabre\CalDAV\Backend\PDO::getCalendarObjects (   $calendarId)

Returns all calendar objects within a calendar.

Every item contains an array with the following keys:

  • calendardata - The iCalendar-compatible calendar data
  • uri - a unique key which will be used to construct the uri. This can be any arbitrary string, but making sure it ends with '.ics' is a good idea. This is only the basename, or filename, not the full path.
  • lastmodified - a timestamp of the last modification time
  • etag - An arbitrary string, surrounded by double-quotes. (e.g.: ' "abcdef"')
  • size - The size of the calendar objects, in bytes.
  • component - optional, a string containing the type of object, such as 'vevent' or 'vtodo'. If specified, this will be used to populate the Content-Type header.

Note that the etag is optional, but it's highly encouraged to return for speed reasons.

The calendardata is also optional. If it's not returned 'getCalendarObject' will be called later, which is expected to return calendardata.

If neither etag or size are specified, the calendardata will be used/fetched to determine these numbers. If both are specified the amount of times this is needed is reduced by a great degree.

Parameters
mixed$calendarId
Returns
array

Implements Sabre\CalDAV\Backend\BackendInterface.

Definition at line 428 of file PDO.php.

References $result, $row, and $stmt.

428  {
429 
430  if (!is_array($calendarId)) {
431  throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
432  }
433  list($calendarId, $instanceId) = $calendarId;
434 
435  $stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size, componenttype FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ?');
436  $stmt->execute([$calendarId]);
437 
438  $result = [];
439  foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
440  $result[] = [
441  'id' => $row['id'],
442  'uri' => $row['uri'],
443  'lastmodified' => (int)$row['lastmodified'],
444  'etag' => '"' . $row['etag'] . '"',
445  'size' => (int)$row['size'],
446  'component' => strtolower($row['componenttype']),
447  ];
448  }
449 
450  return $result;
451 
452  }
$result
$stmt
$row

◆ getCalendarsForUser()

Sabre\CalDAV\Backend\PDO::getCalendarsForUser (   $principalUri)

Returns a list of calendars for a principal.

Every project is an array with the following keys:

  • id, a unique id that will be used by other functions to modify the calendar. This can be the same as the uri or a database key.
  • uri. This is just the 'base uri' or 'filename' of the calendar.
  • principaluri. The owner of the calendar. Almost always the same as principalUri passed to this method.

Furthermore it can contain webdav properties in clark notation. A very common one is '{DAV:}displayname'.

Many clients also require: {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set For this property, you can just return an instance of Sabre.

If you return {http://sabredav.org/ns}read-only and set the value to 1, ACL will automatically be put in read-only mode.

Parameters
string$principalUri
Returns
array

Implements Sabre\CalDAV\Backend\BackendInterface.

Definition at line 156 of file PDO.php.

References $calendar, $row, $stmt, Sabre\CalDAV\Plugin\NS_CALDAV, and Sabre\CalDAV\Plugin\NS_CALENDARSERVER.

156  {
157 
158  $fields = array_values($this->propertyMap);
159  $fields[] = 'calendarid';
160  $fields[] = 'uri';
161  $fields[] = 'synctoken';
162  $fields[] = 'components';
163  $fields[] = 'principaluri';
164  $fields[] = 'transparent';
165  $fields[] = 'access';
166 
167  // Making fields a comma-delimited list
168  $fields = implode(', ', $fields);
169  $stmt = $this->pdo->prepare(<<<SQL
170 SELECT {$this->calendarInstancesTableName}.id as id, $fields FROM {$this->calendarInstancesTableName}
171  LEFT JOIN {$this->calendarTableName} ON
172  {$this->calendarInstancesTableName}.calendarid = {$this->calendarTableName}.id
173 WHERE principaluri = ? ORDER BY calendarorder ASC
174 SQL
175  );
176  $stmt->execute([$principalUri]);
177 
178  $calendars = [];
179  while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
180 
181  $components = [];
182  if ($row['components']) {
183  $components = explode(',', $row['components']);
184  }
185 
186  $calendar = [
187  'id' => [(int)$row['calendarid'], (int)$row['id']],
188  'uri' => $row['uri'],
189  'principaluri' => $row['principaluri'],
190  '{' . CalDAV\Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken'] ? $row['synctoken'] : '0'),
191  '{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0',
192  '{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet($components),
193  '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp($row['transparent'] ? 'transparent' : 'opaque'),
194  'share-resource-uri' => '/ns/share/' . $row['calendarid'],
195  ];
196 
197  $calendar['share-access'] = (int)$row['access'];
198  // 1 = owner, 2 = readonly, 3 = readwrite
199  if ($row['access'] > 1) {
200  // We need to find more information about the original owner.
201  //$stmt2 = $this->pdo->prepare('SELECT principaluri FROM ' . $this->calendarInstancesTableName . ' WHERE access = 1 AND id = ?');
202  //$stmt2->execute([$row['id']]);
203 
204  // read-only is for backwards compatbility. Might go away in
205  // the future.
206  $calendar['read-only'] = (int)$row['access'] === \Sabre\DAV\Sharing\Plugin::ACCESS_READ;
207  }
208 
209  foreach ($this->propertyMap as $xmlName => $dbName) {
210  $calendar[$xmlName] = $row[$dbName];
211  }
212 
213  $calendars[] = $calendar;
214 
215  }
216 
217  return $calendars;
218 
219  }
$stmt
const NS_CALENDARSERVER
This is the namespace for the proprietary calendarserver extensions.
Definition: Plugin.php:38
$row
const NS_CALDAV
This is the official CalDAV namespace.
Definition: Plugin.php:33

◆ getChangesForCalendar()

Sabre\CalDAV\Backend\PDO::getChangesForCalendar (   $calendarId,
  $syncToken,
  $syncLevel,
  $limit = null 
)

The getChanges method returns all the changes that have happened, since the specified syncToken in the specified calendar.

This function should return an array, such as the following:

[ 'syncToken' => 'The current synctoken', 'added' => [ 'new.txt', ], 'modified' => [ 'modified.txt', ], 'deleted' => [ 'foo.php.bak', 'old.txt' ] ];

The returned syncToken property should reflect the current syncToken of the calendar, as reported in the {http://sabredav.org/ns}sync-token property this is needed here too, to ensure the operation is atomic.

If the $syncToken argument is specified as null, this is an initial sync, and all members should be reported.

The modified property is an array of nodenames that have changed since the last token.

The deleted property is an array with nodenames, that have been deleted from collection.

The $syncLevel argument is basically the 'depth' of the report. If it's 1, you only have to report changes that happened only directly in immediate descendants. If it's 2, it should also include changes from the nodes below the child collections. (grandchildren)

The $limit argument allows a client to specify how many results should be returned at most. If the limit is not specified, it should be treated as infinite.

If the limit (infinite or not) is higher than you're willing to return, you should throw a Sabre() exception.

If the syncToken is expired (due to data cleanup) or unknown, you must return null.

The limit is 'suggestive'. You are free to ignore it.

Parameters
mixed$calendarId
string$syncToken
int$syncLevel
int$limit
Returns
array

Implements Sabre\CalDAV\Backend\SyncSupport.

Definition at line 965 of file PDO.php.

References $query, $result, $row, and $stmt.

965  {
966 
967  if (!is_array($calendarId)) {
968  throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
969  }
970  list($calendarId, $instanceId) = $calendarId;
971 
972  // Current synctoken
973  $stmt = $this->pdo->prepare('SELECT synctoken FROM ' . $this->calendarTableName . ' WHERE id = ?');
974  $stmt->execute([$calendarId]);
975  $currentToken = $stmt->fetchColumn(0);
976 
977  if (is_null($currentToken)) return null;
978 
979  $result = [
980  'syncToken' => $currentToken,
981  'added' => [],
982  'modified' => [],
983  'deleted' => [],
984  ];
985 
986  if ($syncToken) {
987 
988  $query = "SELECT uri, operation FROM " . $this->calendarChangesTableName . " WHERE synctoken >= ? AND synctoken < ? AND calendarid = ? ORDER BY synctoken";
989  if ($limit > 0) $query .= " LIMIT " . (int)$limit;
990 
991  // Fetching all changes
992  $stmt = $this->pdo->prepare($query);
993  $stmt->execute([$syncToken, $currentToken, $calendarId]);
994 
995  $changes = [];
996 
997  // This loop ensures that any duplicates are overwritten, only the
998  // last change on a node is relevant.
999  while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
1000 
1001  $changes[$row['uri']] = $row['operation'];
1002 
1003  }
1004 
1005  foreach ($changes as $uri => $operation) {
1006 
1007  switch ($operation) {
1008  case 1 :
1009  $result['added'][] = $uri;
1010  break;
1011  case 2 :
1012  $result['modified'][] = $uri;
1013  break;
1014  case 3 :
1015  $result['deleted'][] = $uri;
1016  break;
1017  }
1018 
1019  }
1020  } else {
1021  // No synctoken supplied, this is the initial sync.
1022  $query = "SELECT uri FROM " . $this->calendarObjectTableName . " WHERE calendarid = ?";
1023  $stmt = $this->pdo->prepare($query);
1024  $stmt->execute([$calendarId]);
1025 
1026  $result['added'] = $stmt->fetchAll(\PDO::FETCH_COLUMN);
1027  }
1028  return $result;
1029 
1030  }
$result
$stmt
$query
$row

◆ getDenormalizedData()

Sabre\CalDAV\Backend\PDO::getDenormalizedData (   $calendarData)
protected

Parses some information from calendar objects, used for optimized calendar-queries.

Returns an array with the following keys:

  • etag - An md5 checksum of the object without the quotes.
  • size - Size of the object in bytes
  • componentType - VEVENT, VTODO or VJOURNAL
  • firstOccurence
  • lastOccurence
  • uid - value of the UID property
Parameters
string$calendarData
Returns
array

Definition at line 640 of file PDO.php.

References $end, Sabre\VObject\DateTimeParser\parse(), and Sabre\VObject\Reader\read().

Referenced by Sabre\CalDAV\Backend\PDO\createCalendarObject(), and Sabre\CalDAV\Backend\PDO\updateCalendarObject().

640  {
641 
642  $vObject = VObject\Reader::read($calendarData);
643  $componentType = null;
644  $component = null;
645  $firstOccurence = null;
646  $lastOccurence = null;
647  $uid = null;
648  foreach ($vObject->getComponents() as $component) {
649  if ($component->name !== 'VTIMEZONE') {
650  $componentType = $component->name;
651  $uid = (string)$component->UID;
652  break;
653  }
654  }
655  if (!$componentType) {
656  throw new \Sabre\DAV\Exception\BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component');
657  }
658  if ($componentType === 'VEVENT') {
659  $firstOccurence = $component->DTSTART->getDateTime()->getTimeStamp();
660  // Finding the last occurence is a bit harder
661  if (!isset($component->RRULE)) {
662  if (isset($component->DTEND)) {
663  $lastOccurence = $component->DTEND->getDateTime()->getTimeStamp();
664  } elseif (isset($component->DURATION)) {
665  $endDate = clone $component->DTSTART->getDateTime();
666  $endDate = $endDate->add(VObject\DateTimeParser::parse($component->DURATION->getValue()));
667  $lastOccurence = $endDate->getTimeStamp();
668  } elseif (!$component->DTSTART->hasTime()) {
669  $endDate = clone $component->DTSTART->getDateTime();
670  $endDate = $endDate->modify('+1 day');
671  $lastOccurence = $endDate->getTimeStamp();
672  } else {
673  $lastOccurence = $firstOccurence;
674  }
675  } else {
676  $it = new VObject\Recur\EventIterator($vObject, (string)$component->UID);
677  $maxDate = new \DateTime(self::MAX_DATE);
678  if ($it->isInfinite()) {
679  $lastOccurence = $maxDate->getTimeStamp();
680  } else {
681  $end = $it->getDtEnd();
682  while ($it->valid() && $end < $maxDate) {
683  $end = $it->getDtEnd();
684  $it->next();
685 
686  }
687  $lastOccurence = $end->getTimeStamp();
688  }
689 
690  }
691 
692  // Ensure Occurence values are positive
693  if ($firstOccurence < 0) $firstOccurence = 0;
694  if ($lastOccurence < 0) $lastOccurence = 0;
695  }
696 
697  // Destroy circular references to PHP will GC the object.
698  $vObject->destroy();
699 
700  return [
701  'etag' => md5($calendarData),
702  'size' => strlen($calendarData),
703  'componentType' => $componentType,
704  'firstOccurence' => $firstOccurence,
705  'lastOccurence' => $lastOccurence,
706  'uid' => $uid,
707  ];
708 
709  }
static parse($date, $referenceTz=null)
Parses either a Date or DateTime, or Duration value.
static read($data, $options=0, $charset='UTF-8')
Parses a vCard or iCalendar object, and returns the top component.
Definition: Reader.php:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getInvites()

Sabre\CalDAV\Backend\PDO::getInvites (   $calendarId)

Returns the list of people whom a calendar is shared with.

Every item in the returned list must be a Sharee object with at least the following properties set: $href $shareAccess $inviteStatus

and optionally: $properties

Parameters
mixed$calendarId
Returns
[]

Everyone is always immediately accepted, for now.

Implements Sabre\CalDAV\Backend\SharingSupport.

Definition at line 1456 of file PDO.php.

References $query, $result, $row, $stmt, and Sabre\HTTP\encodePath().

Referenced by Sabre\CalDAV\Backend\PDO\updateInvites().

1456  {
1457 
1458  if (!is_array($calendarId)) {
1459  throw new \InvalidArgumentException('The value passed to getInvites() is expected to be an array with a calendarId and an instanceId');
1460  }
1461  list($calendarId, $instanceId) = $calendarId;
1462 
1463  $query = <<<SQL
1464 SELECT
1465  principaluri,
1466  access,
1467  share_href,
1468  share_displayname,
1469  share_invitestatus
1470 FROM {$this->calendarInstancesTableName}
1471 WHERE
1472  calendarid = ?
1473 SQL;
1474 
1475  $stmt = $this->pdo->prepare($query);
1476  $stmt->execute([$calendarId]);
1477 
1478  $result = [];
1479  while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
1480 
1481  $result[] = new Sharee([
1482  'href' => isset($row['share_href']) ? $row['share_href'] : \Sabre\HTTP\encodePath($row['principaluri']),
1483  'access' => (int)$row['access'],
1485  'inviteStatus' => (int)$row['share_invitestatus'],
1486  'properties' =>
1487  !empty($row['share_displayname'])
1488  ? ['{DAV:}displayname' => $row['share_displayname']]
1489  : [],
1490  'principal' => $row['principaluri'],
1491  ]);
1492 
1493  }
1494  return $result;
1495 
1496  }
$result
encodePath($path)
Encodes the path of a url.
Definition: functions.php:386
$stmt
$query
$row
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getMultipleCalendarObjects()

Sabre\CalDAV\Backend\PDO::getMultipleCalendarObjects (   $calendarId,
array  $uris 
)

Returns a list of calendar objects.

This method should work identical to getCalendarObject, but instead return all the calendar objects in the list as an array.

If the backend supports this, it may allow for some speed-ups.

Parameters
mixed$calendarId
array$uris
Returns
array

Implements Sabre\CalDAV\Backend\BackendInterface.

Definition at line 507 of file PDO.php.

References $query, $result, $row, and $stmt.

507  {
508 
509  if (!is_array($calendarId)) {
510  throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
511  }
512  list($calendarId, $instanceId) = $calendarId;
513 
514  $result = [];
515  foreach (array_chunk($uris, 900) as $chunk) {
516  $query = 'SELECT id, uri, lastmodified, etag, calendarid, size, calendardata, componenttype FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ? AND uri IN (';
517  // Inserting a whole bunch of question marks
518  $query .= implode(',', array_fill(0, count($chunk), '?'));
519  $query .= ')';
520 
521  $stmt = $this->pdo->prepare($query);
522  $stmt->execute(array_merge([$calendarId], $chunk));
523 
524  while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
525 
526  $result[] = [
527  'id' => $row['id'],
528  'uri' => $row['uri'],
529  'lastmodified' => (int)$row['lastmodified'],
530  'etag' => '"' . $row['etag'] . '"',
531  'size' => (int)$row['size'],
532  'calendardata' => $row['calendardata'],
533  'component' => strtolower($row['componenttype']),
534  ];
535 
536  }
537  }
538  return $result;
539 
540  }
$result
$stmt
$query
$row

◆ getSchedulingObject()

Sabre\CalDAV\Backend\PDO::getSchedulingObject (   $principalUri,
  $objectUri 
)

Returns a single scheduling object.

The returned array should contain the following elements:

  • uri - A unique basename for the object. This will be used to construct a full uri.
  • calendardata - The iCalendar object
  • lastmodified - The last modification date. Can be an int for a unix timestamp, or a PHP DateTime object.
  • etag - A unique token that must change if the object changed.
  • size - The size of the object, in bytes.
Parameters
string$principalUri
string$objectUri
Returns
array

Implements Sabre\CalDAV\Backend\SchedulingSupport.

Definition at line 1258 of file PDO.php.

References $row, and $stmt.

1258  {
1259 
1260  $stmt = $this->pdo->prepare('SELECT uri, calendardata, lastmodified, etag, size FROM ' . $this->schedulingObjectTableName . ' WHERE principaluri = ? AND uri = ?');
1261  $stmt->execute([$principalUri, $objectUri]);
1262  $row = $stmt->fetch(\PDO::FETCH_ASSOC);
1263 
1264  if (!$row) return null;
1265 
1266  return [
1267  'uri' => $row['uri'],
1268  'calendardata' => $row['calendardata'],
1269  'lastmodified' => $row['lastmodified'],
1270  'etag' => '"' . $row['etag'] . '"',
1271  'size' => (int)$row['size'],
1272  ];
1273 
1274  }
$stmt
$row

◆ getSchedulingObjects()

Sabre\CalDAV\Backend\PDO::getSchedulingObjects (   $principalUri)

Returns all scheduling objects for the inbox collection.

These objects should be returned as an array. Every item in the array should follow the same structure as returned from getSchedulingObject.

The main difference is that 'calendardata' is optional.

Parameters
string$principalUri
Returns
array

Implements Sabre\CalDAV\Backend\SchedulingSupport.

Definition at line 1287 of file PDO.php.

References $result, $row, and $stmt.

1287  {
1288 
1289  $stmt = $this->pdo->prepare('SELECT id, calendardata, uri, lastmodified, etag, size FROM ' . $this->schedulingObjectTableName . ' WHERE principaluri = ?');
1290  $stmt->execute([$principalUri]);
1291 
1292  $result = [];
1293  foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) {
1294  $result[] = [
1295  'calendardata' => $row['calendardata'],
1296  'uri' => $row['uri'],
1297  'lastmodified' => $row['lastmodified'],
1298  'etag' => '"' . $row['etag'] . '"',
1299  'size' => (int)$row['size'],
1300  ];
1301  }
1302 
1303  return $result;
1304 
1305  }
$result
$stmt
$row

◆ getSubscriptionsForUser()

Sabre\CalDAV\Backend\PDO::getSubscriptionsForUser (   $principalUri)

Returns a list of subscriptions for a principal.

Every subscription is an array with the following keys:

  • id, a unique id that will be used by other functions to modify the subscription. This can be the same as the uri or a database key.
  • uri. This is just the 'base uri' or 'filename' of the subscription.
  • principaluri. The owner of the subscription. Almost always the same as principalUri passed to this method.
  • source. Url to the actual feed

Furthermore, all the subscription info must be returned too:

  1. {DAV:}displayname
  2. {http://apple.com/ns/ical/}refreshrate
  3. {http://calendarserver.org/ns/}subscribed-strip-todos (omit if todos should not be stripped).
  4. {http://calendarserver.org/ns/}subscribed-strip-alarms (omit if alarms should not be stripped).
  5. {http://calendarserver.org/ns/}subscribed-strip-attachments (omit if attachments should not be stripped).
  6. {http://apple.com/ns/ical/}calendar-color
  7. {http://apple.com/ns/ical/}calendar-order
  8. {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set (should just be an instance of Sabre, with a bunch of default components).
Parameters
string$principalUri
Returns
array

Implements Sabre\CalDAV\Backend\SubscriptionSupport.

Definition at line 1087 of file PDO.php.

References $row, $stmt, and Sabre\CalDAV\Plugin\NS_CALDAV.

1087  {
1088 
1089  $fields = array_values($this->subscriptionPropertyMap);
1090  $fields[] = 'id';
1091  $fields[] = 'uri';
1092  $fields[] = 'source';
1093  $fields[] = 'principaluri';
1094  $fields[] = 'lastmodified';
1095 
1096  // Making fields a comma-delimited list
1097  $fields = implode(', ', $fields);
1098  $stmt = $this->pdo->prepare("SELECT " . $fields . " FROM " . $this->calendarSubscriptionsTableName . " WHERE principaluri = ? ORDER BY calendarorder ASC");
1099  $stmt->execute([$principalUri]);
1100 
1101  $subscriptions = [];
1102  while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
1103 
1104  $subscription = [
1105  'id' => $row['id'],
1106  'uri' => $row['uri'],
1107  'principaluri' => $row['principaluri'],
1108  'source' => $row['source'],
1109  'lastmodified' => $row['lastmodified'],
1110 
1111  '{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VTODO', 'VEVENT']),
1112  ];
1113 
1114  foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) {
1115  if (!is_null($row[$dbName])) {
1116  $subscription[$xmlName] = $row[$dbName];
1117  }
1118  }
1119 
1120  $subscriptions[] = $subscription;
1121 
1122  }
1123 
1124  return $subscriptions;
1125 
1126  }
$stmt
$row
const NS_CALDAV
This is the official CalDAV namespace.
Definition: Plugin.php:33

◆ setPublishStatus()

Sabre\CalDAV\Backend\PDO::setPublishStatus (   $calendarId,
  $value 
)

Publishes a calendar.

Parameters
mixed$calendarId
bool$value
Returns
void

Implements Sabre\CalDAV\Backend\SharingSupport.

Definition at line 1505 of file PDO.php.

1505  {
1506 
1507  throw new DAV\Exception\NotImplemented('Not implemented');
1508 
1509  }

◆ updateCalendar()

Sabre\CalDAV\Backend\PDO::updateCalendar (   $calendarId,
\Sabre\DAV\PropPatch  $propPatch 
)

Updates properties for a calendar.

The list of mutations is stored in a Sabre object. To do the actual updates, you must tell this object which properties you're going to process with the handle() method.

Calling the handle method is like telling the PropPatch object "I promise I can handle updating this property".

Read the PropPatch documentation for more info and examples.

Parameters
mixed$calendarId
\Sabre\DAV\PropPatch$propPatch
Returns
void

Implements Sabre\CalDAV\Backend\BackendInterface.

Definition at line 305 of file PDO.php.

References $stmt, Sabre\CalDAV\Backend\PDO\addChange(), and Sabre\CalDAV\Plugin\NS_CALDAV.

305  {
306 
307  if (!is_array($calendarId)) {
308  throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
309  }
310  list($calendarId, $instanceId) = $calendarId;
311 
312  $supportedProperties = array_keys($this->propertyMap);
313  $supportedProperties[] = '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp';
314 
315  $propPatch->handle($supportedProperties, function($mutations) use ($calendarId, $instanceId) {
316  $newValues = [];
317  foreach ($mutations as $propertyName => $propertyValue) {
318 
319  switch ($propertyName) {
320  case '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp' :
321  $fieldName = 'transparent';
322  $newValues[$fieldName] = $propertyValue->getValue() === 'transparent';
323  break;
324  default :
325  $fieldName = $this->propertyMap[$propertyName];
326  $newValues[$fieldName] = $propertyValue;
327  break;
328  }
329 
330  }
331  $valuesSql = [];
332  foreach ($newValues as $fieldName => $value) {
333  $valuesSql[] = $fieldName . ' = ?';
334  }
335 
336  $stmt = $this->pdo->prepare("UPDATE " . $this->calendarInstancesTableName . " SET " . implode(', ', $valuesSql) . " WHERE id = ?");
337  $newValues['id'] = $instanceId;
338  $stmt->execute(array_values($newValues));
339 
340  $this->addChange($calendarId, "", 2);
341 
342  return true;
343 
344  });
345 
346  }
$stmt
addChange($calendarId, $objectUri, $operation)
Adds a change record to the calendarchanges table.
Definition: PDO.php:1040
const NS_CALDAV
This is the official CalDAV namespace.
Definition: Plugin.php:33
+ Here is the call graph for this function:

◆ updateCalendarObject()

Sabre\CalDAV\Backend\PDO::updateCalendarObject (   $calendarId,
  $objectUri,
  $calendarData 
)

Updates an existing calendarobject, based on it's uri.

The object uri is only the basename, or filename and not a full path.

It is possible return an etag from this function, which will be used in the response to this PUT request. Note that the ETag must be surrounded by double-quotes.

However, you should only really return this ETag if you don't mangle the calendar-data. If the result of a subsequent GET to this object is not the exact same as this request body, you should omit the ETag.

Parameters
mixed$calendarId
string$objectUri
string$calendarData
Returns
string|null

Implements Sabre\CalDAV\Backend\BackendInterface.

Definition at line 607 of file PDO.php.

References $stmt, Sabre\CalDAV\Backend\PDO\addChange(), and Sabre\CalDAV\Backend\PDO\getDenormalizedData().

607  {
608 
609  if (!is_array($calendarId)) {
610  throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
611  }
612  list($calendarId, $instanceId) = $calendarId;
613 
614  $extraData = $this->getDenormalizedData($calendarData);
615 
616  $stmt = $this->pdo->prepare('UPDATE ' . $this->calendarObjectTableName . ' SET calendardata = ?, lastmodified = ?, etag = ?, size = ?, componenttype = ?, firstoccurence = ?, lastoccurence = ?, uid = ? WHERE calendarid = ? AND uri = ?');
617  $stmt->execute([$calendarData, time(), $extraData['etag'], $extraData['size'], $extraData['componentType'], $extraData['firstOccurence'], $extraData['lastOccurence'], $extraData['uid'], $calendarId, $objectUri]);
618 
619  $this->addChange($calendarId, $objectUri, 2);
620 
621  return '"' . $extraData['etag'] . '"';
622 
623  }
$stmt
addChange($calendarId, $objectUri, $operation)
Adds a change record to the calendarchanges table.
Definition: PDO.php:1040
getDenormalizedData($calendarData)
Parses some information from calendar objects, used for optimized calendar-queries.
Definition: PDO.php:640
+ Here is the call graph for this function:

◆ updateInvites()

Sabre\CalDAV\Backend\PDO::updateInvites (   $calendarId,
array  $sharees 
)

Updates the list of shares.

Parameters
mixed$calendarId

Implements Sabre\CalDAV\Backend\SharingSupport.

Definition at line 1343 of file PDO.php.

References Sabre\CalDAV\Backend\PDO\getInvites(), Sabre\DAV\UUIDUtil\getUUID(), Sabre\DAV\Sharing\Plugin\INVITE_ACCEPTED, and Sabre\DAV\Sharing\Plugin\INVITE_INVALID.

1343  {
1344 
1345  if (!is_array($calendarId)) {
1346  throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId');
1347  }
1348  $currentInvites = $this->getInvites($calendarId);
1349  list($calendarId, $instanceId) = $calendarId;
1350 
1351  $removeStmt = $this->pdo->prepare("DELETE FROM " . $this->calendarInstancesTableName . " WHERE calendarid = ? AND share_href = ? AND access IN (2,3)");
1352  $updateStmt = $this->pdo->prepare("UPDATE " . $this->calendarInstancesTableName . " SET access = ?, share_displayname = ?, share_invitestatus = ? WHERE calendarid = ? AND share_href = ?");
1353 
1354  $insertStmt = $this->pdo->prepare('
1355 INSERT INTO ' . $this->calendarInstancesTableName . '
1356  (
1357  calendarid,
1358  principaluri,
1359  access,
1360  displayname,
1361  uri,
1362  description,
1363  calendarorder,
1364  calendarcolor,
1365  timezone,
1366  transparent,
1367  share_href,
1368  share_displayname,
1369  share_invitestatus
1370  )
1371  SELECT
1372  ?,
1373  ?,
1374  ?,
1375  displayname,
1376  ?,
1377  description,
1378  calendarorder,
1379  calendarcolor,
1380  timezone,
1381  1,
1382  ?,
1383  ?,
1384  ?
1385  FROM ' . $this->calendarInstancesTableName . ' WHERE id = ?');
1386 
1387  foreach ($sharees as $sharee) {
1388 
1389  if ($sharee->access === \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS) {
1390  // if access was set no NOACCESS, it means access for an
1391  // existing sharee was removed.
1392  $removeStmt->execute([$calendarId, $sharee->href]);
1393  continue;
1394  }
1395 
1396  if (is_null($sharee->principal)) {
1397  // If the server could not determine the principal automatically,
1398  // we will mark the invite status as invalid.
1399  $sharee->inviteStatus = \Sabre\DAV\Sharing\Plugin::INVITE_INVALID;
1400  } else {
1401  // Because sabre/dav does not yet have an invitation system,
1402  // every invite is automatically accepted for now.
1403  $sharee->inviteStatus = \Sabre\DAV\Sharing\Plugin::INVITE_ACCEPTED;
1404  }
1405 
1406  foreach ($currentInvites as $oldSharee) {
1407 
1408  if ($oldSharee->href === $sharee->href) {
1409  // This is an update
1410  $sharee->properties = array_merge(
1411  $oldSharee->properties,
1412  $sharee->properties
1413  );
1414  $updateStmt->execute([
1415  $sharee->access,
1416  isset($sharee->properties['{DAV:}displayname']) ? $sharee->properties['{DAV:}displayname'] : null,
1417  $sharee->inviteStatus ?: $oldSharee->inviteStatus,
1418  $calendarId,
1419  $sharee->href
1420  ]);
1421  continue 2;
1422  }
1423 
1424  }
1425  // If we got here, it means it was a new sharee
1426  $insertStmt->execute([
1427  $calendarId,
1428  $sharee->principal,
1429  $sharee->access,
1430  \Sabre\DAV\UUIDUtil::getUUID(),
1431  $sharee->href,
1432  isset($sharee->properties['{DAV:}displayname']) ? $sharee->properties['{DAV:}displayname'] : null,
1433  $sharee->inviteStatus ?: \Sabre\DAV\Sharing\Plugin::INVITE_NORESPONSE,
1434  $instanceId
1435  ]);
1436 
1437  }
1438 
1439  }
getInvites($calendarId)
Returns the list of people whom a calendar is shared with.
Definition: PDO.php:1456
static getUUID()
Returns a pseudo-random v4 UUID.
Definition: UUIDUtil.php:26
+ Here is the call graph for this function:

◆ updateSubscription()

Sabre\CalDAV\Backend\PDO::updateSubscription (   $subscriptionId,
DAV\PropPatch  $propPatch 
)

Updates a subscription.

The list of mutations is stored in a Sabre object. To do the actual updates, you must tell this object which properties you're going to process with the handle() method.

Calling the handle method is like telling the PropPatch object "I promise I can handle updating this property".

Read the PropPatch documentation for more info and examples.

Parameters
mixed$subscriptionId
\Sabre\DAV\PropPatch$propPatch
Returns
void

Implements Sabre\CalDAV\Backend\SubscriptionSupport.

Definition at line 1192 of file PDO.php.

References $stmt.

1192  {
1193 
1194  $supportedProperties = array_keys($this->subscriptionPropertyMap);
1195  $supportedProperties[] = '{http://calendarserver.org/ns/}source';
1196 
1197  $propPatch->handle($supportedProperties, function($mutations) use ($subscriptionId) {
1198 
1199  $newValues = [];
1200 
1201  foreach ($mutations as $propertyName => $propertyValue) {
1202 
1203  if ($propertyName === '{http://calendarserver.org/ns/}source') {
1204  $newValues['source'] = $propertyValue->getHref();
1205  } else {
1206  $fieldName = $this->subscriptionPropertyMap[$propertyName];
1207  $newValues[$fieldName] = $propertyValue;
1208  }
1209 
1210  }
1211 
1212  // Now we're generating the sql query.
1213  $valuesSql = [];
1214  foreach ($newValues as $fieldName => $value) {
1215  $valuesSql[] = $fieldName . ' = ?';
1216  }
1217 
1218  $stmt = $this->pdo->prepare("UPDATE " . $this->calendarSubscriptionsTableName . " SET " . implode(', ', $valuesSql) . ", lastmodified = ? WHERE id = ?");
1219  $newValues['lastmodified'] = time();
1220  $newValues['id'] = $subscriptionId;
1221  $stmt->execute(array_values($newValues));
1222 
1223  return true;
1224 
1225  });
1226 
1227  }
$stmt

Field Documentation

◆ $calendarChangesTableName

Sabre\CalDAV\Backend\PDO::$calendarChangesTableName = 'calendarchanges'

Definition at line 74 of file PDO.php.

◆ $calendarInstancesTableName

Sabre\CalDAV\Backend\PDO::$calendarInstancesTableName = 'calendarinstances'

Definition at line 60 of file PDO.php.

◆ $calendarObjectTableName

Sabre\CalDAV\Backend\PDO::$calendarObjectTableName = 'calendarobjects'

Definition at line 67 of file PDO.php.

◆ $calendarSubscriptionsTableName

Sabre\CalDAV\Backend\PDO::$calendarSubscriptionsTableName = 'calendarsubscriptions'

Definition at line 88 of file PDO.php.

◆ $calendarTableName

Sabre\CalDAV\Backend\PDO::$calendarTableName = 'calendars'

Definition at line 50 of file PDO.php.

◆ $pdo

Sabre\CalDAV\Backend\PDO::$pdo
protected

Definition at line 43 of file PDO.php.

Referenced by Sabre\CalDAV\Backend\PDO\__construct().

◆ $propertyMap

Sabre\CalDAV\Backend\PDO::$propertyMap
Initial value:
= [
'{DAV:}displayname' => 'displayname'

Definition at line 98 of file PDO.php.

◆ $schedulingObjectTableName

Sabre\CalDAV\Backend\PDO::$schedulingObjectTableName = 'schedulingobjects'

Definition at line 81 of file PDO.php.

◆ $subscriptionPropertyMap

Sabre\CalDAV\Backend\PDO::$subscriptionPropertyMap
Initial value:
= [
'{DAV:}displayname' => 'displayname'

Definition at line 111 of file PDO.php.

◆ MAX_DATE

const Sabre\CalDAV\Backend\PDO::MAX_DATE = '2038-01-01'

We need to specify a max date, because we need to stop somewhere

On 32 bit system the maximum for a signed integer is 2147483647, so MAX_DATE cannot be higher than date('Y-m-d', 2147483647) which results in 2038-01-19 to avoid problems when the date is converted to a unix timestamp.

Definition at line 36 of file PDO.php.

Referenced by Sabre\CalDAV\Backend\AbstractPDOTest\testCreateCalendarObjectInfiniteRecurrence().


The documentation for this class was generated from the following file: