3 namespace Sabre\VObject;
8 * A property in VObject is usually in the form PARAMNAME:paramValue.
9 * An example is : SUMMARY:Weekly meeting
11 * Properties can also have parameters:
12 * SUMMARY;LANG=en:Weekly meeting.
14 * Parameters can be accessed using the ArrayAccess interface.
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
20 class Property extends Element {
32 * This may be something like 'HOME' for vcards.
43 public $parameters = array();
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.
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',
73 * Creates the new property by name, but in addition will also see if
74 * there's a class mapped to the property name.
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.
82 * @param string $value
83 * @param array $parameters
86 static public function create($name, $value = null, array $parameters = array()) {
88 $name = strtoupper($name);
91 if (strpos($shortName,'.')!==false) {
92 list($group, $shortName) = explode('.', $shortName);
95 if (isset(self::$classMap[$shortName])) {
96 return new self::$classMap[$shortName]($name, $value, $parameters);
98 return new self($name, $value, $parameters);
104 * Creates a new property object
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.
111 * @param string $name
112 * @param string $value
113 * @param array $parameters
115 public function __construct($name, $value = null, array $parameters = array()) {
117 $name = strtoupper($name);
119 if (strpos($name,'.')!==false) {
120 list($group, $name) = explode('.', $name);
123 $this->group = $group;
124 $this->setValue($value);
126 foreach($parameters as $paramName => $paramValues) {
128 if (!is_array($paramValues)) {
129 $paramValues = array($paramValues);
132 foreach($paramValues as $paramValue) {
133 $this->add($paramName, $paramValue);
141 * Updates the internal value
143 * @param string $value
146 public function setValue($value) {
148 $this->value = $value;
153 * Turns the object back into a serialized blob.
157 public function serialize() {
160 if ($this->group) $str = $this->group . '.' . $this->name;
162 if (count($this->parameters)) {
163 foreach($this->parameters as $param) {
165 $str.=';' . $param->serialize();
177 $str.=':' . str_replace($src, $out, $this->value);
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');
196 * Adds a new componenten or element
198 * You can call this method with the following syntaxes:
200 * add(Parameter $element)
201 * add(string $name, $value)
203 * The first version adds an Parameter
204 * The second adds a property as a string.
207 * @param mixed $itemValue
210 public function add($item, $itemValue = null) {
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');
216 $item->parent = $this;
217 $this->parameters[] = $item;
218 } elseif(is_string($item)) {
220 if (!is_scalar($itemValue) && !is_null($itemValue)) {
221 throw new \InvalidArgumentException('The second argument must be scalar');
223 $parameter = new Parameter($item,$itemValue);
224 $parameter->parent = $this;
225 $this->parameters[] = $parameter;
229 throw new \InvalidArgumentException('The first argument must either be a Element or a string');
235 /* ArrayAccess interface {{{ */
238 * Checks if an array element exists
243 public function offsetExists($name) {
245 if (is_int($name)) return parent::offsetExists($name);
247 $name = strtoupper($name);
249 foreach($this->parameters as $parameter) {
250 if ($parameter->name == $name) return true;
257 * Returns a parameter, or parameter list.
259 * @param string $name
262 public function offsetGet($name) {
264 if (is_int($name)) return parent::offsetGet($name);
265 $name = strtoupper($name);
268 foreach($this->parameters as $parameter) {
269 if ($parameter->name == $name)
270 $result[] = $parameter;
273 if (count($result)===0) {
275 } elseif (count($result)===1) {
278 $result[0]->setIterator(new ElementList($result));
285 * Creates a new parameter
287 * @param string $name
288 * @param mixed $value
291 public function offsetSet($name, $value) {
293 if (is_int($name)) parent::offsetSet($name, $value);
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.');
299 $this->offsetUnset($name);
300 $parameter = new Parameter($name, $value);
301 $parameter->parent = $this;
302 $this->parameters[] = $parameter;
304 } elseif ($value instanceof Parameter) {
306 throw new \InvalidArgumentException('Don\'t specify a parameter name if you\'re passing a \\Sabre\\VObject\\Parameter. Add using $array[]=$parameterObject.');
308 $value->parent = $this;
309 $this->parameters[] = $value;
311 throw new \InvalidArgumentException('You can only add parameters to the property object');
317 * Removes one or more parameters with the specified name
319 * @param string $name
322 public function offsetUnset($name) {
324 if (is_int($name)) parent::offsetUnset($name);
325 $name = strtoupper($name);
327 foreach($this->parameters as $key=>$parameter) {
328 if ($parameter->name == $name) {
329 $parameter->parent = null;
330 unset($this->parameters[$key]);
340 * Called when this object is being cast to a string
344 public function __toString() {
346 return (string)$this->value;
351 * This method is automatically called when the object is cloned.
352 * Specifically, this will ensure all child elements are also cloned.
356 public function __clone() {
358 foreach($this->parameters as $key=>$child) {
359 $this->parameters[$key] = clone $child;
360 $this->parameters[$key]->parent = $this;