diff options
Diffstat (limited to 'vendor/sabre/dav/lib/CalDAV/Backend/PDO.php')
-rw-r--r-- | vendor/sabre/dav/lib/CalDAV/Backend/PDO.php | 564 |
1 files changed, 258 insertions, 306 deletions
diff --git a/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php b/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php index 458440588..003dc1392 100644 --- a/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php +++ b/vendor/sabre/dav/lib/CalDAV/Backend/PDO.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Sabre\CalDAV\Backend; use Sabre\CalDAV; @@ -9,7 +11,7 @@ use Sabre\DAV\Xml\Element\Sharee; use Sabre\VObject; /** - * PDO CalDAV backend + * PDO CalDAV backend. * * This backend is used to store calendar-data in a PDO database, such as * sqlite or MySQL @@ -18,15 +20,10 @@ use Sabre\VObject; * @author Evert Pot (http://evertpot.com/) * @license http://sabre.io/license/ Modified BSD License */ -class PDO extends AbstractBackend - implements - SyncSupport, - SubscriptionSupport, - SchedulingSupport, - SharingSupport { - +class PDO extends AbstractBackend implements SyncSupport, SubscriptionSupport, SchedulingSupport, SharingSupport +{ /** - * We need to specify a max date, because we need to stop *somewhere* + * 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 @@ -36,14 +33,14 @@ class PDO extends AbstractBackend const MAX_DATE = '2038-01-01'; /** - * pdo + * pdo. * * @var \PDO */ protected $pdo; /** - * The table name that will be used for calendars + * The table name that will be used for calendars. * * @var string */ @@ -60,7 +57,7 @@ class PDO extends AbstractBackend public $calendarInstancesTableName = 'calendarinstances'; /** - * The table name that will be used for calendar objects + * The table name that will be used for calendar objects. * * @var string */ @@ -96,11 +93,11 @@ class PDO extends AbstractBackend * @var array */ public $propertyMap = [ - '{DAV:}displayname' => 'displayname', + '{DAV:}displayname' => 'displayname', '{urn:ietf:params:xml:ns:caldav}calendar-description' => 'description', - '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => 'timezone', - '{http://apple.com/ns/ical/}calendar-order' => 'calendarorder', - '{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor', + '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => 'timezone', + '{http://apple.com/ns/ical/}calendar-order' => 'calendarorder', + '{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor', ]; /** @@ -109,24 +106,23 @@ class PDO extends AbstractBackend * @var array */ public $subscriptionPropertyMap = [ - '{DAV:}displayname' => 'displayname', - '{http://apple.com/ns/ical/}refreshrate' => 'refreshrate', - '{http://apple.com/ns/ical/}calendar-order' => 'calendarorder', - '{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor', - '{http://calendarserver.org/ns/}subscribed-strip-todos' => 'striptodos', - '{http://calendarserver.org/ns/}subscribed-strip-alarms' => 'stripalarms', + '{DAV:}displayname' => 'displayname', + '{http://apple.com/ns/ical/}refreshrate' => 'refreshrate', + '{http://apple.com/ns/ical/}calendar-order' => 'calendarorder', + '{http://apple.com/ns/ical/}calendar-color' => 'calendarcolor', + '{http://calendarserver.org/ns/}subscribed-strip-todos' => 'striptodos', + '{http://calendarserver.org/ns/}subscribed-strip-alarms' => 'stripalarms', '{http://calendarserver.org/ns/}subscribed-strip-attachments' => 'stripattachments', ]; /** - * Creates the backend + * Creates the backend. * * @param \PDO $pdo */ - function __construct(\PDO $pdo) { - + public function __construct(\PDO $pdo) + { $this->pdo = $pdo; - } /** @@ -151,10 +147,11 @@ class PDO extends AbstractBackend * ACL will automatically be put in read-only mode. * * @param string $principalUri + * * @return array */ - function getCalendarsForUser($principalUri) { - + public function getCalendarsForUser($principalUri) + { $fields = array_values($this->propertyMap); $fields[] = 'calendarid'; $fields[] = 'uri'; @@ -177,24 +174,23 @@ SQL $calendars = []; while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $components = []; if ($row['components']) { $components = explode(',', $row['components']); } $calendar = [ - 'id' => [(int)$row['calendarid'], (int)$row['id']], - 'uri' => $row['uri'], - 'principaluri' => $row['principaluri'], - '{' . CalDAV\Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken'] ? $row['synctoken'] : '0'), - '{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0', - '{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet($components), - '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp($row['transparent'] ? 'transparent' : 'opaque'), - 'share-resource-uri' => '/ns/share/' . $row['calendarid'], + 'id' => [(int) $row['calendarid'], (int) $row['id']], + 'uri' => $row['uri'], + 'principaluri' => $row['principaluri'], + '{'.CalDAV\Plugin::NS_CALENDARSERVER.'}getctag' => 'http://sabre.io/ns/sync/'.($row['synctoken'] ? $row['synctoken'] : '0'), + '{http://sabredav.org/ns}sync-token' => $row['synctoken'] ? $row['synctoken'] : '0', + '{'.CalDAV\Plugin::NS_CALDAV.'}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet($components), + '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-calendar-transp' => new CalDAV\Xml\Property\ScheduleCalendarTransp($row['transparent'] ? 'transparent' : 'opaque'), + 'share-resource-uri' => '/ns/share/'.$row['calendarid'], ]; - $calendar['share-access'] = (int)$row['access']; + $calendar['share-access'] = (int) $row['access']; // 1 = owner, 2 = readonly, 3 = readwrite if ($row['access'] > 1) { // We need to find more information about the original owner. @@ -203,7 +199,7 @@ SQL // read-only is for backwards compatbility. Might go away in // the future. - $calendar['read-only'] = (int)$row['access'] === \Sabre\DAV\Sharing\Plugin::ACCESS_READ; + $calendar['read-only'] = \Sabre\DAV\Sharing\Plugin::ACCESS_READ === (int) $row['access']; } foreach ($this->propertyMap as $xmlName => $dbName) { @@ -211,11 +207,9 @@ SQL } $calendars[] = $calendar; - } return $calendars; - } /** @@ -226,11 +220,12 @@ SQL * * @param string $principalUri * @param string $calendarUri - * @param array $properties + * @param array $properties + * * @return string */ - function createCalendar($principalUri, $calendarUri, array $properties) { - + public function createCalendar($principalUri, $calendarUri, array $properties) + { $fieldNames = [ 'principaluri', 'uri', @@ -239,51 +234,48 @@ SQL ]; $values = [ ':principaluri' => $principalUri, - ':uri' => $calendarUri, - ':transparent' => 0, + ':uri' => $calendarUri, + ':transparent' => 0, ]; - $sccs = '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'; if (!isset($properties[$sccs])) { // Default value $components = 'VEVENT,VTODO'; } else { if (!($properties[$sccs] instanceof CalDAV\Xml\Property\SupportedCalendarComponentSet)) { - throw new DAV\Exception('The ' . $sccs . ' property must be of type: \Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet'); + throw new DAV\Exception('The '.$sccs.' property must be of type: \Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet'); } $components = implode(',', $properties[$sccs]->getValue()); } - $transp = '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp'; + $transp = '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-calendar-transp'; if (isset($properties[$transp])) { - $values[':transparent'] = $properties[$transp]->getValue() === 'transparent' ? 1 : 0; + $values[':transparent'] = 'transparent' === $properties[$transp]->getValue() ? 1 : 0; } - $stmt = $this->pdo->prepare("INSERT INTO " . $this->calendarTableName . " (synctoken, components) VALUES (1, ?)"); + $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarTableName.' (synctoken, components) VALUES (1, ?)'); $stmt->execute([$components]); $calendarId = $this->pdo->lastInsertId( - $this->calendarTableName . '_id_seq' + $this->calendarTableName.'_id_seq' ); $values[':calendarid'] = $calendarId; foreach ($this->propertyMap as $xmlName => $dbName) { if (isset($properties[$xmlName])) { - - $values[':' . $dbName] = $properties[$xmlName]; + $values[':'.$dbName] = $properties[$xmlName]; $fieldNames[] = $dbName; } } - $stmt = $this->pdo->prepare("INSERT INTO " . $this->calendarInstancesTableName . " (" . implode(', ', $fieldNames) . ") VALUES (" . implode(', ', array_keys($values)) . ")"); + $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarInstancesTableName.' ('.implode(', ', $fieldNames).') VALUES ('.implode(', ', array_keys($values)).')'); $stmt->execute($values); return [ $calendarId, - $this->pdo->lastInsertId($this->calendarInstancesTableName . '_id_seq') + $this->pdo->lastInsertId($this->calendarInstancesTableName.'_id_seq'), ]; - } /** @@ -298,100 +290,88 @@ SQL * * Read the PropPatch documentation for more info and examples. * - * @param mixed $calendarId + * @param mixed $calendarId * @param \Sabre\DAV\PropPatch $propPatch - * @return void */ - function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) { - + public function updateCalendar($calendarId, \Sabre\DAV\PropPatch $propPatch) + { if (!is_array($calendarId)) { throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); } list($calendarId, $instanceId) = $calendarId; $supportedProperties = array_keys($this->propertyMap); - $supportedProperties[] = '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp'; + $supportedProperties[] = '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-calendar-transp'; - $propPatch->handle($supportedProperties, function($mutations) use ($calendarId, $instanceId) { + $propPatch->handle($supportedProperties, function ($mutations) use ($calendarId, $instanceId) { $newValues = []; foreach ($mutations as $propertyName => $propertyValue) { - switch ($propertyName) { - case '{' . CalDAV\Plugin::NS_CALDAV . '}schedule-calendar-transp' : + case '{'.CalDAV\Plugin::NS_CALDAV.'}schedule-calendar-transp': $fieldName = 'transparent'; - $newValues[$fieldName] = $propertyValue->getValue() === 'transparent'; + $newValues[$fieldName] = 'transparent' === $propertyValue->getValue(); break; - default : + default: $fieldName = $this->propertyMap[$propertyName]; $newValues[$fieldName] = $propertyValue; break; } - } $valuesSql = []; foreach ($newValues as $fieldName => $value) { - $valuesSql[] = $fieldName . ' = ?'; + $valuesSql[] = $fieldName.' = ?'; } - $stmt = $this->pdo->prepare("UPDATE " . $this->calendarInstancesTableName . " SET " . implode(', ', $valuesSql) . " WHERE id = ?"); + $stmt = $this->pdo->prepare('UPDATE '.$this->calendarInstancesTableName.' SET '.implode(', ', $valuesSql).' WHERE id = ?'); $newValues['id'] = $instanceId; $stmt->execute(array_values($newValues)); - $this->addChange($calendarId, "", 2); + $this->addChange($calendarId, '', 2); return true; - }); - } /** - * Delete a calendar and all it's objects + * Delete a calendar and all it's objects. * * @param mixed $calendarId - * @return void */ - function deleteCalendar($calendarId) { - + public function deleteCalendar($calendarId) + { if (!is_array($calendarId)) { throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); } list($calendarId, $instanceId) = $calendarId; - $stmt = $this->pdo->prepare('SELECT access FROM ' . $this->calendarInstancesTableName . ' where id = ?'); + $stmt = $this->pdo->prepare('SELECT access FROM '.$this->calendarInstancesTableName.' where id = ?'); $stmt->execute([$instanceId]); - $access = (int)$stmt->fetchColumn(); - - if ($access === \Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER) { + $access = (int) $stmt->fetchColumn(); + if (\Sabre\DAV\Sharing\Plugin::ACCESS_SHAREDOWNER === $access) { /** * If the user is the owner of the calendar, we delete all data and all * instances. **/ - $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ?'); + $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?'); $stmt->execute([$calendarId]); - $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarChangesTableName . ' WHERE calendarid = ?'); + $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarChangesTableName.' WHERE calendarid = ?'); $stmt->execute([$calendarId]); - $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarInstancesTableName . ' WHERE calendarid = ?'); + $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarInstancesTableName.' WHERE calendarid = ?'); $stmt->execute([$calendarId]); - $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarTableName . ' WHERE id = ?'); + $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarTableName.' WHERE id = ?'); $stmt->execute([$calendarId]); - } else { - /** * If it was an instance of a shared calendar, we only delete that * instance. */ - $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarInstancesTableName . ' WHERE id = ?'); + $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarInstancesTableName.' WHERE id = ?'); $stmt->execute([$instanceId]); - } - - } /** @@ -423,32 +403,32 @@ SQL * amount of times this is needed is reduced by a great degree. * * @param mixed $calendarId + * * @return array */ - function getCalendarObjects($calendarId) { - + public function getCalendarObjects($calendarId) + { if (!is_array($calendarId)) { throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); } list($calendarId, $instanceId) = $calendarId; - $stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size, componenttype FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ?'); + $stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size, componenttype FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?'); $stmt->execute([$calendarId]); $result = []; foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) { $result[] = [ - 'id' => $row['id'], - 'uri' => $row['uri'], - 'lastmodified' => (int)$row['lastmodified'], - 'etag' => '"' . $row['etag'] . '"', - 'size' => (int)$row['size'], - 'component' => strtolower($row['componenttype']), + 'id' => $row['id'], + 'uri' => $row['uri'], + 'lastmodified' => (int) $row['lastmodified'], + 'etag' => '"'.$row['etag'].'"', + 'size' => (int) $row['size'], + 'component' => strtolower($row['componenttype']), ]; } return $result; - } /** @@ -463,33 +443,35 @@ SQL * * This method must return null if the object did not exist. * - * @param mixed $calendarId + * @param mixed $calendarId * @param string $objectUri + * * @return array|null */ - function getCalendarObject($calendarId, $objectUri) { - + public function getCalendarObject($calendarId, $objectUri) + { if (!is_array($calendarId)) { throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); } list($calendarId, $instanceId) = $calendarId; - $stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size, calendardata, componenttype FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ? AND uri = ?'); + $stmt = $this->pdo->prepare('SELECT id, uri, lastmodified, etag, calendarid, size, calendardata, componenttype FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri = ?'); $stmt->execute([$calendarId, $objectUri]); $row = $stmt->fetch(\PDO::FETCH_ASSOC); - if (!$row) return null; + if (!$row) { + return null; + } return [ - 'id' => $row['id'], - 'uri' => $row['uri'], - 'lastmodified' => (int)$row['lastmodified'], - 'etag' => '"' . $row['etag'] . '"', - 'size' => (int)$row['size'], + 'id' => $row['id'], + 'uri' => $row['uri'], + 'lastmodified' => (int) $row['lastmodified'], + 'etag' => '"'.$row['etag'].'"', + 'size' => (int) $row['size'], 'calendardata' => $row['calendardata'], - 'component' => strtolower($row['componenttype']), + 'component' => strtolower($row['componenttype']), ]; - } /** @@ -502,10 +484,11 @@ SQL * * @param mixed $calendarId * @param array $uris + * * @return array */ - function getMultipleCalendarObjects($calendarId, array $uris) { - + public function getMultipleCalendarObjects($calendarId, array $uris) + { if (!is_array($calendarId)) { throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); } @@ -513,7 +496,7 @@ SQL $result = []; foreach (array_chunk($uris, 900) as $chunk) { - $query = 'SELECT id, uri, lastmodified, etag, calendarid, size, calendardata, componenttype FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ? AND uri IN ('; + $query = 'SELECT id, uri, lastmodified, etag, calendarid, size, calendardata, componenttype FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri IN ('; // Inserting a whole bunch of question marks $query .= implode(',', array_fill(0, count($chunk), '?')); $query .= ')'; @@ -522,24 +505,21 @@ SQL $stmt->execute(array_merge([$calendarId], $chunk)); while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $result[] = [ - 'id' => $row['id'], - 'uri' => $row['uri'], - 'lastmodified' => (int)$row['lastmodified'], - 'etag' => '"' . $row['etag'] . '"', - 'size' => (int)$row['size'], + 'id' => $row['id'], + 'uri' => $row['uri'], + 'lastmodified' => (int) $row['lastmodified'], + 'etag' => '"'.$row['etag'].'"', + 'size' => (int) $row['size'], 'calendardata' => $row['calendardata'], - 'component' => strtolower($row['componenttype']), + 'component' => strtolower($row['componenttype']), ]; - } } - return $result; + return $result; } - /** * Creates a new calendar object. * @@ -553,13 +533,14 @@ SQL * 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. * - * @param mixed $calendarId + * @param mixed $calendarId * @param string $objectUri * @param string $calendarData + * * @return string|null */ - function createCalendarObject($calendarId, $objectUri, $calendarData) { - + public function createCalendarObject($calendarId, $objectUri, $calendarData) + { if (!is_array($calendarId)) { throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); } @@ -567,7 +548,7 @@ SQL $extraData = $this->getDenormalizedData($calendarData); - $stmt = $this->pdo->prepare('INSERT INTO ' . $this->calendarObjectTableName . ' (calendarid, uri, calendardata, lastmodified, etag, size, componenttype, firstoccurence, lastoccurence, uid) VALUES (?,?,?,?,?,?,?,?,?,?)'); + $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarObjectTableName.' (calendarid, uri, calendardata, lastmodified, etag, size, componenttype, firstoccurence, lastoccurence, uid) VALUES (?,?,?,?,?,?,?,?,?,?)'); $stmt->execute([ $calendarId, $objectUri, @@ -582,8 +563,7 @@ SQL ]); $this->addChange($calendarId, $objectUri, 1); - return '"' . $extraData['etag'] . '"'; - + return '"'.$extraData['etag'].'"'; } /** @@ -599,13 +579,14 @@ SQL * 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. * - * @param mixed $calendarId + * @param mixed $calendarId * @param string $objectUri * @param string $calendarData + * * @return string|null */ - function updateCalendarObject($calendarId, $objectUri, $calendarData) { - + public function updateCalendarObject($calendarId, $objectUri, $calendarData) + { if (!is_array($calendarId)) { throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); } @@ -613,13 +594,12 @@ SQL $extraData = $this->getDenormalizedData($calendarData); - $stmt = $this->pdo->prepare('UPDATE ' . $this->calendarObjectTableName . ' SET calendardata = ?, lastmodified = ?, etag = ?, size = ?, componenttype = ?, firstoccurence = ?, lastoccurence = ?, uid = ? WHERE calendarid = ? AND uri = ?'); + $stmt = $this->pdo->prepare('UPDATE '.$this->calendarObjectTableName.' SET calendardata = ?, lastmodified = ?, etag = ?, size = ?, componenttype = ?, firstoccurence = ?, lastoccurence = ?, uid = ? WHERE calendarid = ? AND uri = ?'); $stmt->execute([$calendarData, time(), $extraData['etag'], $extraData['size'], $extraData['componentType'], $extraData['firstOccurence'], $extraData['lastOccurence'], $extraData['uid'], $calendarId, $objectUri]); $this->addChange($calendarId, $objectUri, 2); - return '"' . $extraData['etag'] . '"'; - + return '"'.$extraData['etag'].'"'; } /** @@ -635,10 +615,11 @@ SQL * * uid - value of the UID property * * @param string $calendarData + * * @return array */ - protected function getDenormalizedData($calendarData) { - + protected function getDenormalizedData($calendarData) + { $vObject = VObject\Reader::read($calendarData); $componentType = null; $component = null; @@ -646,16 +627,16 @@ SQL $lastOccurence = null; $uid = null; foreach ($vObject->getComponents() as $component) { - if ($component->name !== 'VTIMEZONE') { + if ('VTIMEZONE' !== $component->name) { $componentType = $component->name; - $uid = (string)$component->UID; + $uid = (string) $component->UID; break; } } if (!$componentType) { throw new \Sabre\DAV\Exception\BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component'); } - if ($componentType === 'VEVENT') { + if ('VEVENT' === $componentType) { $firstOccurence = $component->DTSTART->getDateTime()->getTimeStamp(); // Finding the last occurence is a bit harder if (!isset($component->RRULE)) { @@ -673,7 +654,7 @@ SQL $lastOccurence = $firstOccurence; } } else { - $it = new VObject\Recur\EventIterator($vObject, (string)$component->UID); + $it = new VObject\Recur\EventIterator($vObject, (string) $component->UID); $maxDate = new \DateTime(self::MAX_DATE); if ($it->isInfinite()) { $lastOccurence = $maxDate->getTimeStamp(); @@ -682,30 +663,31 @@ SQL while ($it->valid() && $end < $maxDate) { $end = $it->getDtEnd(); $it->next(); - } $lastOccurence = $end->getTimeStamp(); } - } // Ensure Occurence values are positive - if ($firstOccurence < 0) $firstOccurence = 0; - if ($lastOccurence < 0) $lastOccurence = 0; + if ($firstOccurence < 0) { + $firstOccurence = 0; + } + if ($lastOccurence < 0) { + $lastOccurence = 0; + } } // Destroy circular references to PHP will GC the object. $vObject->destroy(); return [ - 'etag' => md5($calendarData), - 'size' => strlen($calendarData), - 'componentType' => $componentType, + 'etag' => md5($calendarData), + 'size' => strlen($calendarData), + 'componentType' => $componentType, 'firstOccurence' => $firstOccurence, - 'lastOccurence' => $lastOccurence, - 'uid' => $uid, + 'lastOccurence' => $lastOccurence, + 'uid' => $uid, ]; - } /** @@ -713,22 +695,20 @@ SQL * * The object uri is only the basename, or filename and not a full path. * - * @param mixed $calendarId + * @param mixed $calendarId * @param string $objectUri - * @return void */ - function deleteCalendarObject($calendarId, $objectUri) { - + public function deleteCalendarObject($calendarId, $objectUri) + { if (!is_array($calendarId)) { throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); } list($calendarId, $instanceId) = $calendarId; - $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarObjectTableName . ' WHERE calendarid = ? AND uri = ?'); + $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarObjectTableName.' WHERE calendarid = ? AND uri = ?'); $stmt->execute([$calendarId, $objectUri]); $this->addChange($calendarId, $objectUri, 3); - } /** @@ -781,10 +761,11 @@ SQL * * @param mixed $calendarId * @param array $filters + * * @return array */ - function calendarQuery($calendarId, array $filters) { - + public function calendarQuery($calendarId, array $filters) + { if (!is_array($calendarId)) { throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); } @@ -808,7 +789,7 @@ SQL $requirePostFilter = false; } // There was a time-range filter - if ($componentType == 'VEVENT' && isset($filters['comp-filters'][0]['time-range'])) { + if ('VEVENT' == $componentType && isset($filters['comp-filters'][0]['time-range'])) { $timeRange = $filters['comp-filters'][0]['time-range']; // If start time OR the end time is not specified, we can do a @@ -817,13 +798,12 @@ SQL $requirePostFilter = false; } } - } if ($requirePostFilter) { - $query = "SELECT uri, calendardata FROM " . $this->calendarObjectTableName . " WHERE calendarid = :calendarid"; + $query = 'SELECT uri, calendardata FROM '.$this->calendarObjectTableName.' WHERE calendarid = :calendarid'; } else { - $query = "SELECT uri FROM " . $this->calendarObjectTableName . " WHERE calendarid = :calendarid"; + $query = 'SELECT uri FROM '.$this->calendarObjectTableName.' WHERE calendarid = :calendarid'; } $values = [ @@ -831,16 +811,16 @@ SQL ]; if ($componentType) { - $query .= " AND componenttype = :componenttype"; + $query .= ' AND componenttype = :componenttype'; $values['componenttype'] = $componentType; } if ($timeRange && $timeRange['start']) { - $query .= " AND lastoccurence > :startdate"; + $query .= ' AND lastoccurence > :startdate'; $values['startdate'] = $timeRange['start']->getTimeStamp(); } if ($timeRange && $timeRange['end']) { - $query .= " AND firstoccurence < :enddate"; + $query .= ' AND firstoccurence < :enddate'; $values['enddate'] = $timeRange['end']->getTimeStamp(); } @@ -855,11 +835,9 @@ SQL } } $result[] = $row['uri']; - } return $result; - } /** @@ -879,10 +857,11 @@ SQL * * @param string $principalUri * @param string $uid + * * @return string|null */ - function getCalendarObjectByUID($principalUri, $uid) { - + public function getCalendarObjectByUID($principalUri, $uid) + { $query = <<<SQL SELECT calendar_instances.uri AS calendaruri, calendarobjects.uri as objecturi @@ -901,9 +880,8 @@ SQL; $stmt->execute([$principalUri, $uid]); if ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - return $row['calendaruri'] . '/' . $row['objecturi']; + return $row['calendaruri'].'/'.$row['objecturi']; } - } /** @@ -956,37 +934,41 @@ SQL; * * The limit is 'suggestive'. You are free to ignore it. * - * @param mixed $calendarId + * @param mixed $calendarId * @param string $syncToken - * @param int $syncLevel - * @param int $limit + * @param int $syncLevel + * @param int $limit + * * @return array */ - function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null) { - + public function getChangesForCalendar($calendarId, $syncToken, $syncLevel, $limit = null) + { if (!is_array($calendarId)) { throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); } list($calendarId, $instanceId) = $calendarId; // Current synctoken - $stmt = $this->pdo->prepare('SELECT synctoken FROM ' . $this->calendarTableName . ' WHERE id = ?'); + $stmt = $this->pdo->prepare('SELECT synctoken FROM '.$this->calendarTableName.' WHERE id = ?'); $stmt->execute([$calendarId]); $currentToken = $stmt->fetchColumn(0); - if (is_null($currentToken)) return null; + if (is_null($currentToken)) { + return null; + } $result = [ 'syncToken' => $currentToken, - 'added' => [], - 'modified' => [], - 'deleted' => [], + 'added' => [], + 'modified' => [], + 'deleted' => [], ]; if ($syncToken) { - - $query = "SELECT uri, operation FROM " . $this->calendarChangesTableName . " WHERE synctoken >= ? AND synctoken < ? AND calendarid = ? ORDER BY synctoken"; - if ($limit > 0) $query .= " LIMIT " . (int)$limit; + $query = 'SELECT uri, operation FROM '.$this->calendarChangesTableName.' WHERE synctoken >= ? AND synctoken < ? AND calendarid = ? ORDER BY synctoken'; + if ($limit > 0) { + $query .= ' LIMIT '.(int) $limit; + } // Fetching all changes $stmt = $this->pdo->prepare($query); @@ -997,60 +979,54 @@ SQL; // This loop ensures that any duplicates are overwritten, only the // last change on a node is relevant. while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $changes[$row['uri']] = $row['operation']; - } foreach ($changes as $uri => $operation) { - switch ($operation) { - case 1 : + case 1: $result['added'][] = $uri; break; - case 2 : + case 2: $result['modified'][] = $uri; break; - case 3 : + case 3: $result['deleted'][] = $uri; break; } - } } else { // No synctoken supplied, this is the initial sync. - $query = "SELECT uri FROM " . $this->calendarObjectTableName . " WHERE calendarid = ?"; + $query = 'SELECT uri FROM '.$this->calendarObjectTableName.' WHERE calendarid = ?'; $stmt = $this->pdo->prepare($query); $stmt->execute([$calendarId]); $result['added'] = $stmt->fetchAll(\PDO::FETCH_COLUMN); } - return $result; + return $result; } /** * Adds a change record to the calendarchanges table. * - * @param mixed $calendarId + * @param mixed $calendarId * @param string $objectUri - * @param int $operation 1 = add, 2 = modify, 3 = delete. - * @return void + * @param int $operation 1 = add, 2 = modify, 3 = delete */ - protected function addChange($calendarId, $objectUri, $operation) { - - $stmt = $this->pdo->prepare('INSERT INTO ' . $this->calendarChangesTableName . ' (uri, synctoken, calendarid, operation) SELECT ?, synctoken, ?, ? FROM ' . $this->calendarTableName . ' WHERE id = ?'); + protected function addChange($calendarId, $objectUri, $operation) + { + $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarChangesTableName.' (uri, synctoken, calendarid, operation) SELECT ?, synctoken, ?, ? FROM '.$this->calendarTableName.' WHERE id = ?'); $stmt->execute([ $objectUri, $calendarId, $operation, - $calendarId + $calendarId, ]); - $stmt = $this->pdo->prepare('UPDATE ' . $this->calendarTableName . ' SET synctoken = synctoken + 1 WHERE id = ?'); + $stmt = $this->pdo->prepare('UPDATE '.$this->calendarTableName.' SET synctoken = synctoken + 1 WHERE id = ?'); $stmt->execute([ - $calendarId + $calendarId, ]); - } /** @@ -1082,10 +1058,11 @@ SQL; * default components). * * @param string $principalUri + * * @return array */ - function getSubscriptionsForUser($principalUri) { - + public function getSubscriptionsForUser($principalUri) + { $fields = array_values($this->subscriptionPropertyMap); $fields[] = 'id'; $fields[] = 'uri'; @@ -1095,20 +1072,19 @@ SQL; // Making fields a comma-delimited list $fields = implode(', ', $fields); - $stmt = $this->pdo->prepare("SELECT " . $fields . " FROM " . $this->calendarSubscriptionsTableName . " WHERE principaluri = ? ORDER BY calendarorder ASC"); + $stmt = $this->pdo->prepare('SELECT '.$fields.' FROM '.$this->calendarSubscriptionsTableName.' WHERE principaluri = ? ORDER BY calendarorder ASC'); $stmt->execute([$principalUri]); $subscriptions = []; while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $subscription = [ - 'id' => $row['id'], - 'uri' => $row['uri'], + 'id' => $row['id'], + 'uri' => $row['uri'], 'principaluri' => $row['principaluri'], - 'source' => $row['source'], + 'source' => $row['source'], 'lastmodified' => $row['lastmodified'], - '{' . CalDAV\Plugin::NS_CALDAV . '}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VTODO', 'VEVENT']), + '{'.CalDAV\Plugin::NS_CALDAV.'}supported-calendar-component-set' => new CalDAV\Xml\Property\SupportedCalendarComponentSet(['VTODO', 'VEVENT']), ]; foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) { @@ -1118,11 +1094,9 @@ SQL; } $subscriptions[] = $subscription; - } return $subscriptions; - } /** @@ -1133,11 +1107,12 @@ SQL; * * @param string $principalUri * @param string $uri - * @param array $properties + * @param array $properties + * * @return mixed */ - function createSubscription($principalUri, $uri, array $properties) { - + public function createSubscription($principalUri, $uri, array $properties) + { $fieldNames = [ 'principaluri', 'uri', @@ -1151,30 +1126,28 @@ SQL; $values = [ ':principaluri' => $principalUri, - ':uri' => $uri, - ':source' => $properties['{http://calendarserver.org/ns/}source']->getHref(), + ':uri' => $uri, + ':source' => $properties['{http://calendarserver.org/ns/}source']->getHref(), ':lastmodified' => time(), ]; foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) { if (isset($properties[$xmlName])) { - - $values[':' . $dbName] = $properties[$xmlName]; + $values[':'.$dbName] = $properties[$xmlName]; $fieldNames[] = $dbName; } } - $stmt = $this->pdo->prepare("INSERT INTO " . $this->calendarSubscriptionsTableName . " (" . implode(', ', $fieldNames) . ") VALUES (" . implode(', ', array_keys($values)) . ")"); + $stmt = $this->pdo->prepare('INSERT INTO '.$this->calendarSubscriptionsTableName.' ('.implode(', ', $fieldNames).') VALUES ('.implode(', ', array_keys($values)).')'); $stmt->execute($values); return $this->pdo->lastInsertId( - $this->calendarSubscriptionsTableName . '_id_seq' + $this->calendarSubscriptionsTableName.'_id_seq' ); - } /** - * Updates a subscription + * Updates a subscription. * * The list of mutations is stored in a Sabre\DAV\PropPatch object. * To do the actual updates, you must tell this object which properties @@ -1185,58 +1158,50 @@ SQL; * * Read the PropPatch documentation for more info and examples. * - * @param mixed $subscriptionId + * @param mixed $subscriptionId * @param \Sabre\DAV\PropPatch $propPatch - * @return void */ - function updateSubscription($subscriptionId, DAV\PropPatch $propPatch) { - + public function updateSubscription($subscriptionId, DAV\PropPatch $propPatch) + { $supportedProperties = array_keys($this->subscriptionPropertyMap); $supportedProperties[] = '{http://calendarserver.org/ns/}source'; - $propPatch->handle($supportedProperties, function($mutations) use ($subscriptionId) { - + $propPatch->handle($supportedProperties, function ($mutations) use ($subscriptionId) { $newValues = []; foreach ($mutations as $propertyName => $propertyValue) { - - if ($propertyName === '{http://calendarserver.org/ns/}source') { + if ('{http://calendarserver.org/ns/}source' === $propertyName) { $newValues['source'] = $propertyValue->getHref(); } else { $fieldName = $this->subscriptionPropertyMap[$propertyName]; $newValues[$fieldName] = $propertyValue; } - } // Now we're generating the sql query. $valuesSql = []; foreach ($newValues as $fieldName => $value) { - $valuesSql[] = $fieldName . ' = ?'; + $valuesSql[] = $fieldName.' = ?'; } - $stmt = $this->pdo->prepare("UPDATE " . $this->calendarSubscriptionsTableName . " SET " . implode(', ', $valuesSql) . ", lastmodified = ? WHERE id = ?"); + $stmt = $this->pdo->prepare('UPDATE '.$this->calendarSubscriptionsTableName.' SET '.implode(', ', $valuesSql).', lastmodified = ? WHERE id = ?'); $newValues['lastmodified'] = time(); $newValues['id'] = $subscriptionId; $stmt->execute(array_values($newValues)); return true; - }); - } /** - * Deletes a subscription + * Deletes a subscription. * * @param mixed $subscriptionId - * @return void */ - function deleteSubscription($subscriptionId) { - - $stmt = $this->pdo->prepare('DELETE FROM ' . $this->calendarSubscriptionsTableName . ' WHERE id = ?'); + public function deleteSubscription($subscriptionId) + { + $stmt = $this->pdo->prepare('DELETE FROM '.$this->calendarSubscriptionsTableName.' WHERE id = ?'); $stmt->execute([$subscriptionId]); - } /** @@ -1253,24 +1218,26 @@ SQL; * * @param string $principalUri * @param string $objectUri + * * @return array */ - function getSchedulingObject($principalUri, $objectUri) { - - $stmt = $this->pdo->prepare('SELECT uri, calendardata, lastmodified, etag, size FROM ' . $this->schedulingObjectTableName . ' WHERE principaluri = ? AND uri = ?'); + public function getSchedulingObject($principalUri, $objectUri) + { + $stmt = $this->pdo->prepare('SELECT uri, calendardata, lastmodified, etag, size FROM '.$this->schedulingObjectTableName.' WHERE principaluri = ? AND uri = ?'); $stmt->execute([$principalUri, $objectUri]); $row = $stmt->fetch(\PDO::FETCH_ASSOC); - if (!$row) return null; + if (!$row) { + return null; + } return [ - 'uri' => $row['uri'], + 'uri' => $row['uri'], 'calendardata' => $row['calendardata'], 'lastmodified' => $row['lastmodified'], - 'etag' => '"' . $row['etag'] . '"', - 'size' => (int)$row['size'], + 'etag' => '"'.$row['etag'].'"', + 'size' => (int) $row['size'], ]; - } /** @@ -1282,40 +1249,38 @@ SQL; * The main difference is that 'calendardata' is optional. * * @param string $principalUri + * * @return array */ - function getSchedulingObjects($principalUri) { - - $stmt = $this->pdo->prepare('SELECT id, calendardata, uri, lastmodified, etag, size FROM ' . $this->schedulingObjectTableName . ' WHERE principaluri = ?'); + public function getSchedulingObjects($principalUri) + { + $stmt = $this->pdo->prepare('SELECT id, calendardata, uri, lastmodified, etag, size FROM '.$this->schedulingObjectTableName.' WHERE principaluri = ?'); $stmt->execute([$principalUri]); $result = []; foreach ($stmt->fetchAll(\PDO::FETCH_ASSOC) as $row) { $result[] = [ 'calendardata' => $row['calendardata'], - 'uri' => $row['uri'], + 'uri' => $row['uri'], 'lastmodified' => $row['lastmodified'], - 'etag' => '"' . $row['etag'] . '"', - 'size' => (int)$row['size'], + 'etag' => '"'.$row['etag'].'"', + 'size' => (int) $row['size'], ]; } return $result; - } /** - * Deletes a scheduling object + * Deletes a scheduling object. * * @param string $principalUri * @param string $objectUri - * @return void */ - function deleteSchedulingObject($principalUri, $objectUri) { - - $stmt = $this->pdo->prepare('DELETE FROM ' . $this->schedulingObjectTableName . ' WHERE principaluri = ? AND uri = ?'); + public function deleteSchedulingObject($principalUri, $objectUri) + { + $stmt = $this->pdo->prepare('DELETE FROM '.$this->schedulingObjectTableName.' WHERE principaluri = ? AND uri = ?'); $stmt->execute([$principalUri, $objectUri]); - } /** @@ -1324,35 +1289,32 @@ SQL; * @param string $principalUri * @param string $objectUri * @param string $objectData - * @return void */ - function createSchedulingObject($principalUri, $objectUri, $objectData) { - - $stmt = $this->pdo->prepare('INSERT INTO ' . $this->schedulingObjectTableName . ' (principaluri, calendardata, uri, lastmodified, etag, size) VALUES (?, ?, ?, ?, ?, ?)'); + public function createSchedulingObject($principalUri, $objectUri, $objectData) + { + $stmt = $this->pdo->prepare('INSERT INTO '.$this->schedulingObjectTableName.' (principaluri, calendardata, uri, lastmodified, etag, size) VALUES (?, ?, ?, ?, ?, ?)'); $stmt->execute([$principalUri, $objectData, $objectUri, time(), md5($objectData), strlen($objectData)]); - } /** * Updates the list of shares. * - * @param mixed $calendarId + * @param mixed $calendarId * @param \Sabre\DAV\Xml\Element\Sharee[] $sharees - * @return void */ - function updateInvites($calendarId, array $sharees) { - + public function updateInvites($calendarId, array $sharees) + { if (!is_array($calendarId)) { throw new \InvalidArgumentException('The value passed to $calendarId is expected to be an array with a calendarId and an instanceId'); } $currentInvites = $this->getInvites($calendarId); list($calendarId, $instanceId) = $calendarId; - $removeStmt = $this->pdo->prepare("DELETE FROM " . $this->calendarInstancesTableName . " WHERE calendarid = ? AND share_href = ? AND access IN (2,3)"); - $updateStmt = $this->pdo->prepare("UPDATE " . $this->calendarInstancesTableName . " SET access = ?, share_displayname = ?, share_invitestatus = ? WHERE calendarid = ? AND share_href = ?"); + $removeStmt = $this->pdo->prepare('DELETE FROM '.$this->calendarInstancesTableName.' WHERE calendarid = ? AND share_href = ? AND access IN (2,3)'); + $updateStmt = $this->pdo->prepare('UPDATE '.$this->calendarInstancesTableName.' SET access = ?, share_displayname = ?, share_invitestatus = ? WHERE calendarid = ? AND share_href = ?'); $insertStmt = $this->pdo->prepare(' -INSERT INTO ' . $this->calendarInstancesTableName . ' +INSERT INTO '.$this->calendarInstancesTableName.' ( calendarid, principaluri, @@ -1382,11 +1344,10 @@ INSERT INTO ' . $this->calendarInstancesTableName . ' ?, ?, ? - FROM ' . $this->calendarInstancesTableName . ' WHERE id = ?'); + FROM '.$this->calendarInstancesTableName.' WHERE id = ?'); foreach ($sharees as $sharee) { - - if ($sharee->access === \Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS) { + if (\Sabre\DAV\Sharing\Plugin::ACCESS_NOACCESS === $sharee->access) { // if access was set no NOACCESS, it means access for an // existing sharee was removed. $removeStmt->execute([$calendarId, $sharee->href]); @@ -1404,7 +1365,6 @@ INSERT INTO ' . $this->calendarInstancesTableName . ' } foreach ($currentInvites as $oldSharee) { - if ($oldSharee->href === $sharee->href) { // This is an update $sharee->properties = array_merge( @@ -1416,11 +1376,10 @@ INSERT INTO ' . $this->calendarInstancesTableName . ' isset($sharee->properties['{DAV:}displayname']) ? $sharee->properties['{DAV:}displayname'] : null, $sharee->inviteStatus ?: $oldSharee->inviteStatus, $calendarId, - $sharee->href + $sharee->href, ]); continue 2; } - } // If we got here, it means it was a new sharee $insertStmt->execute([ @@ -1431,11 +1390,9 @@ INSERT INTO ' . $this->calendarInstancesTableName . ' $sharee->href, isset($sharee->properties['{DAV:}displayname']) ? $sharee->properties['{DAV:}displayname'] : null, $sharee->inviteStatus ?: \Sabre\DAV\Sharing\Plugin::INVITE_NORESPONSE, - $instanceId + $instanceId, ]); - } - } /** @@ -1451,10 +1408,11 @@ INSERT INTO ' . $this->calendarInstancesTableName . ' * $properties * * @param mixed $calendarId + * * @return \Sabre\DAV\Xml\Element\Sharee[] */ - function getInvites($calendarId) { - + public function getInvites($calendarId) + { if (!is_array($calendarId)) { throw new \InvalidArgumentException('The value passed to getInvites() is expected to be an array with a calendarId and an instanceId'); } @@ -1477,35 +1435,29 @@ SQL; $result = []; while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) { - $result[] = new Sharee([ - 'href' => isset($row['share_href']) ? $row['share_href'] : \Sabre\HTTP\encodePath($row['principaluri']), - 'access' => (int)$row['access'], + 'href' => isset($row['share_href']) ? $row['share_href'] : \Sabre\HTTP\encodePath($row['principaluri']), + 'access' => (int) $row['access'], /// Everyone is always immediately accepted, for now. - 'inviteStatus' => (int)$row['share_invitestatus'], - 'properties' => - !empty($row['share_displayname']) + 'inviteStatus' => (int) $row['share_invitestatus'], + 'properties' => !empty($row['share_displayname']) ? ['{DAV:}displayname' => $row['share_displayname']] : [], 'principal' => $row['principaluri'], ]); - } - return $result; + return $result; } /** - * Publishes a calendar + * Publishes a calendar. * * @param mixed $calendarId - * @param bool $value - * @return void + * @param bool $value */ - function setPublishStatus($calendarId, $value) { - + public function setPublishStatus($calendarId, $value) + { throw new DAV\Exception\NotImplemented('Not implemented'); - } - } |