Browse Source
add Nextcloud Search extension to CalDAV
add Nextcloud Search extension to CalDAV
Signed-off-by: Georg Ehrke <developer@georgehrke.com>pull/4098/head
No known key found for this signature in database
GPG Key ID: 9D98FD9380A1CB43
14 changed files with 1064 additions and 1 deletions
-
72apps/dav/appinfo/database.xml
-
2apps/dav/appinfo/info.xml
-
278apps/dav/lib/CalDAV/CalDavBackend.php
-
10apps/dav/lib/CalDAV/CalendarHome.php
-
102apps/dav/lib/CalDAV/Search/CalendarSearchValidator.php
-
159apps/dav/lib/CalDAV/Search/SearchPlugin.php
-
47apps/dav/lib/CalDAV/Search/Xml/Filter/CompFilter.php
-
43apps/dav/lib/CalDAV/Search/Xml/Filter/LimitFilter.php
-
43apps/dav/lib/CalDAV/Search/Xml/Filter/OffsetFilter.php
-
55apps/dav/lib/CalDAV/Search/Xml/Filter/ParamFilter.php
-
47apps/dav/lib/CalDAV/Search/Xml/Filter/PropFilter.php
-
43apps/dav/lib/CalDAV/Search/Xml/Filter/SearchTermFilter.php
-
163apps/dav/lib/CalDAV/Search/Xml/Request/CalendarSearchReport.php
-
1apps/dav/lib/Server.php
@ -0,0 +1,102 @@ |
|||
<?php |
|||
/** |
|||
* @author Georg Ehrke <oc.list@georgehrke.com> |
|||
* |
|||
* @copyright Copyright (c) 2017 Georg Ehrke <oc.list@georgehrke.com> |
|||
* @license GNU AGPL version 3 or any later version |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
namespace OCA\DAV\CalDAV\Search; |
|||
|
|||
use Sabre\VObject; |
|||
|
|||
class CalendarSearchValidator { |
|||
|
|||
/** |
|||
* Verify if a list of filters applies to the calendar data object |
|||
* |
|||
* The list of filters must be formatted as parsed by Xml\Request\CalendarSearchReport |
|||
* |
|||
* @param VObject\Component\VCalendar $vObject |
|||
* @param array $filters |
|||
* @return bool |
|||
*/ |
|||
function validate(VObject\Component\VCalendar $vObject, array $filters) { |
|||
$comps = $vObject->getComponents(); |
|||
$filters['comps'][] = 'VTIMEZONE'; |
|||
|
|||
$matches = false; |
|||
foreach($comps as $comp) { |
|||
if ($comp->name === 'VTIMEZONE') { |
|||
continue; |
|||
} |
|||
if ($matches) { |
|||
break; |
|||
} |
|||
|
|||
// check comps
|
|||
if (!in_array($comp->name, $filters['comps'])) { |
|||
return false; |
|||
} |
|||
|
|||
$children = $comp->children(); |
|||
foreach($children as $child) { |
|||
if (!($child instanceof VObject\Property)) { |
|||
continue; |
|||
} |
|||
if ($matches) { |
|||
break; |
|||
} |
|||
|
|||
foreach($filters['props'] as $prop) { |
|||
if ($child->name !== $prop) { |
|||
continue; |
|||
} |
|||
|
|||
$value = $child->getValue(); |
|||
if (substr_count($value, $filters['search-term'])) { |
|||
$matches = true; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
foreach($filters['params'] as $param) { |
|||
$propName = $param['property']; |
|||
$paramName = $param['parameter']; |
|||
|
|||
if ($child->name !== $propName) { |
|||
continue; |
|||
} |
|||
if ($matches) { |
|||
break; |
|||
} |
|||
|
|||
$parameters = $child->parameters(); |
|||
foreach ($parameters as $key => $value) { |
|||
if ($paramName !== $key) { |
|||
continue; |
|||
} |
|||
if (substr_count($value, $filters['search-term'])) { |
|||
$matches = true; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
return $matches; |
|||
} |
|||
} |
|||
@ -0,0 +1,159 @@ |
|||
<?php |
|||
/** |
|||
* @author Georg Ehrke <oc.list@georgehrke.com> |
|||
* |
|||
* @copyright Copyright (c) 2017 Georg Ehrke <oc.list@georgehrke.com> |
|||
* @license GNU AGPL version 3 or any later version |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
namespace OCA\DAV\CalDAV\Search; |
|||
|
|||
use Sabre\DAV\Server; |
|||
use Sabre\DAV\ServerPlugin; |
|||
use OCA\DAV\CalDAV\CalendarHome; |
|||
|
|||
class SearchPlugin extends ServerPlugin { |
|||
const NS_Nextcloud = 'http://nextcloud.com/ns'; |
|||
|
|||
/** |
|||
* Reference to SabreDAV server object. |
|||
* |
|||
* @var \Sabre\DAV\Server |
|||
*/ |
|||
protected $server; |
|||
|
|||
/** |
|||
* This method should return a list of server-features. |
|||
* |
|||
* This is for example 'versioning' and is added to the DAV: header |
|||
* in an OPTIONS response. |
|||
* |
|||
* @return string[] |
|||
*/ |
|||
public function getFeatures() { |
|||
// May have to be changed to be detected
|
|||
return ['nc-calendar-search']; |
|||
} |
|||
|
|||
/** |
|||
* Returns a plugin name. |
|||
* |
|||
* Using this name other plugins will be able to access other plugins |
|||
* using Sabre\DAV\Server::getPlugin |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function getPluginName() { |
|||
return 'nc-calendar-search'; |
|||
} |
|||
|
|||
/** |
|||
* This initializes the plugin. |
|||
* |
|||
* This function is called by Sabre\DAV\Server, after |
|||
* addPlugin is called. |
|||
* |
|||
* This method should set up the required event subscriptions. |
|||
* |
|||
* @param Server $server |
|||
*/ |
|||
public function initialize(Server $server) { |
|||
$this->server = $server; |
|||
|
|||
$server->on('report', [$this, 'report']); |
|||
|
|||
$server->xml->elementMap['{' . self::NS_Nextcloud . '}calendar-search'] = |
|||
'OCA\\DAV\\CalDAV\\Search\\Xml\\Request\\CalendarSearchReport'; |
|||
} |
|||
|
|||
/** |
|||
* This functions handles REPORT requests specific to CalDAV |
|||
* |
|||
* @param string $reportName |
|||
* @param mixed $report |
|||
* @param mixed $path |
|||
* @return bool |
|||
*/ |
|||
function report($reportName, $report, $path) { |
|||
switch ($reportName) { |
|||
case '{' . self::NS_Nextcloud . '}calendar-search' : |
|||
$this->server->transactionType = 'report-nc-calendar-search'; |
|||
$this->calendarSearch($report); |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Returns a list of reports this plugin supports. |
|||
* |
|||
* This will be used in the {DAV:}supported-report-set property. |
|||
* Note that you still need to subscribe to the 'report' event to actually |
|||
* implement them |
|||
* |
|||
* @param string $uri |
|||
* @return array |
|||
*/ |
|||
public function getSupportedReportSet($uri) { |
|||
$node = $this->server->tree->getNodeForPath($uri); |
|||
|
|||
$reports = []; |
|||
if ($node instanceof CalendarHome) { |
|||
$reports[] = '{' . self::NS_Nextcloud . '}calendar-search'; |
|||
} |
|||
|
|||
return $reports; |
|||
} |
|||
|
|||
/** |
|||
* This function handles the calendar-query REPORT |
|||
* |
|||
* This report is used by clients to request calendar objects based on |
|||
* complex conditions. |
|||
* |
|||
* @param Xml\Request\CalendarSearchReport $report |
|||
* @return void |
|||
*/ |
|||
private function calendarSearch($report) { |
|||
$node = $this->server->tree->getNodeForPath($this->server->getRequestUri()); |
|||
$depth = $this->server->getHTTPDepth(0); |
|||
|
|||
// The default result is an empty array
|
|||
$result = []; |
|||
|
|||
// If we're dealing with the calendar home, the calendar home itself is
|
|||
// responsible for the calendar-query
|
|||
if ($node instanceof CalendarHome && $depth == 2) { |
|||
|
|||
$nodePaths = $node->calendarSearch($report->filters, $report->limit, $report->offset); |
|||
|
|||
foreach ($nodePaths as $path) { |
|||
list($properties) = $this->server->getPropertiesForPath( |
|||
$this->server->getRequestUri() . '/' . $path, |
|||
$report->properties); |
|||
$result[] = $properties; |
|||
} |
|||
} |
|||
|
|||
$prefer = $this->server->getHTTPPrefer(); |
|||
|
|||
$this->server->httpResponse->setStatus(207); |
|||
$this->server->httpResponse->setHeader('Content-Type', |
|||
'application/xml; charset=utf-8'); |
|||
$this->server->httpResponse->setHeader('Vary', 'Brief,Prefer'); |
|||
$this->server->httpResponse->setBody( |
|||
$this->server->generateMultiStatus($result, |
|||
$prefer['return'] === 'minimal')); |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* @author Georg Ehrke <oc.list@georgehrke.com> |
|||
* |
|||
* @copyright Copyright (c) 2017 Georg Ehrke <oc.list@georgehrke.com> |
|||
* @license GNU AGPL version 3 or any later version |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
namespace OCA\DAV\CalDAV\Search\Xml\Filter; |
|||
|
|||
use Sabre\DAV\Exception\BadRequest; |
|||
use Sabre\Xml\Reader; |
|||
use Sabre\Xml\XmlDeserializable; |
|||
use OCA\DAV\CalDAV\Search\SearchPlugin; |
|||
|
|||
class CompFilter implements XmlDeserializable { |
|||
|
|||
/** |
|||
* @param Reader $reader |
|||
* @throws BadRequest |
|||
* @return string |
|||
*/ |
|||
static function xmlDeserialize(Reader $reader) { |
|||
$att = $reader->parseAttributes(); |
|||
$componentName = $att['name']; |
|||
|
|||
$reader->parseInnerTree(); |
|||
|
|||
if (!is_string($componentName)) { |
|||
throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}comp-filter requires a valid name attribute'); |
|||
} |
|||
|
|||
return $componentName; |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
<?php |
|||
/** |
|||
* @author Georg Ehrke <oc.list@georgehrke.com> |
|||
* |
|||
* @copyright Copyright (c) 2017 Georg Ehrke <oc.list@georgehrke.com> |
|||
* @license GNU AGPL version 3 or any later version |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
namespace OCA\DAV\CalDAV\Search\Xml\Filter; |
|||
|
|||
use Sabre\DAV\Exception\BadRequest; |
|||
use Sabre\Xml\Reader; |
|||
use Sabre\Xml\XmlDeserializable; |
|||
use OCA\DAV\CalDAV\Search\SearchPlugin; |
|||
|
|||
class LimitFilter implements XmlDeserializable { |
|||
|
|||
/** |
|||
* @param Reader $reader |
|||
* @throws BadRequest |
|||
* @return int |
|||
*/ |
|||
static function xmlDeserialize(Reader $reader) { |
|||
$value = $reader->parseInnerTree(); |
|||
if (!is_int($value) && !is_string($value)) { |
|||
throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}limit has illegal value'); |
|||
} |
|||
|
|||
return intval($value); |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
<?php |
|||
/** |
|||
* @author Georg Ehrke <oc.list@georgehrke.com> |
|||
* |
|||
* @copyright Copyright (c) 2017 Georg Ehrke <oc.list@georgehrke.com> |
|||
* @license GNU AGPL version 3 or any later version |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
namespace OCA\DAV\CalDAV\Search\Xml\Filter; |
|||
|
|||
use Sabre\DAV\Exception\BadRequest; |
|||
use Sabre\Xml\Reader; |
|||
use Sabre\Xml\XmlDeserializable; |
|||
use OCA\DAV\CalDAV\Search\SearchPlugin; |
|||
|
|||
class OffsetFilter implements XmlDeserializable { |
|||
|
|||
/** |
|||
* @param Reader $reader |
|||
* @throws BadRequest |
|||
* @return int |
|||
*/ |
|||
static function xmlDeserialize(Reader $reader) { |
|||
$value = $reader->parseInnerTree(); |
|||
if (!is_int($value) && !is_string($value)) { |
|||
throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}offset has illegal value'); |
|||
} |
|||
|
|||
return intval($value); |
|||
} |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
<?php |
|||
/** |
|||
* @author Georg Ehrke <oc.list@georgehrke.com> |
|||
* |
|||
* @copyright Copyright (c) 2017 Georg Ehrke <oc.list@georgehrke.com> |
|||
* @license GNU AGPL version 3 or any later version |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
namespace OCA\DAV\CalDAV\Search\Xml\Filter; |
|||
|
|||
use Sabre\DAV\Exception\BadRequest; |
|||
use Sabre\Xml\Reader; |
|||
use Sabre\Xml\XmlDeserializable; |
|||
use OCA\DAV\CalDAV\Search\SearchPlugin; |
|||
|
|||
class ParamFilter implements XmlDeserializable { |
|||
|
|||
/** |
|||
* @param Reader $reader |
|||
* @throws BadRequest |
|||
* @return string |
|||
*/ |
|||
static function xmlDeserialize(Reader $reader) { |
|||
$att = $reader->parseAttributes(); |
|||
$property = $att['property']; |
|||
$parameter = $att['name']; |
|||
|
|||
$reader->parseInnerTree(); |
|||
|
|||
if (!is_string($property)) { |
|||
throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid property attribute'); |
|||
|
|||
} |
|||
if (!is_string($parameter)) { |
|||
throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}param-filter requires a valid parameter attribute'); |
|||
} |
|||
|
|||
return [ |
|||
'property' => $property, |
|||
'parameter' => $parameter, |
|||
]; |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
<?php |
|||
/** |
|||
* @author Georg Ehrke <oc.list@georgehrke.com> |
|||
* |
|||
* @copyright Copyright (c) 2017 Georg Ehrke <oc.list@georgehrke.com> |
|||
* @license GNU AGPL version 3 or any later version |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
namespace OCA\DAV\CalDAV\Search\Xml\Filter; |
|||
|
|||
use Sabre\DAV\Exception\BadRequest; |
|||
use Sabre\Xml\Reader; |
|||
use Sabre\Xml\XmlDeserializable; |
|||
use OCA\DAV\CalDAV\Search\SearchPlugin; |
|||
|
|||
class PropFilter implements XmlDeserializable { |
|||
|
|||
/** |
|||
* @param Reader $reader |
|||
* @throws BadRequest |
|||
* @return string |
|||
*/ |
|||
static function xmlDeserialize(Reader $reader) { |
|||
$att = $reader->parseAttributes(); |
|||
$componentName = $att['name']; |
|||
|
|||
$reader->parseInnerTree(); |
|||
|
|||
if (!is_string($componentName)) { |
|||
throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}prop-filter requires a valid name attribute'); |
|||
} |
|||
|
|||
return $componentName; |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
<?php |
|||
/** |
|||
* @author Georg Ehrke <oc.list@georgehrke.com> |
|||
* |
|||
* @copyright Copyright (c) 2017 Georg Ehrke <oc.list@georgehrke.com> |
|||
* @license GNU AGPL version 3 or any later version |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
namespace OCA\DAV\CalDAV\Search\Xml\Filter; |
|||
|
|||
use Sabre\DAV\Exception\BadRequest; |
|||
use Sabre\Xml\Reader; |
|||
use Sabre\Xml\XmlDeserializable; |
|||
use OCA\DAV\CalDAV\Search\SearchPlugin; |
|||
|
|||
class SearchTermFilter implements XmlDeserializable { |
|||
|
|||
/** |
|||
* @param Reader $reader |
|||
* @throws BadRequest |
|||
* @return string |
|||
*/ |
|||
static function xmlDeserialize(Reader $reader) { |
|||
$value = $reader->parseInnerTree(); |
|||
if (!is_string($value)) { |
|||
throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}search-term has illegal value'); |
|||
} |
|||
|
|||
return $value; |
|||
} |
|||
} |
|||
@ -0,0 +1,163 @@ |
|||
<?php |
|||
/** |
|||
* @author Georg Ehrke <oc.list@georgehrke.com> |
|||
* |
|||
* @copyright Copyright (c) 2017 Georg Ehrke <oc.list@georgehrke.com> |
|||
* @license GNU AGPL version 3 or any later version |
|||
* |
|||
* This code is free software: you can redistribute it and/or modify |
|||
* it under the terms of the GNU Affero General Public License, version 3, |
|||
* as published by the Free Software Foundation. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU Affero General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public License, version 3, |
|||
* along with this program. If not, see <http://www.gnu.org/licenses/> |
|||
* |
|||
*/ |
|||
namespace OCA\DAV\CalDAV\Search\Xml\Request; |
|||
|
|||
use Sabre\CalDAV\Plugin; |
|||
use Sabre\DAV\Exception\BadRequest; |
|||
use Sabre\Xml\Reader; |
|||
use Sabre\Xml\XmlDeserializable; |
|||
use OCA\DAV\CalDAV\Search\SearchPlugin; |
|||
|
|||
/** |
|||
* CalendarSearchReport request parser. |
|||
* |
|||
* This class parses the {urn:ietf:params:xml:ns:caldav}calendar-query |
|||
* REPORT, as defined in: |
|||
* |
|||
* https:// link to standard |
|||
*/ |
|||
class CalendarSearchReport implements XmlDeserializable { |
|||
|
|||
/** |
|||
* An array with requested properties. |
|||
* |
|||
* @var array |
|||
*/ |
|||
public $properties; |
|||
|
|||
/** |
|||
* List of property/component filters. |
|||
* |
|||
* @var array |
|||
*/ |
|||
public $filters; |
|||
|
|||
/** |
|||
* @var int |
|||
*/ |
|||
public $limit; |
|||
|
|||
/** |
|||
* @var int |
|||
*/ |
|||
public $offset; |
|||
|
|||
/** |
|||
* The deserialize method is called during xml parsing. |
|||
* |
|||
* This method is called statically, this is because in theory this method |
|||
* may be used as a type of constructor, or factory method. |
|||
* |
|||
* Often you want to return an instance of the current class, but you are |
|||
* free to return other data as well. |
|||
* |
|||
* You are responsible for advancing the reader to the next element. Not |
|||
* doing anything will result in a never-ending loop. |
|||
* |
|||
* If you just want to skip parsing for this element altogether, you can |
|||
* just call $reader->next(); |
|||
* |
|||
* $reader->parseInnerTree() will parse the entire sub-tree, and advance to |
|||
* the next element. |
|||
* |
|||
* @param Reader $reader |
|||
* @return mixed |
|||
*/ |
|||
static function xmlDeserialize(Reader $reader) { |
|||
$elems = $reader->parseInnerTree([ |
|||
'{http://nextcloud.com/ns}comp-filter' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\CompFilter', |
|||
'{http://nextcloud.com/ns}prop-filter' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\PropFilter', |
|||
'{http://nextcloud.com/ns}param-filter' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\ParamFilter', |
|||
'{http://nextcloud.com/ns}search-term' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\SearchTermFilter', |
|||
'{http://nextcloud.com/ns}limit' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\LimitFilter', |
|||
'{http://nextcloud.com/ns}offset' => 'OCA\\DAV\\CalDAV\\Search\\Xml\\Filter\\OffsetFilter', |
|||
'{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue', |
|||
]); |
|||
|
|||
$newProps = [ |
|||
'filters' => [], |
|||
'properties' => [], |
|||
'limit' => null, |
|||
'offset' => null |
|||
]; |
|||
|
|||
if (!is_array($elems)) { |
|||
$elems = []; |
|||
} |
|||
|
|||
foreach ($elems as $elem) { |
|||
switch ($elem['name']) { |
|||
case '{DAV:}prop': |
|||
$newProps['properties'] = array_keys($elem['value']); |
|||
if (isset($elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'])) { |
|||
$newProps += $elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data']; |
|||
} |
|||
break; |
|||
case '{' . SearchPlugin::NS_Nextcloud . '}filter': |
|||
foreach ($elem['value'] as $subElem) { |
|||
if ($subElem['name'] === '{' . SearchPlugin::NS_Nextcloud . '}comp-filter') { |
|||
if (!is_array($newProps['filters']['comps'])) { |
|||
$newProps['filters']['comps'] = []; |
|||
} |
|||
$newProps['filters']['comps'][] = $subElem['value']; |
|||
} elseif ($subElem['name'] === '{' . SearchPlugin::NS_Nextcloud . '}prop-filter') { |
|||
if (!is_array($newProps['filters']['props'])) { |
|||
$newProps['filters']['props'] = []; |
|||
} |
|||
$newProps['filters']['props'][] = $subElem['value']; |
|||
} elseif ($subElem['name'] === '{' . SearchPlugin::NS_Nextcloud . '}param-filter') { |
|||
if (!is_array($newProps['filters']['params'])) { |
|||
$newProps['filters']['params'] = []; |
|||
} |
|||
$newProps['filters']['params'][] = $subElem['value']; |
|||
} elseif ($subElem['name'] === '{' . SearchPlugin::NS_Nextcloud . '}search-term') { |
|||
$newProps['filters']['search-term'] = $subElem['value']; |
|||
} |
|||
} |
|||
break; |
|||
case '{' . SearchPlugin::NS_Nextcloud . '}limit': |
|||
$newProps['limit'] = $elem['value']; |
|||
break; |
|||
case '{' . SearchPlugin::NS_Nextcloud . '}offset': |
|||
$newProps['offset'] = $elem['value']; |
|||
break; |
|||
|
|||
} |
|||
} |
|||
|
|||
if (empty($newProps['filters'])) { |
|||
throw new BadRequest('The {' . SearchPlugin::NS_Nextcloud . '}filter element is required for this request'); |
|||
} |
|||
|
|||
$propsOrParamsDefined = (!empty($newProps['filters']['props']) || !empty($newProps['filters'])); |
|||
$noCompsDefined = empty($newProps['filters']['comps']); |
|||
if ($propsOrParamsDefined && $noCompsDefined) { |
|||
throw new BadRequest('{' . SearchPlugin::NS_Nextcloud . '}prop-filter or {' . SearchPlugin::NS_Nextcloud . '}param-filter given without any {' . SearchPlugin::NS_Nextcloud . '}comp-filter'); |
|||
} |
|||
|
|||
|
|||
$obj = new self(); |
|||
foreach ($newProps as $key => $value) { |
|||
$obj->$key = $value; |
|||
} |
|||
return $obj; |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue