summaryrefslogtreecommitdiffstats
path: root/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/Sabre/CardDAV/AddressBookQueryParser.php')
-rw-r--r--3rdparty/Sabre/CardDAV/AddressBookQueryParser.php211
1 files changed, 211 insertions, 0 deletions
diff --git a/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php b/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php
new file mode 100644
index 00000000000..08adc3b8157
--- /dev/null
+++ b/3rdparty/Sabre/CardDAV/AddressBookQueryParser.php
@@ -0,0 +1,211 @@
+<?php
+
+/**
+ * Parses the addressbook-query report request body.
+ *
+ * Whoever designed this format, and the CalDAV equavalent even more so,
+ * has no feel for design.
+ *
+ * @package Sabre
+ * @subpackage CardDAV
+ * @copyright Copyright (C) 2007-2011 Rooftop Solutions. All rights reserved.
+ * @author Evert Pot (http://www.rooftopsolutions.nl/)
+ * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
+ */
+class Sabre_CardDAV_AddressBookQueryParser {
+
+ const TEST_ANYOF = 'anyof';
+ const TEST_ALLOF = 'allof';
+
+ /**
+ * List of requested properties the client wanted
+ *
+ * @var array
+ */
+ public $requestedProperties;
+
+ /**
+ * The number of results the client wants
+ *
+ * null means it wasn't specified, which in most cases means 'all results'.
+ *
+ * @var int|null
+ */
+ public $limit;
+
+ /**
+ * List of property filters.
+ *
+ * @var array
+ */
+ public $filters;
+
+ /**
+ * Either TEST_ANYOF or TEST_ALLOF
+ *
+ * @var string
+ */
+ public $test;
+
+ /**
+ * DOM Document
+ *
+ * @var DOMDocument
+ */
+ protected $dom;
+
+ /**
+ * DOM XPath object
+ *
+ * @var DOMXPath
+ */
+ protected $xpath;
+
+ /**
+ * Creates the parser
+ *
+ * @param DOMNode $dom
+ * @return void
+ */
+ public function __construct(DOMDocument $dom) {
+
+ $this->dom = $dom;
+
+ $this->xpath = new DOMXPath($dom);
+ $this->xpath->registerNameSpace('card',Sabre_CardDAV_Plugin::NS_CARDDAV);
+
+ }
+
+ /**
+ * Parses the request.
+ *
+ * @param DOMNode $dom
+ * @return void
+ */
+ public function parse() {
+
+ $filterNode = null;
+
+ $limit = $this->xpath->evaluate('number(/card:addressbook-query/card:limit/card:nresults)');
+ if (is_nan($limit)) $limit = null;
+
+ $filter = $this->xpath->query('/card:addressbook-query/card:filter');
+ if ($filter->length !== 1) {
+ throw new Sabre_DAV_Exception_BadRequest('Only one filter element is allowed');
+ }
+
+ $filter = $filter->item(0);
+ $test = $this->xpath->evaluate('string(@test)', $filter);
+ if (!$test) $test = self::TEST_ANYOF;
+ if ($test !== self::TEST_ANYOF && $test !== self::TEST_ALLOF) {
+ throw new Sabre_DAV_Exception_BadRequest('The test attribute must either hold "anyof" or "allof"');
+ }
+
+ $propFilters = array();
+
+ $propFilterNodes = $this->xpath->query('card:prop-filter', $filter);
+ for($ii=0; $ii < $propFilterNodes->length; $ii++) {
+
+ $propFilters[] = $this->parsePropFilterNode($propFilterNodes->item($ii));
+
+
+ }
+
+ $this->filters = $propFilters;
+ $this->limit = $limit;
+ $this->requestedProperties = array_keys(Sabre_DAV_XMLUtil::parseProperties($this->dom->firstChild));
+ $this->test = $test;
+
+ }
+
+ /**
+ * Parses the prop-filter xml element
+ *
+ * @param DOMElement $propFilterNode
+ * @return array
+ */
+ protected function parsePropFilterNode(DOMElement $propFilterNode) {
+
+ $propFilter = array();
+ $propFilter['name'] = $propFilterNode->getAttribute('name');
+ $propFilter['test'] = $propFilterNode->getAttribute('test');
+ if (!$propFilter['test']) $propFilter['test'] = 'anyof';
+
+ $propFilter['is-not-defined'] = $this->xpath->query('card:is-not-defined', $propFilterNode)->length>0;
+
+ $paramFilterNodes = $this->xpath->query('card:param-filter', $propFilterNode);
+
+ $propFilter['param-filters'] = array();
+
+
+ for($ii=0;$ii<$paramFilterNodes->length;$ii++) {
+
+ $propFilter['param-filters'][] = $this->parseParamFilterNode($paramFilterNodes->item($ii));
+
+ }
+ $propFilter['text-matches'] = array();
+ $textMatchNodes = $this->xpath->query('card:text-match', $propFilterNode);
+
+ for($ii=0;$ii<$textMatchNodes->length;$ii++) {
+
+ $propFilter['text-matches'][] = $this->parseTextMatchNode($textMatchNodes->item($ii));
+
+ }
+
+ return $propFilter;
+
+ }
+
+ /**
+ * Parses the param-filter element
+ *
+ * @param DOMElement $paramFilterNode
+ * @return array
+ */
+ public function parseParamFilterNode(DOMElement $paramFilterNode) {
+
+ $paramFilter = array();
+ $paramFilter['name'] = $paramFilterNode->getAttribute('name');
+ $paramFilter['is-not-defined'] = $this->xpath->query('card:is-not-defined', $paramFilterNode)->length>0;
+ $paramFilter['text-match'] = null;
+
+ $textMatch = $this->xpath->query('card:text-match', $paramFilterNode);
+ if ($textMatch->length>0) {
+ $paramFilter['text-match'] = $this->parseTextMatchNode($textMatch->item(0));
+ }
+
+ return $paramFilter;
+
+ }
+
+ /**
+ * Text match
+ *
+ * @param DOMElement $textMatchNode
+ * @return void
+ */
+ public function parseTextMatchNode(DOMElement $textMatchNode) {
+
+ $matchType = $textMatchNode->getAttribute('match-type');
+ if (!$matchType) $matchType = 'contains';
+
+ if (!in_array($matchType, array('contains', 'equals', 'starts-with', 'ends-with'))) {
+ throw new Sabre_DAV_Exception_BadRequest('Unknown match-type: ' . $matchType);
+ }
+
+ $negateCondition = $textMatchNode->getAttribute('negate-condition');
+ $negateCondition = $negateCondition==='yes';
+ $collation = $textMatchNode->getAttribute('collation');
+ if (!$collation) $collation = 'i;unicode-casemap';
+
+ return array(
+ 'negate-condition' => $negateCondition,
+ 'collation' => $collation,
+ 'match-type' => $matchType,
+ 'value' => $textMatchNode->nodeValue
+ );
+
+
+ }
+
+}