diff options
Diffstat (limited to '3rdparty/Sabre/CardDAV/AddressBookQueryParser.php')
-rw-r--r-- | 3rdparty/Sabre/CardDAV/AddressBookQueryParser.php | 211 |
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 + ); + + + } + +} |