diff options
-rw-r--r-- | apps/dav/lib/CalDAV/CalDavBackend.php | 151 |
1 files changed, 79 insertions, 72 deletions
diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index d949f32c1fc..f0d332adab5 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -97,6 +97,7 @@ use Sabre\VObject\Reader; use Sabre\VObject\Recur\EventIterator; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\GenericEvent; +use function array_column; use function array_merge; use function array_values; use function explode; @@ -104,6 +105,7 @@ use function is_array; use function is_resource; use function pathinfo; use function rewind; +use function settype; use function sprintf; use function str_replace; use function strtolower; @@ -142,20 +144,19 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription public const CLASSIFICATION_CONFIDENTIAL = 2; /** - * List of CalDAV properties, and how they map to database field names + * List of CalDAV properties, and how they map to database field names and their type * Add your own properties by simply adding on to this array. * - * Note that only string-based properties are supported here. - * * @var array + * @psalm-var array<string, string[]> */ public $propertyMap = [ - '{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', - '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}deleted-at' => 'deleted_at', + '{DAV:}displayname' => ['displayname', 'string'], + '{urn:ietf:params:xml:ns:caldav}calendar-description' => ['description', 'string'], + '{urn:ietf:params:xml:ns:caldav}calendar-timezone' => ['timezone', 'string'], + '{http://apple.com/ns/ical/}calendar-order' => ['calendarorder', 'int'], + '{http://apple.com/ns/ical/}calendar-color' => ['calendarcolor', 'string'], + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}deleted-at' => ['deleted_at', 'int'], ]; /** @@ -164,13 +165,13 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * @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', - '{http://calendarserver.org/ns/}subscribed-strip-attachments' => 'stripattachments', + '{DAV:}displayname' => ['displayname', 'string'], + '{http://apple.com/ns/ical/}refreshrate' => ['refreshrate', 'string'], + '{http://apple.com/ns/ical/}calendar-order' => ['calendarorder', 'int'], + '{http://apple.com/ns/ical/}calendar-color' => ['calendarcolor', 'string'], + '{http://calendarserver.org/ns/}subscribed-strip-todos' => ['striptodos', 'bool'], + '{http://calendarserver.org/ns/}subscribed-strip-alarms' => ['stripalarms', 'string'], + '{http://calendarserver.org/ns/}subscribed-strip-attachments' => ['stripattachments', 'string'], ]; /** @@ -351,7 +352,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription public function getCalendarsForUser($principalUri) { $principalUriOriginal = $principalUri; $principalUri = $this->convertPrincipal($principalUri, true); - $fields = array_values($this->propertyMap); + $fields = array_column($this->propertyMap, 0); $fields[] = 'id'; $fields[] = 'uri'; $fields[] = 'synctoken'; @@ -392,10 +393,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal' => $this->convertPrincipal($principalUri, !$this->legacyEndpoint), ]; - foreach ($this->propertyMap as $xmlName => $dbName) { - $calendar[$xmlName] = $row[$dbName]; - } - + $calendar = $this->rowToCalendar($row, $calendar); $calendar = $this->addOwnerPrincipalToCalendar($calendar); $calendar = $this->addResourceTypeToCalendar($row, $calendar); @@ -411,7 +409,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $principals[] = $principalUri; - $fields = array_values($this->propertyMap); + $fields = array_column($this->propertyMap, 0); $fields[] = 'a.id'; $fields[] = 'a.uri'; $fields[] = 'a.synctoken'; @@ -469,10 +467,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $readOnlyPropertyName => $readOnly, ]; - foreach ($this->propertyMap as $xmlName => $dbName) { - $calendar[$xmlName] = $row[$dbName]; - } - + $calendar = $this->rowToCalendar($row, $calendar); $calendar = $this->addOwnerPrincipalToCalendar($calendar); $calendar = $this->addResourceTypeToCalendar($row, $calendar); @@ -489,7 +484,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription */ public function getUsersOwnCalendars($principalUri) { $principalUri = $this->convertPrincipal($principalUri, true); - $fields = array_values($this->propertyMap); + $fields = array_column($this->propertyMap, 0); $fields[] = 'id'; $fields[] = 'uri'; $fields[] = 'synctoken'; @@ -518,10 +513,8 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components), '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), ]; - foreach ($this->propertyMap as $xmlName => $dbName) { - $calendar[$xmlName] = $row[$dbName]; - } + $calendar = $this->rowToCalendar($row, $calendar); $calendar = $this->addOwnerPrincipalToCalendar($calendar); $calendar = $this->addResourceTypeToCalendar($row, $calendar); @@ -556,7 +549,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * @return array */ public function getPublicCalendars() { - $fields = array_values($this->propertyMap); + $fields = array_column($this->propertyMap, 0); $fields[] = 'a.id'; $fields[] = 'a.uri'; $fields[] = 'a.synctoken'; @@ -595,10 +588,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC, ]; - foreach ($this->propertyMap as $xmlName => $dbName) { - $calendar[$xmlName] = $row[$dbName]; - } - + $calendar = $this->rowToCalendar($row, $calendar); $calendar = $this->addOwnerPrincipalToCalendar($calendar); $calendar = $this->addResourceTypeToCalendar($row, $calendar); @@ -617,7 +607,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * @throws NotFound */ public function getPublicCalendar($uri) { - $fields = array_values($this->propertyMap); + $fields = array_column($this->propertyMap, 0); $fields[] = 'a.id'; $fields[] = 'a.uri'; $fields[] = 'a.synctoken'; @@ -663,10 +653,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}public' => (int)$row['access'] === self::ACCESS_PUBLIC, ]; - foreach ($this->propertyMap as $xmlName => $dbName) { - $calendar[$xmlName] = $row[$dbName]; - } - + $calendar = $this->rowToCalendar($row, $calendar); $calendar = $this->addOwnerPrincipalToCalendar($calendar); $calendar = $this->addResourceTypeToCalendar($row, $calendar); @@ -679,7 +666,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * @return array|null */ public function getCalendarByUri($principal, $uri) { - $fields = array_values($this->propertyMap); + $fields = array_column($this->propertyMap, 0); $fields[] = 'id'; $fields[] = 'uri'; $fields[] = 'synctoken'; @@ -717,10 +704,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), ]; - foreach ($this->propertyMap as $xmlName => $dbName) { - $calendar[$xmlName] = $row[$dbName]; - } - + $calendar = $this->rowToCalendar($row, $calendar); $calendar = $this->addOwnerPrincipalToCalendar($calendar); $calendar = $this->addResourceTypeToCalendar($row, $calendar); @@ -732,7 +716,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * @return array|null */ public function getCalendarById($calendarId) { - $fields = array_values($this->propertyMap); + $fields = array_column($this->propertyMap, 0); $fields[] = 'id'; $fields[] = 'uri'; $fields[] = 'synctoken'; @@ -769,10 +753,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'), ]; - foreach ($this->propertyMap as $xmlName => $dbName) { - $calendar[$xmlName] = $row[$dbName]; - } - + $calendar = $this->rowToCalendar($row, $calendar); $calendar = $this->addOwnerPrincipalToCalendar($calendar); $calendar = $this->addResourceTypeToCalendar($row, $calendar); @@ -783,7 +764,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * @param $subscriptionId */ public function getSubscriptionById($subscriptionId) { - $fields = array_values($this->subscriptionPropertyMap); + $fields = array_column($this->subscriptionPropertyMap, 0); $fields[] = 'id'; $fields[] = 'uri'; $fields[] = 'source'; @@ -815,13 +796,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', ]; - foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) { - if (!is_null($row[$dbName])) { - $subscription[$xmlName] = $row[$dbName]; - } - } - - return $subscription; + return $this->rowToSubscription($row, $subscription); } /** @@ -863,7 +838,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $values['transparent'] = (int) ($properties[$transp]->getValue() === 'transparent'); } - foreach ($this->propertyMap as $xmlName => $dbName) { + foreach ($this->propertyMap as $xmlName => [$dbName, $type]) { if (isset($properties[$xmlName])) { $values[$dbName] = $properties[$xmlName]; } @@ -912,7 +887,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $newValues[$fieldName] = (int) ($propertyValue->getValue() === 'transparent'); break; default: - $fieldName = $this->propertyMap[$propertyName]; + $fieldName = $this->propertyMap[$propertyName][0]; $newValues[$fieldName] = $propertyValue; break; } @@ -1109,7 +1084,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription 'size' => (int) $row['size'], 'component' => strtolower($row['componenttype']), 'classification' => (int) $row['classification'], - '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}deleted-at' => $row['deleted_at'], + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}deleted-at' => $row['deleted_at'] === null ? $row['deleted_at'] : (int) $row['deleted_at'], ]; } $stmt->closeCursor(); @@ -1148,7 +1123,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription 'size' => (int)$row['size'], 'component' => strtolower($row['componenttype']), 'classification' => (int)$row['classification'], - '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}deleted-at' => $row['deleted_at'], + '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}deleted-at' => $row['deleted_at'] === null ? $row['deleted_at'] : (int) $row['deleted_at'], ]; } $stmt->closeCursor(); @@ -2452,7 +2427,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription * @return array */ public function getSubscriptionsForUser($principalUri) { - $fields = array_values($this->subscriptionPropertyMap); + $fields = array_column($this->subscriptionPropertyMap, 0); $fields[] = 'id'; $fields[] = 'uri'; $fields[] = 'source'; @@ -2480,13 +2455,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0', ]; - foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) { - if (!is_null($row[$dbName])) { - $subscription[$xmlName] = $row[$dbName]; - } - } - - $subscriptions[] = $subscription; + $subscriptions[] = $this->rowToSubscription($row, $subscription); } return $subscriptions; @@ -2517,7 +2486,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription $propertiesBoolean = ['striptodos', 'stripalarms', 'stripattachments']; - foreach ($this->subscriptionPropertyMap as $xmlName => $dbName) { + foreach ($this->subscriptionPropertyMap as $xmlName => [$dbName, $type]) { if (array_key_exists($xmlName, $properties)) { $values[$dbName] = $properties[$xmlName]; if (in_array($dbName, $propertiesBoolean)) { @@ -2579,7 +2548,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription if ($propertyName === '{http://calendarserver.org/ns/}source') { $newValues['source'] = $propertyValue->getHref(); } else { - $fieldName = $this->subscriptionPropertyMap[$propertyName]; + $fieldName = $this->subscriptionPropertyMap[$propertyName][0]; $newValues[$fieldName] = $propertyValue; } } @@ -3263,4 +3232,42 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription } return $calendar; } + + /** + * Amend the calendar info with database row data + * + * @param array $row + * @param array $calendar + * + * @return array + */ + private function rowToCalendar($row, array $calendar): array { + foreach ($this->propertyMap as $xmlName => [$dbName, $type]) { + $value = $row[$dbName]; + if ($value !== null) { + settype($value, $type); + } + $calendar[$xmlName] = $value; + } + return $calendar; + } + + /** + * Amend the subscription info with database row data + * + * @param array $row + * @param array $subscription + * + * @return array + */ + private function rowToSubscription($row, array $subscription): array { + foreach ($this->subscriptionPropertyMap as $xmlName => [$dbName, $type]) { + $value = $row[$dbName]; + if ($value !== null) { + settype($value, $type); + } + $subscription[$xmlName] = $value; + } + return $subscription; + } } |