1<?php 2 3declare(strict_types=1); 4 5namespace Sabre\DAV\Xml\Property; 6 7use Sabre\DAV\Browser\HtmlOutput; 8use Sabre\DAV\Browser\HtmlOutputHelper; 9use Sabre\Uri; 10use Sabre\Xml\Element; 11use Sabre\Xml\Reader; 12use Sabre\Xml\Writer; 13 14/** 15 * Href property. 16 * 17 * This class represents any WebDAV property that contains a {DAV:}href 18 * element, and there are many. 19 * 20 * It can support either 1 or more hrefs. If while unserializing no valid 21 * {DAV:}href elements were found, this property will unserialize itself as 22 * null. 23 * 24 * @copyright Copyright (C) fruux GmbH (https://fruux.com/) 25 * @author Evert Pot (http://www.rooftopsolutions.nl/) 26 * @license http://sabre.io/license/ Modified BSD License 27 */ 28class Href implements Element, HtmlOutput 29{ 30 /** 31 * List of uris. 32 * 33 * @var array 34 */ 35 protected $hrefs; 36 37 /** 38 * Constructor. 39 * 40 * You must either pass a string for a single href, or an array of hrefs. 41 * 42 * If auto-prefix is set to false, the hrefs will be treated as absolute 43 * and not relative to the servers base uri. 44 * 45 * @param string|string[] $hrefs 46 */ 47 public function __construct($hrefs) 48 { 49 if (is_string($hrefs)) { 50 $hrefs = [$hrefs]; 51 } 52 $this->hrefs = $hrefs; 53 } 54 55 /** 56 * Returns the first Href. 57 * 58 * @return string|null 59 */ 60 public function getHref() 61 { 62 return $this->hrefs[0] ?? null; 63 } 64 65 /** 66 * Returns the hrefs as an array. 67 * 68 * @return array 69 */ 70 public function getHrefs() 71 { 72 return $this->hrefs; 73 } 74 75 /** 76 * The xmlSerialize method is called during xml writing. 77 * 78 * Use the $writer argument to write its own xml serialization. 79 * 80 * An important note: do _not_ create a parent element. Any element 81 * implementing XmlSerializable should only ever write what's considered 82 * its 'inner xml'. 83 * 84 * The parent of the current element is responsible for writing a 85 * containing element. 86 * 87 * This allows serializers to be re-used for different element names. 88 * 89 * If you are opening new elements, you must also close them again. 90 */ 91 public function xmlSerialize(Writer $writer) 92 { 93 foreach ($this->getHrefs() as $href) { 94 $href = Uri\resolve($writer->contextUri, $href); 95 $writer->writeElement('{DAV:}href', $href); 96 } 97 } 98 99 /** 100 * Generate html representation for this value. 101 * 102 * The html output is 100% trusted, and no effort is being made to sanitize 103 * it. It's up to the implementor to sanitize user provided values. 104 * 105 * The output must be in UTF-8. 106 * 107 * The baseUri parameter is a url to the root of the application, and can 108 * be used to construct local links. 109 * 110 * @return string 111 */ 112 public function toHtml(HtmlOutputHelper $html) 113 { 114 $links = []; 115 foreach ($this->getHrefs() as $href) { 116 $links[] = $html->link($href); 117 } 118 119 return implode('<br />', $links); 120 } 121 122 /** 123 * The deserialize method is called during xml parsing. 124 * 125 * This method is called statically, this is because in theory this method 126 * may be used as a type of constructor, or factory method. 127 * 128 * Often you want to return an instance of the current class, but you are 129 * free to return other data as well. 130 * 131 * You are responsible for advancing the reader to the next element. Not 132 * doing anything will result in a never-ending loop. 133 * 134 * If you just want to skip parsing for this element altogether, you can 135 * just call $reader->next(); 136 * 137 * $reader->parseInnerTree() will parse the entire sub-tree, and advance to 138 * the next element. 139 * 140 * @return mixed 141 */ 142 public static function xmlDeserialize(Reader $reader) 143 { 144 $hrefs = []; 145 foreach ((array) $reader->parseInnerTree() as $elem) { 146 if ('{DAV:}href' !== $elem['name']) { 147 continue; 148 } 149 150 $hrefs[] = $elem['value']; 151 } 152 if ($hrefs) { 153 return new self($hrefs); 154 } 155 } 156} 157