comparison vendor/sabre/vobject/lib/Parameter.php @ 7:430dbd5346f7

vendor sabre as distributed
author Charlie Root
date Sat, 13 Jan 2018 09:06:10 -0500
parents
children
comparison
equal deleted inserted replaced
6:cec75ba50afc 7:430dbd5346f7
1 <?php
2
3 namespace Sabre\VObject;
4
5 use
6 ArrayObject;
7
8 /**
9 * VObject Parameter
10 *
11 * This class represents a parameter. A parameter is always tied to a property.
12 * In the case of:
13 * DTSTART;VALUE=DATE:20101108
14 * VALUE=DATE would be the parameter name and value.
15 *
16 * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
17 * @author Evert Pot (http://evertpot.com/)
18 * @license http://sabre.io/license/ Modified BSD License
19 */
20 class Parameter extends Node {
21
22 /**
23 * Parameter name
24 *
25 * @var string
26 */
27 public $name;
28
29 /**
30 * vCard 2.1 allows parameters to be encoded without a name.
31 *
32 * We can deduce the parameter name based on it's value.
33 *
34 * @var bool
35 */
36 public $noName = false;
37
38 /**
39 * Parameter value
40 *
41 * @var string
42 */
43 protected $value;
44
45 /**
46 * Sets up the object.
47 *
48 * It's recommended to use the create:: factory method instead.
49 *
50 * @param string $name
51 * @param string $value
52 */
53 public function __construct(Document $root, $name, $value = null) {
54
55 $this->name = strtoupper($name);
56 $this->root = $root;
57 if (is_null($name)) {
58 $this->noName = true;
59 $this->name = static::guessParameterNameByValue($value);
60 }
61
62 // If guessParameterNameByValue() returns an empty string
63 // above, we're actually dealing with a parameter that has no value.
64 // In that case we have to move the value to the name.
65 if ($this->name === '') {
66 $this->noName = false;
67 $this->name = strtoupper($value);
68 } else {
69 $this->setValue($value);
70 }
71
72 }
73
74 /**
75 * Try to guess property name by value, can be used for vCard 2.1 nameless parameters.
76 *
77 * Figuring out what the name should have been. Note that a ton of
78 * these are rather silly in 2014 and would probably rarely be
79 * used, but we like to be complete.
80 *
81 * @param string $value
82 * @return string
83 */
84 public static function guessParameterNameByValue($value) {
85 switch(strtoupper($value)) {
86
87 // Encodings
88 case '7-BIT' :
89 case 'QUOTED-PRINTABLE' :
90 case 'BASE64' :
91 $name = 'ENCODING';
92 break;
93
94 // Common types
95 case 'WORK' :
96 case 'HOME' :
97 case 'PREF' :
98
99 // Delivery Label Type
100 case 'DOM' :
101 case 'INTL' :
102 case 'POSTAL' :
103 case 'PARCEL' :
104
105 // Telephone types
106 case 'VOICE' :
107 case 'FAX' :
108 case 'MSG' :
109 case 'CELL' :
110 case 'PAGER' :
111 case 'BBS' :
112 case 'MODEM' :
113 case 'CAR' :
114 case 'ISDN' :
115 case 'VIDEO' :
116
117 // EMAIL types (lol)
118 case 'AOL' :
119 case 'APPLELINK' :
120 case 'ATTMAIL' :
121 case 'CIS' :
122 case 'EWORLD' :
123 case 'INTERNET' :
124 case 'IBMMAIL' :
125 case 'MCIMAIL' :
126 case 'POWERSHARE' :
127 case 'PRODIGY' :
128 case 'TLX' :
129 case 'X400' :
130
131 // Photo / Logo format types
132 case 'GIF' :
133 case 'CGM' :
134 case 'WMF' :
135 case 'BMP' :
136 case 'DIB' :
137 case 'PICT' :
138 case 'TIFF' :
139 case 'PDF ':
140 case 'PS' :
141 case 'JPEG' :
142 case 'MPEG' :
143 case 'MPEG2' :
144 case 'AVI' :
145 case 'QTIME' :
146
147 // Sound Digital Audio Type
148 case 'WAVE' :
149 case 'PCM' :
150 case 'AIFF' :
151
152 // Key types
153 case 'X509' :
154 case 'PGP' :
155 $name = 'TYPE';
156 break;
157
158 // Value types
159 case 'INLINE' :
160 case 'URL' :
161 case 'CONTENT-ID' :
162 case 'CID' :
163 $name = 'VALUE';
164 break;
165
166 default:
167 $name = '';
168 }
169
170 return $name;
171 }
172
173 /**
174 * Updates the current value.
175 *
176 * This may be either a single, or multiple strings in an array.
177 *
178 * @param string|array $value
179 * @return void
180 */
181 public function setValue($value) {
182
183 $this->value = $value;
184
185 }
186
187 /**
188 * Returns the current value
189 *
190 * This method will always return a string, or null. If there were multiple
191 * values, it will automatically concatinate them (separated by comma).
192 *
193 * @return string|null
194 */
195 public function getValue() {
196
197 if (is_array($this->value)) {
198 return implode(',' , $this->value);
199 } else {
200 return $this->value;
201 }
202
203 }
204
205 /**
206 * Sets multiple values for this parameter.
207 *
208 * @param array $value
209 * @return void
210 */
211 public function setParts(array $value) {
212
213 $this->value = $value;
214
215 }
216
217 /**
218 * Returns all values for this parameter.
219 *
220 * If there were no values, an empty array will be returned.
221 *
222 * @return array
223 */
224 public function getParts() {
225
226 if (is_array($this->value)) {
227 return $this->value;
228 } elseif (is_null($this->value)) {
229 return array();
230 } else {
231 return array($this->value);
232 }
233
234 }
235
236 /**
237 * Adds a value to this parameter
238 *
239 * If the argument is specified as an array, all items will be added to the
240 * parameter value list.
241 *
242 * @param string|array $part
243 * @return void
244 */
245 public function addValue($part) {
246
247 if (is_null($this->value)) {
248 $this->value = $part;
249 } else {
250 $this->value = array_merge((array)$this->value, (array)$part);
251 }
252
253 }
254
255 /**
256 * Checks if this parameter contains the specified value.
257 *
258 * This is a case-insensitive match. It makes sense to call this for for
259 * instance the TYPE parameter, to see if it contains a keyword such as
260 * 'WORK' or 'FAX'.
261 *
262 * @param string $value
263 * @return bool
264 */
265 public function has($value) {
266
267 return in_array(
268 strtolower($value),
269 array_map('strtolower', (array)$this->value)
270 );
271
272 }
273
274 /**
275 * Turns the object back into a serialized blob.
276 *
277 * @return string
278 */
279 public function serialize() {
280
281 $value = $this->getParts();
282
283 if (count($value)===0) {
284 return $this->name . '=';
285 }
286
287 if ($this->root->getDocumentType() === Document::VCARD21 && $this->noName) {
288
289 return implode(';', $value);
290
291 }
292
293 return $this->name . '=' . array_reduce(
294 $value,
295 function($out, $item) {
296
297 if (!is_null($out)) $out.=',';
298
299 // If there's no special characters in the string, we'll use the simple
300 // format.
301 //
302 // The list of special characters is defined as:
303 //
304 // Any character except CONTROL, DQUOTE, ";", ":", ","
305 //
306 // by the iCalendar spec:
307 // https://tools.ietf.org/html/rfc5545#section-3.1
308 //
309 // And we add ^ to that because of:
310 // https://tools.ietf.org/html/rfc6868
311 //
312 // But we've found that iCal (7.0, shipped with OSX 10.9)
313 // severaly trips on + characters not being quoted, so we
314 // added + as well.
315 if (!preg_match('#(?: [\n":;\^,\+] )#x', $item)) {
316 return $out.$item;
317 } else {
318 // Enclosing in double-quotes, and using RFC6868 for encoding any
319 // special characters
320 $out.='"' . strtr(
321 $item,
322 array(
323 '^' => '^^',
324 "\n" => '^n',
325 '"' => '^\'',
326 )
327 ) . '"';
328 return $out;
329 }
330
331 }
332 );
333
334 }
335
336 /**
337 * This method returns an array, with the representation as it should be
338 * encoded in json. This is used to create jCard or jCal documents.
339 *
340 * @return array
341 */
342 public function jsonSerialize() {
343
344 return $this->value;
345
346 }
347
348 /**
349 * Called when this object is being cast to a string
350 *
351 * @return string
352 */
353 public function __toString() {
354
355 return (string)$this->getValue();
356
357 }
358
359 /**
360 * Returns the iterator for this object
361 *
362 * @return ElementList
363 */
364 public function getIterator() {
365
366 if (!is_null($this->iterator))
367 return $this->iterator;
368
369 return $this->iterator = new ArrayObject((array)$this->value);
370
371 }
372
373 }