]> git.mxchange.org Git - friendica-addons.git/blob - dav/sabre-vobject/lib/Sabre/VObject/Property.php
Second part of refactoring; should be runnable again, yet not thoroughly tested
[friendica-addons.git] / dav / sabre-vobject / lib / Sabre / VObject / Property.php
1 <?php
2
3 namespace Sabre\VObject;
4
5 /**
6  * VObject Property
7  *
8  * A property in VObject is usually in the form PARAMNAME:paramValue.
9  * An example is : SUMMARY:Weekly meeting
10  *
11  * Properties can also have parameters:
12  * SUMMARY;LANG=en:Weekly meeting.
13  *
14  * Parameters can be accessed using the ArrayAccess interface.
15  *
16  * @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
17  * @author Evert Pot (http://www.rooftopsolutions.nl/)
18  * @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
19  */
20 class Property extends Element {
21
22     /**
23      * Propertyname
24      *
25      * @var string
26      */
27     public $name;
28
29     /**
30      * Group name
31      *
32      * This may be something like 'HOME' for vcards.
33      *
34      * @var string
35      */
36     public $group;
37
38     /**
39      * Property parameters
40      *
41      * @var array
42      */
43     public $parameters = array();
44
45     /**
46      * Property value
47      *
48      * @var string
49      */
50     public $value;
51
52     /**
53      * If properties are added to this map, they will be automatically mapped
54      * to their respective classes, if parsed by the reader or constructed with
55      * the 'create' method.
56      *
57      * @var array
58      */
59     static public $classMap = array(
60         'COMPLETED'     => 'Sabre\\VObject\\Property\\DateTime',
61         'CREATED'       => 'Sabre\\VObject\\Property\\DateTime',
62         'DTEND'         => 'Sabre\\VObject\\Property\\DateTime',
63         'DTSTAMP'       => 'Sabre\\VObject\\Property\\DateTime',
64         'DTSTART'       => 'Sabre\\VObject\\Property\\DateTime',
65         'DUE'           => 'Sabre\\VObject\\Property\\DateTime',
66         'EXDATE'        => 'Sabre\\VObject\\Property\\MultiDateTime',
67         'LAST-MODIFIED' => 'Sabre\\VObject\\Property\\DateTime',
68         'RECURRENCE-ID' => 'Sabre\\VObject\\Property\\DateTime',
69         'TRIGGER'       => 'Sabre\\VObject\\Property\\DateTime',
70     );
71
72     /**
73      * Creates the new property by name, but in addition will also see if
74      * there's a class mapped to the property name.
75      *
76      * Parameters can be specified with the optional third argument. Parameters
77      * must be a key->value map of the parameter name, and value. If the value
78      * is specified as an array, it is assumed that multiple parameters with
79      * the same name should be added.
80      *
81      * @param string $name
82      * @param string $value
83      * @param array $parameters
84      * @return Property
85      */
86     static public function create($name, $value = null, array $parameters = array()) {
87
88         $name = strtoupper($name);
89         $shortName = $name;
90         $group = null;
91         if (strpos($shortName,'.')!==false) {
92             list($group, $shortName) = explode('.', $shortName);
93         }
94
95         if (isset(self::$classMap[$shortName])) {
96             return new self::$classMap[$shortName]($name, $value, $parameters);
97         } else {
98             return new self($name, $value, $parameters);
99         }
100
101     }
102
103     /**
104      * Creates a new property object
105      *
106      * Parameters can be specified with the optional third argument. Parameters
107      * must be a key->value map of the parameter name, and value. If the value
108      * is specified as an array, it is assumed that multiple parameters with
109      * the same name should be added.
110      *
111      * @param string $name
112      * @param string $value
113      * @param array $parameters
114      */
115     public function __construct($name, $value = null, array $parameters = array()) {
116
117         $name = strtoupper($name);
118         $group = null;
119         if (strpos($name,'.')!==false) {
120             list($group, $name) = explode('.', $name);
121         }
122         $this->name = $name;
123         $this->group = $group;
124         $this->setValue($value);
125
126         foreach($parameters as $paramName => $paramValues) {
127
128             if (!is_array($paramValues)) {
129                 $paramValues = array($paramValues);
130             }
131
132             foreach($paramValues as $paramValue) {
133                 $this->add($paramName, $paramValue);
134             }
135
136         }
137
138     }
139
140     /**
141      * Updates the internal value
142      *
143      * @param string $value
144      * @return void
145      */
146     public function setValue($value) {
147
148         $this->value = $value;
149
150     }
151
152     /**
153      * Turns the object back into a serialized blob.
154      *
155      * @return string
156      */
157     public function serialize() {
158
159         $str = $this->name;
160         if ($this->group) $str = $this->group . '.' . $this->name;
161
162         if (count($this->parameters)) {
163             foreach($this->parameters as $param) {
164
165                 $str.=';' . $param->serialize();
166
167             }
168         }
169         $src = array(
170             '\\',
171             "\n",
172         );
173         $out = array(
174             '\\\\',
175             '\n',
176         );
177         $str.=':' . str_replace($src, $out, $this->value);
178
179         $out = '';
180         while(strlen($str)>0) {
181             if (strlen($str)>75) {
182                 $out.= mb_strcut($str,0,75,'utf-8') . "\r\n";
183                 $str = ' ' . mb_strcut($str,75,strlen($str),'utf-8');
184             } else {
185                 $out.=$str . "\r\n";
186                 $str='';
187                 break;
188             }
189         }
190
191         return $out;
192
193     }
194
195     /**
196      * Adds a new componenten or element
197      *
198      * You can call this method with the following syntaxes:
199      *
200      * add(Parameter $element)
201      * add(string $name, $value)
202      *
203      * The first version adds an Parameter
204      * The second adds a property as a string.
205      *
206      * @param mixed $item
207      * @param mixed $itemValue
208      * @return void
209      */
210     public function add($item, $itemValue = null) {
211
212         if ($item instanceof Parameter) {
213             if (!is_null($itemValue)) {
214                 throw new \InvalidArgumentException('The second argument must not be specified, when passing a VObject');
215             }
216             $item->parent = $this;
217             $this->parameters[] = $item;
218         } elseif(is_string($item)) {
219
220             if (!is_scalar($itemValue) && !is_null($itemValue)) {
221                 throw new \InvalidArgumentException('The second argument must be scalar');
222             }
223             $parameter = new Parameter($item,$itemValue);
224             $parameter->parent = $this;
225             $this->parameters[] = $parameter;
226
227         } else {
228
229             throw new \InvalidArgumentException('The first argument must either be a Element or a string');
230
231         }
232
233     }
234
235     /* ArrayAccess interface {{{ */
236
237     /**
238      * Checks if an array element exists
239      *
240      * @param mixed $name
241      * @return bool
242      */
243     public function offsetExists($name) {
244
245         if (is_int($name)) return parent::offsetExists($name);
246
247         $name = strtoupper($name);
248
249         foreach($this->parameters as $parameter) {
250             if ($parameter->name == $name) return true;
251         }
252         return false;
253
254     }
255
256     /**
257      * Returns a parameter, or parameter list.
258      *
259      * @param string $name
260      * @return Element
261      */
262     public function offsetGet($name) {
263
264         if (is_int($name)) return parent::offsetGet($name);
265         $name = strtoupper($name);
266
267         $result = array();
268         foreach($this->parameters as $parameter) {
269             if ($parameter->name == $name)
270                 $result[] = $parameter;
271         }
272
273         if (count($result)===0) {
274             return null;
275         } elseif (count($result)===1) {
276             return $result[0];
277         } else {
278             $result[0]->setIterator(new ElementList($result));
279             return $result[0];
280         }
281
282     }
283
284     /**
285      * Creates a new parameter
286      *
287      * @param string $name
288      * @param mixed $value
289      * @return void
290      */
291     public function offsetSet($name, $value) {
292
293         if (is_int($name)) parent::offsetSet($name, $value);
294
295         if (is_scalar($value)) {
296             if (!is_string($name))
297                 throw new \InvalidArgumentException('A parameter name must be specified. This means you cannot use the $array[]="string" to add parameters.');
298
299             $this->offsetUnset($name);
300             $parameter = new Parameter($name, $value);
301             $parameter->parent = $this;
302             $this->parameters[] = $parameter;
303
304         } elseif ($value instanceof Parameter) {
305             if (!is_null($name))
306                 throw new \InvalidArgumentException('Don\'t specify a parameter name if you\'re passing a \\Sabre\\VObject\\Parameter. Add using $array[]=$parameterObject.');
307
308             $value->parent = $this;
309             $this->parameters[] = $value;
310         } else {
311             throw new \InvalidArgumentException('You can only add parameters to the property object');
312         }
313
314     }
315
316     /**
317      * Removes one or more parameters with the specified name
318      *
319      * @param string $name
320      * @return void
321      */
322     public function offsetUnset($name) {
323
324         if (is_int($name)) parent::offsetUnset($name);
325         $name = strtoupper($name);
326
327         foreach($this->parameters as $key=>$parameter) {
328             if ($parameter->name == $name) {
329                 $parameter->parent = null;
330                 unset($this->parameters[$key]);
331             }
332
333         }
334
335     }
336
337     /* }}} */
338
339     /**
340      * Called when this object is being cast to a string
341      *
342      * @return string
343      */
344     public function __toString() {
345
346         return (string)$this->value;
347
348     }
349
350     /**
351      * This method is automatically called when the object is cloned.
352      * Specifically, this will ensure all child elements are also cloned.
353      *
354      * @return void
355      */
356     public function __clone() {
357
358         foreach($this->parameters as $key=>$child) {
359             $this->parameters[$key] = clone $child;
360             $this->parameters[$key]->parent = $this;
361         }
362
363     }
364
365 }