ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Property.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Sabre\VObject;
4 
5 use Sabre\Xml;
6 
17 abstract class Property extends Node {
18 
26  public $name;
27 
35  public $group;
36 
42  public $parameters = [];
43 
49  protected $value;
50 
57  public $delimiter = ';';
58 
72  function __construct(Component $root, $name, $value = null, array $parameters = [], $group = null) {
73 
74  $this->name = $name;
75  $this->group = $group;
76 
77  $this->root = $root;
78 
79  foreach ($parameters as $k => $v) {
80  $this->add($k, $v);
81  }
82 
83  if (!is_null($value)) {
84  $this->setValue($value);
85  }
86 
87  }
88 
98  function setValue($value) {
99 
100  $this->value = $value;
101 
102  }
103 
115  function getValue() {
116 
117  if (is_array($this->value)) {
118  if (count($this->value) == 0) {
119  return;
120  } elseif (count($this->value) === 1) {
121  return $this->value[0];
122  } else {
123  return $this->getRawMimeDirValue();
124  }
125  } else {
126  return $this->value;
127  }
128 
129  }
130 
138  function setParts(array $parts) {
139 
140  $this->value = $parts;
141 
142  }
143 
152  function getParts() {
153 
154  if (is_null($this->value)) {
155  return [];
156  } elseif (is_array($this->value)) {
157  return $this->value;
158  } else {
159  return [$this->value];
160  }
161 
162  }
163 
174  function add($name, $value = null) {
175  $noName = false;
176  if ($name === null) {
178  $noName = true;
179  }
180 
181  if (isset($this->parameters[strtoupper($name)])) {
182  $this->parameters[strtoupper($name)]->addValue($value);
183  }
184  else {
185  $param = new Parameter($this->root, $name, $value);
186  $param->noName = $noName;
187  $this->parameters[$param->name] = $param;
188  }
189  }
190 
196  function parameters() {
197 
198  return $this->parameters;
199 
200  }
201 
210  abstract function getValueType();
211 
222  abstract function setRawMimeDirValue($val);
223 
229  abstract function getRawMimeDirValue();
230 
236  function serialize() {
237 
238  $str = $this->name;
239  if ($this->group) $str = $this->group . '.' . $this->name;
240 
241  foreach ($this->parameters() as $param) {
242 
243  $str .= ';' . $param->serialize();
244 
245  }
246 
247  $str .= ':' . $this->getRawMimeDirValue();
248 
249  $str = \preg_replace(
250  '/(
251  (?:^.)? # 1 additional byte in first line because of missing single space (see next line)
252  .{1,74} # max 75 bytes per line (1 byte is used for a single space added after every CRLF)
253  (?![\x80-\xbf]) # prevent splitting multibyte characters
254  )/x',
255  "$1\r\n ",
256  $str
257  );
258 
259  // remove single space after last CRLF
260  return \substr($str, 0, -1);
261 
262  }
263 
271  function getJsonValue() {
272 
273  return $this->getParts();
274 
275  }
276 
286  function setJsonValue(array $value) {
287 
288  if (count($value) === 1) {
289  $this->setValue(reset($value));
290  } else {
291  $this->setValue($value);
292  }
293 
294  }
295 
302  function jsonSerialize() {
303 
304  $parameters = [];
305 
306  foreach ($this->parameters as $parameter) {
307  if ($parameter->name === 'VALUE') {
308  continue;
309  }
310  $parameters[strtolower($parameter->name)] = $parameter->jsonSerialize();
311  }
312  // In jCard, we need to encode the property-group as a separate 'group'
313  // parameter.
314  if ($this->group) {
315  $parameters['group'] = $this->group;
316  }
317 
318  return array_merge(
319  [
320  strtolower($this->name),
321  (object)$parameters,
322  strtolower($this->getValueType()),
323  ],
324  $this->getJsonValue()
325  );
326  }
327 
336  function setXmlValue(array $value) {
337 
338  $this->setJsonValue($value);
339 
340  }
341 
350  function xmlSerialize(Xml\Writer $writer) {
351 
352  $parameters = [];
353 
354  foreach ($this->parameters as $parameter) {
355 
356  if ($parameter->name === 'VALUE') {
357  continue;
358  }
359 
360  $parameters[] = $parameter;
361 
362  }
363 
364  $writer->startElement(strtolower($this->name));
365 
366  if (!empty($parameters)) {
367 
368  $writer->startElement('parameters');
369 
370  foreach ($parameters as $parameter) {
371 
372  $writer->startElement(strtolower($parameter->name));
373  $writer->write($parameter);
374  $writer->endElement();
375 
376  }
377 
378  $writer->endElement();
379 
380  }
381 
382  $this->xmlSerializeValue($writer);
383  $writer->endElement();
384 
385  }
386 
395  protected function xmlSerializeValue(Xml\Writer $writer) {
396 
397  $valueType = strtolower($this->getValueType());
398 
399  foreach ($this->getJsonValue() as $values) {
400  foreach ((array)$values as $value) {
401  $writer->writeElement($valueType, $value);
402  }
403  }
404 
405  }
406 
416  function __toString() {
417 
418  return (string)$this->getValue();
419 
420  }
421 
422  /* ArrayAccess interface {{{ */
423 
431  function offsetExists($name) {
432 
433  if (is_int($name)) return parent::offsetExists($name);
434 
435  $name = strtoupper($name);
436 
437  foreach ($this->parameters as $parameter) {
438  if ($parameter->name == $name) return true;
439  }
440  return false;
441 
442  }
443 
453  function offsetGet($name) {
454 
455  if (is_int($name)) return parent::offsetGet($name);
456  $name = strtoupper($name);
457 
458  if (!isset($this->parameters[$name])) {
459  return;
460  }
461 
462  return $this->parameters[$name];
463 
464  }
465 
474  function offsetSet($name, $value) {
475 
476  if (is_int($name)) {
477  parent::offsetSet($name, $value);
478  // @codeCoverageIgnoreStart
479  // This will never be reached, because an exception is always
480  // thrown.
481  return;
482  // @codeCoverageIgnoreEnd
483  }
484 
485  $param = new Parameter($this->root, $name, $value);
486  $this->parameters[$param->name] = $param;
487 
488  }
489 
497  function offsetUnset($name) {
498 
499  if (is_int($name)) {
500  parent::offsetUnset($name);
501  // @codeCoverageIgnoreStart
502  // This will never be reached, because an exception is always
503  // thrown.
504  return;
505  // @codeCoverageIgnoreEnd
506  }
507 
508  unset($this->parameters[strtoupper($name)]);
509 
510  }
511  /* }}} */
512 
519  function __clone() {
520 
521  foreach ($this->parameters as $key => $child) {
522  $this->parameters[$key] = clone $child;
523  $this->parameters[$key]->parent = $this;
524  }
525 
526  }
527 
546  function validate($options = 0) {
547 
548  $warnings = [];
549 
550  // Checking if our value is UTF-8
551  if (!StringUtil::isUTF8($this->getRawMimeDirValue())) {
552 
553  $oldValue = $this->getRawMimeDirValue();
554  $level = 3;
555  if ($options & self::REPAIR) {
556  $newValue = StringUtil::convertToUTF8($oldValue);
557  if (true || StringUtil::isUTF8($newValue)) {
558  $this->setRawMimeDirValue($newValue);
559  $level = 1;
560  }
561 
562  }
563 
564 
565  if (preg_match('%([\x00-\x08\x0B-\x0C\x0E-\x1F\x7F])%', $oldValue, $matches)) {
566  $message = 'Property contained a control character (0x' . bin2hex($matches[1]) . ')';
567  } else {
568  $message = 'Property is not valid UTF-8! ' . $oldValue;
569  }
570 
571  $warnings[] = [
572  'level' => $level,
573  'message' => $message,
574  'node' => $this,
575  ];
576  }
577 
578  // Checking if the propertyname does not contain any invalid bytes.
579  if (!preg_match('/^([A-Z0-9-]+)$/', $this->name)) {
580  $warnings[] = [
581  'level' => $options & self::REPAIR ? 1 : 3,
582  'message' => 'The propertyname: ' . $this->name . ' contains invalid characters. Only A-Z, 0-9 and - are allowed',
583  'node' => $this,
584  ];
585  if ($options & self::REPAIR) {
586  // Uppercasing and converting underscores to dashes.
587  $this->name = strtoupper(
588  str_replace('_', '-', $this->name)
589  );
590  // Removing every other invalid character
591  $this->name = preg_replace('/([^A-Z0-9-])/u', '', $this->name);
592 
593  }
594 
595  }
596 
597  if ($encoding = $this->offsetGet('ENCODING')) {
598 
599  if ($this->root->getDocumentType() === Document::VCARD40) {
600  $warnings[] = [
601  'level' => 3,
602  'message' => 'ENCODING parameter is not valid in vCard 4.',
603  'node' => $this
604  ];
605  } else {
606 
607  $encoding = (string)$encoding;
608 
609  $allowedEncoding = [];
610 
611  switch ($this->root->getDocumentType()) {
612  case Document::ICALENDAR20 :
613  $allowedEncoding = ['8BIT', 'BASE64'];
614  break;
615  case Document::VCARD21 :
616  $allowedEncoding = ['QUOTED-PRINTABLE', 'BASE64', '8BIT'];
617  break;
618  case Document::VCARD30 :
619  $allowedEncoding = ['B'];
620  break;
621 
622  }
623  if ($allowedEncoding && !in_array(strtoupper($encoding), $allowedEncoding)) {
624  $warnings[] = [
625  'level' => 3,
626  'message' => 'ENCODING=' . strtoupper($encoding) . ' is not valid for this document type.',
627  'node' => $this
628  ];
629  }
630  }
631 
632  }
633 
634  // Validating inner parameters
635  foreach ($this->parameters as $param) {
636  $warnings = array_merge($warnings, $param->validate($options));
637  }
638 
639  return $warnings;
640 
641  }
642 
651  function destroy() {
652 
653  parent::destroy();
654  foreach ($this->parameters as $param) {
655  $param->destroy();
656  }
657  $this->parameters = [];
658 
659  }
660 
661 }
iCalendar/vCard/jCal/jCard/xCal/xCard writer object.
Definition: Writer.php:17
setXmlValue(array $value)
Hydrate data from a XML subtree, as it would appear in a xCard or xCal object.
Definition: Property.php:336
setRawMimeDirValue($val)
Sets a raw value coming from a mimedir (iCalendar/vCard) file.
jsonSerialize()
This method returns an array, with the representation as it should be encoded in JSON.
Definition: Property.php:302
setValue($value)
Updates the current value.
Definition: Property.php:98
offsetExists($name)
Checks if an array element exists.
Definition: Property.php:431
static isUTF8($str)
Returns true or false depending on if a string is valid UTF-8.
Definition: StringUtil.php:21
offsetGet($name)
Returns a parameter.
Definition: Property.php:453
destroy()
Call this method on a document if you&#39;re done using it.
Definition: Property.php:651
VObject Parameter.
Definition: Parameter.php:20
static convertToUTF8($str)
This method tries its best to convert the input string to UTF-8.
Definition: StringUtil.php:42
getValueType()
Returns the type of value.
xmlSerializeValue(Xml\Writer $writer)
This method serializes only the value of a property.
Definition: Property.php:395
getJsonValue()
Returns the value, in the format it should be encoded for JSON.
Definition: Property.php:271
xmlSerialize(Xml\Writer $writer)
This method serializes the data into XML.
Definition: Property.php:350
getParts()
Returns a multi-valued property.
Definition: Property.php:152
catch(Exception $e) $message
__construct(Component $root, $name, $value=null, array $parameters=[], $group=null)
Creates the generic property.
Definition: Property.php:72
add($name, $value=null)
Adds a new parameter.
Definition: Property.php:174
$values
const VCARD30
vCard 3.0.
Definition: Document.php:44
A node is the root class for every element in an iCalendar of vCard object.
Definition: Node.php:14
setParts(array $parts)
Sets a multi-valued property.
Definition: Property.php:138
validate($options=0)
Validates the node for correctness.
Definition: Property.php:546
const ICALENDAR20
iCalendar 2.0.
Definition: Document.php:34
parameters()
Returns an iterable list of children.
Definition: Property.php:196
offsetUnset($name)
Removes one or more parameters with the specified name.
Definition: Property.php:497
count()
Returns the number of elements.
Definition: Node.php:177
getRawMimeDirValue()
Returns a raw mime-dir representation of the value.
getValue()
Returns the current value.
Definition: Property.php:115
offsetSet($name, $value)
Creates a new parameter.
Definition: Property.php:474
const VCARD21
vCard 2.1.
Definition: Document.php:39
setJsonValue(array $value)
Sets the JSON value, as it would appear in a jCard or jCal object.
Definition: Property.php:286
const VCARD40
vCard 4.0.
Definition: Document.php:49
__toString()
Called when this object is being cast to a string.
Definition: Property.php:416
static guessParameterNameByValue($value)
Try to guess property name by value, can be used for vCard 2.1 nameless parameters.
Definition: Parameter.php:85
__clone()
This method is automatically called when the object is cloned.
Definition: Property.php:519
serialize()
Turns the object back into a serialized blob.
Definition: Property.php:236
$key
Definition: croninfo.php:18