diff options
Diffstat (limited to 'apps/dav/lib/DAV/CustomPropertiesBackend.php')
-rw-r--r-- | apps/dav/lib/DAV/CustomPropertiesBackend.php | 70 |
1 files changed, 58 insertions, 12 deletions
diff --git a/apps/dav/lib/DAV/CustomPropertiesBackend.php b/apps/dav/lib/DAV/CustomPropertiesBackend.php index acee65cd00d..bd09ac2e4e6 100644 --- a/apps/dav/lib/DAV/CustomPropertiesBackend.php +++ b/apps/dav/lib/DAV/CustomPropertiesBackend.php @@ -31,6 +31,7 @@ use Sabre\DAV\PropertyStorage\Backend\BackendInterface; use Sabre\DAV\PropFind; use Sabre\DAV\PropPatch; use Sabre\DAV\Tree; +use Sabre\DAV\Xml\Property\Complex; use function array_intersect; class CustomPropertiesBackend implements BackendInterface { @@ -39,6 +40,21 @@ class CustomPropertiesBackend implements BackendInterface { private const TABLE_NAME = 'properties'; /** + * Value is stored as string. + */ + public const PROPERTY_TYPE_STRING = 1; + + /** + * Value is stored as XML fragment. + */ + public const PROPERTY_TYPE_XML = 2; + + /** + * Value is stored as a property object. + */ + public const PROPERTY_TYPE_OBJECT = 3; + + /** * Ignored properties * * @var string[] @@ -239,7 +255,7 @@ class CustomPropertiesBackend implements BackendInterface { $result = $qb->executeQuery(); $props = []; while ($row = $result->fetch()) { - $props[$row['propertyname']] = $row['propertyvalue']; + $props[$row['propertyname']] = $this->decodeValueFromDatabase($row['propertyvalue'], $row['valuetype']); } $result->closeCursor(); return $props; @@ -282,7 +298,7 @@ class CustomPropertiesBackend implements BackendInterface { $props = []; while ($row = $result->fetch()) { - $props[$row['propertyname']] = $row['propertyvalue']; + $props[$row['propertyname']] = $this->decodeValueFromDatabase($row['propertyvalue'], $row['valuetype']); } $result->closeCursor(); @@ -304,9 +320,9 @@ class CustomPropertiesBackend implements BackendInterface { ' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?'; $insertStatement = 'INSERT INTO `*PREFIX*properties`' . - ' (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)'; + ' (`userid`,`propertypath`,`propertyname`,`propertyvalue`, `valuetype`) VALUES(?,?,?,?,?)'; - $updateStatement = 'UPDATE `*PREFIX*properties` SET `propertyvalue` = ?' . + $updateStatement = 'UPDATE `*PREFIX*properties` SET `propertyvalue` = ?, `valuetype` = ?' . ' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?'; // TODO: use "insert or update" strategy ? @@ -325,24 +341,22 @@ class CustomPropertiesBackend implements BackendInterface { ); } } else { - if ($propertyValue instanceOf \Sabre\DAV\Xml\Property\Complex) { - $propertyValue = $propertyValue->getXml(); - } elseif (!is_string($propertyValue)) { - $propertyValue = (string)$propertyValue; - } + [$value, $valueType] = $this->encodeValueForDatabase($propertyValue); if (!array_key_exists($propertyName, $existing)) { $this->connection->executeUpdate($insertStatement, [ $this->user->getUID(), $this->formatPath($path), $propertyName, - $propertyValue, + $value, + $valueType ] ); } else { $this->connection->executeUpdate($updateStatement, [ - $propertyValue, + $value, + $valueType, $this->user->getUID(), $this->formatPath($path), $propertyName, @@ -367,8 +381,40 @@ class CustomPropertiesBackend implements BackendInterface { private function formatPath(string $path): string { if (strlen($path) > 250) { return sha1($path); + } + + return $path; + } + + /** + * @param mixed $value + * @return array + */ + private function encodeValueForDatabase($value): array { + if (is_scalar($value)) { + $valueType = self::PROPERTY_TYPE_STRING; + } elseif ($value instanceof Complex) { + $valueType = self::PROPERTY_TYPE_XML; + $value = $value->getXml(); } else { - return $path; + $valueType = self::PROPERTY_TYPE_OBJECT; + $value = serialize($value); + } + return [$value, $valueType]; + } + + /** + * @return mixed|Complex|string + */ + private function decodeValueFromDatabase(string $value, int $valueType) { + switch ($valueType) { + case self::PROPERTY_TYPE_XML: + return new Complex($value); + case self::PROPERTY_TYPE_OBJECT: + return unserialize($value); + case self::PROPERTY_TYPE_STRING: + default: + return $value; } } } |