1<?php 2 3namespace Sabre\DAVACL\Xml\Property; 4 5use Sabre\DAV; 6use Sabre\DAV\Browser\HtmlOutputHelper; 7use Sabre\DAV\Exception\BadRequest; 8use Sabre\Xml\Reader; 9use Sabre\Xml\Writer; 10 11/** 12 * Principal property 13 * 14 * The principal property represents a principal from RFC3744 (ACL). 15 * The property can be used to specify a principal or pseudo principals. 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 Principal extends DAV\Xml\Property\Href { 22 23 /** 24 * To specify a not-logged-in user, use the UNAUTHENTICATED principal 25 */ 26 const UNAUTHENTICATED = 1; 27 28 /** 29 * To specify any principal that is logged in, use AUTHENTICATED 30 */ 31 const AUTHENTICATED = 2; 32 33 /** 34 * Specific principals can be specified with the HREF 35 */ 36 const HREF = 3; 37 38 /** 39 * Everybody, basically 40 */ 41 const ALL = 4; 42 43 /** 44 * Principal-type 45 * 46 * Must be one of the UNAUTHENTICATED, AUTHENTICATED or HREF constants. 47 * 48 * @var int 49 */ 50 protected $type; 51 52 /** 53 * Creates the property. 54 * 55 * The 'type' argument must be one of the type constants defined in this class. 56 * 57 * 'href' is only required for the HREF type. 58 * 59 * @param int $type 60 * @param string|null $href 61 */ 62 function __construct($type, $href = null) { 63 64 $this->type = $type; 65 if ($type === self::HREF && is_null($href)) { 66 throw new DAV\Exception('The href argument must be specified for the HREF principal type.'); 67 } 68 if ($href) { 69 $href = rtrim($href, '/') . '/'; 70 parent::__construct($href); 71 } 72 73 } 74 75 /** 76 * Returns the principal type 77 * 78 * @return int 79 */ 80 function getType() { 81 82 return $this->type; 83 84 } 85 86 87 /** 88 * The xmlSerialize method is called during xml writing. 89 * 90 * Use the $writer argument to write its own xml serialization. 91 * 92 * An important note: do _not_ create a parent element. Any element 93 * implementing XmlSerializable should only ever write what's considered 94 * its 'inner xml'. 95 * 96 * The parent of the current element is responsible for writing a 97 * containing element. 98 * 99 * This allows serializers to be re-used for different element names. 100 * 101 * If you are opening new elements, you must also close them again. 102 * 103 * @param Writer $writer 104 * @return void 105 */ 106 function xmlSerialize(Writer $writer) { 107 108 switch ($this->type) { 109 110 case self::UNAUTHENTICATED : 111 $writer->writeElement('{DAV:}unauthenticated'); 112 break; 113 case self::AUTHENTICATED : 114 $writer->writeElement('{DAV:}authenticated'); 115 break; 116 case self::HREF : 117 parent::xmlSerialize($writer); 118 break; 119 case self::ALL : 120 $writer->writeElement('{DAV:}all'); 121 break; 122 } 123 124 } 125 126 /** 127 * Generate html representation for this value. 128 * 129 * The html output is 100% trusted, and no effort is being made to sanitize 130 * it. It's up to the implementor to sanitize user provided values. 131 * 132 * The output must be in UTF-8. 133 * 134 * The baseUri parameter is a url to the root of the application, and can 135 * be used to construct local links. 136 * 137 * @param HtmlOutputHelper $html 138 * @return string 139 */ 140 function toHtml(HtmlOutputHelper $html) { 141 142 switch ($this->type) { 143 144 case self::UNAUTHENTICATED : 145 return '<em>unauthenticated</em>'; 146 case self::AUTHENTICATED : 147 return '<em>authenticated</em>'; 148 case self::HREF : 149 return parent::toHtml($html); 150 case self::ALL : 151 return '<em>all</em>'; 152 } 153 154 } 155 156 /** 157 * The deserialize method is called during xml parsing. 158 * 159 * This method is called staticly, this is because in theory this method 160 * may be used as a type of constructor, or factory method. 161 * 162 * Often you want to return an instance of the current class, but you are 163 * free to return other data as well. 164 * 165 * Important note 2: You are responsible for advancing the reader to the 166 * next element. Not doing anything will result in a never-ending loop. 167 * 168 * If you just want to skip parsing for this element altogether, you can 169 * just call $reader->next(); 170 * 171 * $reader->parseInnerTree() will parse the entire sub-tree, and advance to 172 * the next element. 173 * 174 * @param Reader $reader 175 * @return mixed 176 */ 177 static function xmlDeserialize(Reader $reader) { 178 179 $tree = $reader->parseInnerTree()[0]; 180 181 switch ($tree['name']) { 182 case '{DAV:}unauthenticated' : 183 return new self(self::UNAUTHENTICATED); 184 case '{DAV:}authenticated' : 185 return new self(self::AUTHENTICATED); 186 case '{DAV:}href': 187 return new self(self::HREF, $tree['value']); 188 case '{DAV:}all': 189 return new self(self::ALL); 190 default : 191 throw new BadRequest('Unknown or unsupported principal type: ' . $tree['name']); 192 } 193 194 } 195 196} 197