PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.4
Booking for Appointments and Events Calendar – Amelia v2.4.4
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / vendor / sabre / vobject / lib / Parser / XML.php
ameliabooking / vendor / sabre / vobject / lib / Parser Last commit date
XML 6 months ago Json.php 6 months ago MimeDir.php 6 months ago Parser.php 6 months ago XML.php 6 months ago
XML.php
285 lines
1 <?php
2
3 namespace AmeliaVendor\Sabre\VObject\Parser;
4
5 use AmeliaVendor\Sabre\VObject\Component;
6 use AmeliaVendor\Sabre\VObject\Component\VCalendar;
7 use AmeliaVendor\Sabre\VObject\Component\VCard;
8 use AmeliaVendor\Sabre\VObject\EofException;
9 use AmeliaVendor\Sabre\VObject\ParseException;
10 use AmeliaVendor\Sabre\Xml as SabreXml;
11 /**
12 * XML Parser.
13 *
14 * This parser parses both the xCal and xCard formats.
15 *
16 * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
17 * @author Ivan Enderlin
18 * @license http://sabre.io/license/ Modified BSD License
19 */
20 class XML extends Parser
21 {
22 const XCAL_NAMESPACE = 'urn:ietf:params:xml:ns:icalendar-2.0';
23 const XCARD_NAMESPACE = 'urn:ietf:params:xml:ns:vcard-4.0';
24 /**
25 * The input data.
26 *
27 * @var array
28 */
29 protected $input;
30 /**
31 * A pointer/reference to the input.
32 *
33 * @var array
34 */
35 private $pointer;
36 /**
37 * Document, root component.
38 *
39 * @var \AmeliaVendor\Sabre\VObject\Document
40 */
41 protected $root;
42 /**
43 * Creates the parser.
44 *
45 * Optionally, it's possible to parse the input stream here.
46 *
47 * @param mixed $input
48 * @param int $options any parser options (OPTION constants)
49 */
50 public function __construct($input = null, $options = 0)
51 {
52 if (0 === $options) {
53 $options = parent::OPTION_FORGIVING;
54 }
55 parent::__construct($input, $options);
56 }
57 /**
58 * Parse xCal or xCard.
59 *
60 * @param resource|string $input
61 * @param int $options
62 *
63 * @throws \Exception
64 *
65 * @return \AmeliaVendor\Sabre\VObject\Document
66 */
67 public function parse($input = null, $options = 0)
68 {
69 if (!is_null($input)) {
70 $this->setInput($input);
71 }
72 if (0 !== $options) {
73 $this->options = $options;
74 }
75 if (is_null($this->input)) {
76 throw new EofException('End of input stream, or no input supplied');
77 }
78 switch ($this->input['name']) {
79 case '{' . self::XCAL_NAMESPACE . '}icalendar':
80 $this->root = new VCalendar([], false);
81 $this->pointer =& $this->input['value'][0];
82 $this->parseVCalendarComponents($this->root);
83 break;
84 case '{' . self::XCARD_NAMESPACE . '}vcards':
85 foreach ($this->input['value'] as &$vCard) {
86 $this->root = new VCard(['version' => '4.0'], false);
87 $this->pointer =& $vCard;
88 $this->parseVCardComponents($this->root);
89 // We just parse the first <vcard /> element.
90 break;
91 }
92 break;
93 default:
94 throw new ParseException('Unsupported XML standard');
95 }
96 return $this->root;
97 }
98 /**
99 * Parse a xCalendar component.
100 */
101 protected function parseVCalendarComponents(Component $parentComponent)
102 {
103 foreach ($this->pointer['value'] ?: [] as $children) {
104 switch (static::getTagName($children['name'])) {
105 case 'properties':
106 $this->pointer =& $children['value'];
107 $this->parseProperties($parentComponent);
108 break;
109 case 'components':
110 $this->pointer =& $children;
111 $this->parseComponent($parentComponent);
112 break;
113 }
114 }
115 }
116 /**
117 * Parse a xCard component.
118 */
119 protected function parseVCardComponents(Component $parentComponent)
120 {
121 $this->pointer =& $this->pointer['value'];
122 $this->parseProperties($parentComponent);
123 }
124 /**
125 * Parse xCalendar and xCard properties.
126 *
127 * @param string $propertyNamePrefix
128 */
129 protected function parseProperties(Component $parentComponent, $propertyNamePrefix = '')
130 {
131 foreach ($this->pointer ?: [] as $xmlProperty) {
132 list($namespace, $tagName) = SabreXml\Service::parseClarkNotation($xmlProperty['name']);
133 $propertyName = $tagName;
134 $propertyValue = [];
135 $propertyParameters = [];
136 $propertyType = 'text';
137 // A property which is not part of the standard.
138 if (self::XCAL_NAMESPACE !== $namespace && self::XCARD_NAMESPACE !== $namespace) {
139 $propertyName = 'xml';
140 $value = '<' . $tagName . ' xmlns="' . $namespace . '"';
141 foreach ($xmlProperty['attributes'] as $attributeName => $attributeValue) {
142 $value .= ' ' . $attributeName . '="' . str_replace('"', '\"', $attributeValue) . '"';
143 }
144 $value .= '>' . $xmlProperty['value'] . '</' . $tagName . '>';
145 $propertyValue = [$value];
146 $this->createProperty($parentComponent, $propertyName, $propertyParameters, $propertyType, $propertyValue);
147 continue;
148 }
149 // xCard group.
150 if ('group' === $propertyName) {
151 if (!isset($xmlProperty['attributes']['name'])) {
152 continue;
153 }
154 $this->pointer =& $xmlProperty['value'];
155 $this->parseProperties($parentComponent, strtoupper($xmlProperty['attributes']['name']) . '.');
156 continue;
157 }
158 // Collect parameters.
159 foreach ($xmlProperty['value'] as $i => $xmlPropertyChild) {
160 if (!is_array($xmlPropertyChild) || 'parameters' !== static::getTagName($xmlPropertyChild['name'])) {
161 continue;
162 }
163 $xmlParameters = $xmlPropertyChild['value'];
164 foreach ($xmlParameters as $xmlParameter) {
165 $propertyParameterValues = [];
166 foreach ($xmlParameter['value'] as $xmlParameterValues) {
167 $propertyParameterValues[] = $xmlParameterValues['value'];
168 }
169 $propertyParameters[static::getTagName($xmlParameter['name'])] = implode(',', $propertyParameterValues);
170 }
171 array_splice($xmlProperty['value'], $i, 1);
172 }
173 $propertyNameExtended = ($this->root instanceof VCalendar ? 'xcal' : 'xcard') . ':' . $propertyName;
174 switch ($propertyNameExtended) {
175 case 'xcal:geo':
176 $propertyType = 'float';
177 $propertyValue['latitude'] = 0;
178 $propertyValue['longitude'] = 0;
179 foreach ($xmlProperty['value'] as $xmlRequestChild) {
180 $propertyValue[static::getTagName($xmlRequestChild['name'])] = $xmlRequestChild['value'];
181 }
182 break;
183 case 'xcal:request-status':
184 $propertyType = 'text';
185 foreach ($xmlProperty['value'] as $xmlRequestChild) {
186 $propertyValue[static::getTagName($xmlRequestChild['name'])] = $xmlRequestChild['value'];
187 }
188 break;
189 case 'xcal:freebusy':
190 $propertyType = 'freebusy';
191 // We don't break because we only want to set
192 // another property type.
193 // no break
194 case 'xcal:categories':
195 case 'xcal:resources':
196 case 'xcal:exdate':
197 foreach ($xmlProperty['value'] as $specialChild) {
198 $propertyValue[static::getTagName($specialChild['name'])] = $specialChild['value'];
199 }
200 break;
201 case 'xcal:rdate':
202 $propertyType = 'date-time';
203 foreach ($xmlProperty['value'] as $specialChild) {
204 $tagName = static::getTagName($specialChild['name']);
205 if ('period' === $tagName) {
206 $propertyParameters['value'] = 'PERIOD';
207 $propertyValue[] = implode('/', $specialChild['value']);
208 } else {
209 $propertyValue[] = $specialChild['value'];
210 }
211 }
212 break;
213 default:
214 $propertyType = static::getTagName($xmlProperty['value'][0]['name']);
215 foreach ($xmlProperty['value'] as $value) {
216 $propertyValue[] = $value['value'];
217 }
218 if ('date' === $propertyType) {
219 $propertyParameters['value'] = 'DATE';
220 }
221 break;
222 }
223 $this->createProperty($parentComponent, $propertyNamePrefix . $propertyName, $propertyParameters, $propertyType, $propertyValue);
224 }
225 }
226 /**
227 * Parse a component.
228 */
229 protected function parseComponent(Component $parentComponent)
230 {
231 $components = $this->pointer['value'] ?: [];
232 foreach ($components as $component) {
233 $componentName = static::getTagName($component['name']);
234 $currentComponent = $this->root->createComponent($componentName, null, false);
235 $this->pointer =& $component;
236 $this->parseVCalendarComponents($currentComponent);
237 $parentComponent->add($currentComponent);
238 }
239 }
240 /**
241 * Create a property.
242 *
243 * @param string $name
244 * @param array $parameters
245 * @param string $type
246 * @param mixed $value
247 */
248 protected function createProperty(Component $parentComponent, $name, $parameters, $type, $value)
249 {
250 $property = $this->root->createProperty($name, null, $parameters, $type);
251 $parentComponent->add($property);
252 $property->setXmlValue($value);
253 }
254 /**
255 * Sets the input data.
256 *
257 * @param resource|string $input
258 */
259 public function setInput($input)
260 {
261 if (is_resource($input)) {
262 $input = stream_get_contents($input);
263 }
264 if (is_string($input)) {
265 $reader = new SabreXml\Reader();
266 $reader->elementMap['{' . self::XCAL_NAMESPACE . '}period'] = \AmeliaVendor\Sabre\VObject\Parser\XML\Element\KeyValue::class;
267 $reader->elementMap['{' . self::XCAL_NAMESPACE . '}recur'] = \AmeliaVendor\Sabre\VObject\Parser\XML\Element\KeyValue::class;
268 $reader->xml($input);
269 $input = $reader->parse();
270 }
271 $this->input = $input;
272 }
273 /**
274 * Get tag name from a Clark notation.
275 *
276 * @param string $clarkedTagName
277 *
278 * @return string
279 */
280 protected static function getTagName($clarkedTagName)
281 {
282 list(, $tagName) = SabreXml\Service::parseClarkNotation($clarkedTagName);
283 return $tagName;
284 }
285 }