1<?php 2 3namespace Sabre\DAVACL\Xml\Request; 4 5use Sabre\DAV\Exception\BadRequest; 6use Sabre\Xml\Reader; 7use Sabre\Xml\XmlDeserializable; 8 9/** 10 * PrincipalSearchPropertySetReport request parser. 11 * 12 * This class parses the {DAV:}principal-property-search REPORT, as defined 13 * in: 14 * 15 * https://tools.ietf.org/html/rfc3744#section-9.4 16 * 17 * @copyright Copyright (C) fruux GmbH (https://fruux.com/) 18 * @author Evert Pot (http://evertpot.com/) 19 * @license http://sabre.io/license/ Modified BSD License 20 */ 21class PrincipalPropertySearchReport implements XmlDeserializable { 22 23 /** 24 * The requested properties. 25 * 26 * @var array|null 27 */ 28 public $properties; 29 30 /** 31 * searchProperties 32 * 33 * @var array 34 */ 35 public $searchProperties = []; 36 37 /** 38 * By default the property search will be conducted on the url of the http 39 * request. If this is set to true, it will be applied to the principal 40 * collection set instead. 41 * 42 * @var bool 43 */ 44 public $applyToPrincipalCollectionSet = false; 45 46 /** 47 * Search for principals matching ANY of the properties (OR) or a ALL of 48 * the properties (AND). 49 * 50 * This property is either "anyof" or "allof". 51 * 52 * @var string 53 */ 54 public $test; 55 56 /** 57 * The deserialize method is called during xml parsing. 58 * 59 * This method is called statically, this is because in theory this method 60 * may be used as a type of constructor, or factory method. 61 * 62 * Often you want to return an instance of the current class, but you are 63 * free to return other data as well. 64 * 65 * You are responsible for advancing the reader to the next element. Not 66 * doing anything will result in a never-ending loop. 67 * 68 * If you just want to skip parsing for this element altogether, you can 69 * just call $reader->next(); 70 * 71 * $reader->parseInnerTree() will parse the entire sub-tree, and advance to 72 * the next element. 73 * 74 * @param Reader $reader 75 * @return mixed 76 */ 77 static function xmlDeserialize(Reader $reader) { 78 79 $self = new self(); 80 81 $foundSearchProp = false; 82 $self->test = 'allof'; 83 if ($reader->getAttribute('test') === 'anyof') { 84 $self->test = 'anyof'; 85 } 86 87 $elemMap = [ 88 '{DAV:}property-search' => 'Sabre\\Xml\\Element\\KeyValue', 89 '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue', 90 ]; 91 92 foreach ($reader->parseInnerTree($elemMap) as $elem) { 93 94 switch ($elem['name']) { 95 96 case '{DAV:}prop' : 97 $self->properties = array_keys($elem['value']); 98 break; 99 case '{DAV:}property-search' : 100 $foundSearchProp = true; 101 // This property has two sub-elements: 102 // {DAV:}prop - The property to be searched on. This may 103 // also be more than one 104 // {DAV:}match - The value to match with 105 if (!isset($elem['value']['{DAV:}prop']) || !isset($elem['value']['{DAV:}match'])) { 106 throw new BadRequest('The {DAV:}property-search element must contain one {DAV:}match and one {DAV:}prop element'); 107 } 108 foreach ($elem['value']['{DAV:}prop'] as $propName => $discard) { 109 $self->searchProperties[$propName] = $elem['value']['{DAV:}match']; 110 } 111 break; 112 case '{DAV:}apply-to-principal-collection-set' : 113 $self->applyToPrincipalCollectionSet = true; 114 break; 115 116 } 117 118 } 119 if (!$foundSearchProp) { 120 throw new BadRequest('The {DAV:}principal-property-search report must contain at least 1 {DAV:}property-search element'); 121 } 122 123 return $self; 124 125 } 126 127} 128