ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
XML.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Sabre\VObject\Parser;
4 
10 use Sabre\Xml as SabreXml;
11 
21 class XML extends Parser {
22 
23  const XCAL_NAMESPACE = 'urn:ietf:params:xml:ns:icalendar-2.0';
24  const XCARD_NAMESPACE = 'urn:ietf:params:xml:ns:vcard-4.0';
25 
31  protected $input;
32 
38  private $pointer;
39 
45  protected $root;
46 
57  function __construct($input = null, $options = 0) {
58 
59  if (0 === $options) {
60  $options = parent::OPTION_FORGIVING;
61  }
62 
63  parent::__construct($input, $options);
64 
65  }
66 
77  function parse($input = null, $options = 0) {
78 
79  if (!is_null($input)) {
80  $this->setInput($input);
81  }
82 
83  if (0 !== $options) {
84  $this->options = $options;
85  }
86 
87  if (is_null($this->input)) {
88  throw new EofException('End of input stream, or no input supplied');
89  }
90 
91  switch ($this->input['name']) {
92 
93  case '{' . self::XCAL_NAMESPACE . '}icalendar':
94  $this->root = new VCalendar([], false);
95  $this->pointer = &$this->input['value'][0];
96  $this->parseVCalendarComponents($this->root);
97  break;
98 
99  case '{' . self::XCARD_NAMESPACE . '}vcards':
100  foreach ($this->input['value'] as &$vCard) {
101 
102  $this->root = new VCard(['version' => '4.0'], false);
103  $this->pointer = &$vCard;
104  $this->parseVCardComponents($this->root);
105 
106  // We just parse the first <vcard /> element.
107  break;
108 
109  }
110  break;
111 
112  default:
113  throw new ParseException('Unsupported XML standard');
114 
115  }
116 
117  return $this->root;
118  }
119 
127  protected function parseVCalendarComponents(Component $parentComponent) {
128 
129  foreach ($this->pointer['value'] ?: [] as $children) {
130 
131  switch (static::getTagName($children['name'])) {
132 
133  case 'properties':
134  $this->pointer = &$children['value'];
135  $this->parseProperties($parentComponent);
136  break;
137 
138  case 'components':
139  $this->pointer = &$children;
140  $this->parseComponent($parentComponent);
141  break;
142  }
143  }
144 
145  }
146 
154  protected function parseVCardComponents(Component $parentComponent) {
155 
156  $this->pointer = &$this->pointer['value'];
157  $this->parseProperties($parentComponent);
158 
159  }
160 
169  protected function parseProperties(Component $parentComponent, $propertyNamePrefix = '') {
170 
171  foreach ($this->pointer ?: [] as $xmlProperty) {
172 
173  list($namespace, $tagName) = SabreXml\Service::parseClarkNotation($xmlProperty['name']);
174 
175  $propertyName = $tagName;
176  $propertyValue = [];
177  $propertyParameters = [];
178  $propertyType = 'text';
179 
180  // A property which is not part of the standard.
181  if ($namespace !== self::XCAL_NAMESPACE
182  && $namespace !== self::XCARD_NAMESPACE) {
183 
184  $propertyName = 'xml';
185  $value = '<' . $tagName . ' xmlns="' . $namespace . '"';
186 
187  foreach ($xmlProperty['attributes'] as $attributeName => $attributeValue) {
188  $value .= ' ' . $attributeName . '="' . str_replace('"', '\"', $attributeValue) . '"';
189  }
190 
191  $value .= '>' . $xmlProperty['value'] . '</' . $tagName . '>';
192 
193  $propertyValue = [$value];
194 
195  $this->createProperty(
196  $parentComponent,
197  $propertyName,
198  $propertyParameters,
199  $propertyType,
200  $propertyValue
201  );
202 
203  continue;
204  }
205 
206  // xCard group.
207  if ($propertyName === 'group') {
208 
209  if (!isset($xmlProperty['attributes']['name'])) {
210  continue;
211  }
212 
213  $this->pointer = &$xmlProperty['value'];
214  $this->parseProperties(
215  $parentComponent,
216  strtoupper($xmlProperty['attributes']['name']) . '.'
217  );
218 
219  continue;
220 
221  }
222 
223  // Collect parameters.
224  foreach ($xmlProperty['value'] as $i => $xmlPropertyChild) {
225 
226  if (!is_array($xmlPropertyChild)
227  || 'parameters' !== static::getTagName($xmlPropertyChild['name']))
228  continue;
229 
230  $xmlParameters = $xmlPropertyChild['value'];
231 
232  foreach ($xmlParameters as $xmlParameter) {
233 
234  $propertyParameterValues = [];
235 
236  foreach ($xmlParameter['value'] as $xmlParameterValues) {
237  $propertyParameterValues[] = $xmlParameterValues['value'];
238  }
239 
240  $propertyParameters[static::getTagName($xmlParameter['name'])]
241  = implode(',', $propertyParameterValues);
242 
243  }
244 
245  array_splice($xmlProperty['value'], $i, 1);
246 
247  }
248 
249  $propertyNameExtended = ($this->root instanceof VCalendar
250  ? 'xcal'
251  : 'xcard') . ':' . $propertyName;
252 
253  switch ($propertyNameExtended) {
254 
255  case 'xcal:geo':
256  $propertyType = 'float';
257  $propertyValue['latitude'] = 0;
258  $propertyValue['longitude'] = 0;
259 
260  foreach ($xmlProperty['value'] as $xmlRequestChild) {
261  $propertyValue[static::getTagName($xmlRequestChild['name'])]
262  = $xmlRequestChild['value'];
263  }
264  break;
265 
266  case 'xcal:request-status':
267  $propertyType = 'text';
268 
269  foreach ($xmlProperty['value'] as $xmlRequestChild) {
270  $propertyValue[static::getTagName($xmlRequestChild['name'])]
271  = $xmlRequestChild['value'];
272  }
273  break;
274 
275  case 'xcal:freebusy':
276  $propertyType = 'freebusy';
277  // We don't break because we only want to set
278  // another property type.
279 
280  case 'xcal:categories':
281  case 'xcal:resources':
282  case 'xcal:exdate':
283  foreach ($xmlProperty['value'] as $specialChild) {
284  $propertyValue[static::getTagName($specialChild['name'])]
285  = $specialChild['value'];
286  }
287  break;
288 
289  case 'xcal:rdate':
290  $propertyType = 'date-time';
291 
292  foreach ($xmlProperty['value'] as $specialChild) {
293 
294  $tagName = static::getTagName($specialChild['name']);
295 
296  if ('period' === $tagName) {
297 
298  $propertyParameters['value'] = 'PERIOD';
299  $propertyValue[] = implode('/', $specialChild['value']);
300 
301  }
302  else {
303  $propertyValue[] = $specialChild['value'];
304  }
305  }
306  break;
307 
308  default:
309  $propertyType = static::getTagName($xmlProperty['value'][0]['name']);
310 
311  foreach ($xmlProperty['value'] as $value) {
312  $propertyValue[] = $value['value'];
313  }
314 
315  if ('date' === $propertyType) {
316  $propertyParameters['value'] = 'DATE';
317  }
318  break;
319  }
320 
321  $this->createProperty(
322  $parentComponent,
323  $propertyNamePrefix . $propertyName,
324  $propertyParameters,
325  $propertyType,
326  $propertyValue
327  );
328 
329  }
330 
331  }
332 
340  protected function parseComponent(Component $parentComponent) {
341 
342  $components = $this->pointer['value'] ?: [];
343 
344  foreach ($components as $component) {
345 
346  $componentName = static::getTagName($component['name']);
347  $currentComponent = $this->root->createComponent(
348  $componentName,
349  null,
350  false
351  );
352 
353  $this->pointer = &$component;
354  $this->parseVCalendarComponents($currentComponent);
355 
356  $parentComponent->add($currentComponent);
357 
358  }
359 
360  }
361 
373  protected function createProperty(Component $parentComponent, $name, $parameters, $type, $value) {
374 
375  $property = $this->root->createProperty(
376  $name,
377  null,
378  $parameters,
379  $type
380  );
381  $parentComponent->add($property);
382  $property->setXmlValue($value);
383 
384  }
385 
393  function setInput($input) {
394 
395  if (is_resource($input)) {
396  $input = stream_get_contents($input);
397  }
398 
399  if (is_string($input)) {
400 
401  $reader = new SabreXml\Reader();
402  $reader->elementMap['{' . self::XCAL_NAMESPACE . '}period']
403  = 'Sabre\VObject\Parser\XML\Element\KeyValue';
404  $reader->elementMap['{' . self::XCAL_NAMESPACE . '}recur']
405  = 'Sabre\VObject\Parser\XML\Element\KeyValue';
406  $reader->xml($input);
407  $input = $reader->parse();
408 
409  }
410 
411  $this->input = $input;
412 
413  }
414 
422  protected static function getTagName($clarkedTagName) {
423 
424  list(, $tagName) = SabreXml\Service::parseClarkNotation($clarkedTagName);
425  return $tagName;
426 
427  }
428 }
if($err=$client->getError()) $namespace
parse($input=null, $options=0)
Parse xCal or xCard.
Definition: XML.php:77
$type
createProperty(Component $parentComponent, $name, $parameters, $type, $value)
Create a property.
Definition: XML.php:373
The VCalendar component.
Definition: VCalendar.php:23
static parseClarkNotation($str)
Parses a clark-notation string, and returns the namespace and element name components.
Definition: Service.php:274
setInput($input)
Sets the input data.
Definition: XML.php:393
The Reader class expands upon PHP&#39;s built-in XMLReader.
Definition: Reader.php:20
parseComponent(Component $parentComponent)
Parse a component.
Definition: XML.php:340
input
Definition: langcheck.php:166
parseVCalendarComponents(Component $parentComponent)
Parse a xCalendar component.
Definition: XML.php:127
Abstract parser.
Definition: Parser.php:14
add()
Adds a new property or component, and returns the new item.
Definition: Component.php:109
XML Parser.
Definition: XML.php:21
static getTagName($clarkedTagName)
Get tag name from a Clark notation.
Definition: XML.php:422
Exception thrown by Reader if an invalid object was attempted to be parsed.
parseVCardComponents(Component $parentComponent)
Parse a xCard component.
Definition: XML.php:154
$i
Definition: disco.tpl.php:19
Exception thrown by parser when the end of the stream has been reached, before this was expected...
The VCard component.
Definition: VCard.php:18
__construct($input=null, $options=0)
Creates the parser.
Definition: XML.php:57
parseProperties(Component $parentComponent, $propertyNamePrefix='')
Parse xCalendar and xCard properties.
Definition: XML.php:169