ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
Property.php
Go to the documentation of this file.
1<?php
2
3namespace Sabre\VObject;
4
5use Sabre\Xml;
6
17abstract 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()) {
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}
An exception for terminatinating execution or to throw for unit testing.
const VCARD30
vCard 3.0.
Definition: Document.php:44
const ICALENDAR20
iCalendar 2.0.
Definition: Document.php:34
const VCARD21
vCard 2.1.
Definition: Document.php:39
const VCARD40
vCard 4.0.
Definition: Document.php:49
A node is the root class for every element in an iCalendar of vCard object.
Definition: Node.php:19
count()
Returns the number of elements.
Definition: Node.php:177
VObject Parameter.
Definition: Parameter.php:20
static guessParameterNameByValue($value)
Try to guess property name by value, can be used for vCard 2.1 nameless parameters.
Definition: Parameter.php:85
parameters()
Returns an iterable list of children.
Definition: Property.php:196
serialize()
Turns the object back into a serialized blob.
Definition: Property.php:236
getValueType()
Returns the type of value.
offsetUnset($name)
Removes one or more parameters with the specified name.
Definition: Property.php:497
getParts()
Returns a multi-valued property.
Definition: Property.php:152
xmlSerializeValue(Xml\Writer $writer)
This method serializes only the value of a property.
Definition: Property.php:395
setJsonValue(array $value)
Sets the JSON value, as it would appear in a jCard or jCal object.
Definition: Property.php:286
__toString()
Called when this object is being cast to a string.
Definition: Property.php:416
__construct(Component $root, $name, $value=null, array $parameters=[], $group=null)
Creates the generic property.
Definition: Property.php:72
__clone()
This method is automatically called when the object is cloned.
Definition: Property.php:519
add($name, $value=null)
Adds a new parameter.
Definition: Property.php:174
offsetExists($name)
Checks if an array element exists.
Definition: Property.php:431
xmlSerialize(Xml\Writer $writer)
This method serializes the data into XML.
Definition: Property.php:350
validate($options=0)
Validates the node for correctness.
Definition: Property.php:546
getValue()
Returns the current value.
Definition: Property.php:115
jsonSerialize()
This method returns an array, with the representation as it should be encoded in JSON.
Definition: Property.php:302
getJsonValue()
Returns the value, in the format it should be encoded for JSON.
Definition: Property.php:271
offsetGet($name)
Returns a parameter.
Definition: Property.php:453
destroy()
Call this method on a document if you're done using it.
Definition: Property.php:651
offsetSet($name, $value)
Creates a new parameter.
Definition: Property.php:474
setRawMimeDirValue($val)
Sets a raw value coming from a mimedir (iCalendar/vCard) file.
getRawMimeDirValue()
Returns a raw mime-dir representation of the value.
setParts(array $parts)
Sets a multi-valued property.
Definition: Property.php:138
setXmlValue(array $value)
Hydrate data from a XML subtree, as it would appear in a xCard or xCal object.
Definition: Property.php:336
setValue($value)
Updates the current value.
Definition: Property.php:98
static convertToUTF8($str)
This method tries its best to convert the input string to UTF-8.
Definition: StringUtil.php:42
static isUTF8($str)
Returns true or false depending on if a string is valid UTF-8.
Definition: StringUtil.php:21
iCalendar/vCard/jCal/jCard/xCal/xCard writer object.
Definition: Writer.php:17
$key
Definition: croninfo.php:18
catch(Exception $e) $message
$values