@@ -7,686 +7,686 @@ |
||
7 | 7 | * @see RFC 2426, RFC 2425 |
8 | 8 | * @version 0.4.8 |
9 | 9 | */ |
10 | - class vCard implements Countable, Iterator |
|
11 | - { |
|
12 | - const MODE_ERROR = 'error'; |
|
13 | - const MODE_SINGLE = 'single'; |
|
14 | - const MODE_MULTIPLE = 'multiple'; |
|
15 | - |
|
16 | - const endl = "\n"; |
|
17 | - |
|
18 | - /** |
|
19 | - * @var string Current object mode - error, single or multiple (for a single vCard within a file and multiple combined vCards) |
|
20 | - */ |
|
21 | - private $Mode; //single, multiple, error |
|
22 | - |
|
23 | - private $Path = ''; |
|
24 | - private $RawData = ''; |
|
25 | - |
|
26 | - /** |
|
27 | - * @var array Internal options container. Options: |
|
28 | - * bool Collapse: If true, elements that can have multiple values but have only a single value are returned as that value instead of an array |
|
29 | - * If false, an array is returned even if it has only one value. |
|
30 | - */ |
|
31 | - private $Options = array( |
|
32 | - 'Collapse' => false |
|
33 | - ); |
|
34 | - |
|
35 | - /** |
|
36 | - * @var array Internal data container. Contains vCard objects for multiple vCards and just the data for single vCards. |
|
37 | - */ |
|
38 | - private $Data = array(); |
|
39 | - |
|
40 | - /** |
|
41 | - * @static Parts of structured elements according to the spec. |
|
42 | - */ |
|
43 | - private static $Spec_StructuredElements = array( |
|
44 | - 'n' => array('lastname', 'firstname', 'additionalnames', 'prefixes', 'suffixes'), |
|
45 | - 'adr' => array('pobox', 'extendedaddress', 'streetaddress', 'locality', 'region', 'postalcode', 'country'), |
|
46 | - 'geo' => array('latitude', 'longitude'), |
|
47 | - 'org' => array('name', 'unit1', 'unit2') |
|
48 | - ); |
|
49 | - private static $Spec_MultipleValueElements = array('nickname', 'categories'); |
|
50 | - |
|
51 | - private static $Spec_ElementTypes = array( |
|
52 | - 'email' => array('internet', 'x400', 'pref', 'home', 'work'), |
|
53 | - 'adr' => array('dom', 'intl', 'postal', 'parcel', 'home', 'work', 'pref'), |
|
54 | - 'label' => array('dom', 'intl', 'postal', 'parcel', 'home', 'work', 'pref'), |
|
55 | - 'tel' => array('home', 'msg', 'work', 'pref', 'voice', 'fax', 'cell', 'video', 'pager', 'bbs', 'modem', 'car', 'isdn', 'pcs'), |
|
56 | - 'impp' => array('personal', 'business', 'home', 'work', 'mobile', 'pref') |
|
57 | - ); |
|
58 | - |
|
59 | - private static $Spec_FileElements = array('photo', 'logo', 'sound'); |
|
60 | - |
|
61 | - /** |
|
62 | - * vCard constructor |
|
63 | - * |
|
64 | - * @param string Path to file, optional. |
|
65 | - * @param string Raw data, optional. |
|
66 | - * @param array Additional options, optional. Currently supported options: |
|
67 | - * bool Collapse: If true, elements that can have multiple values but have only a single value are returned as that value instead of an array |
|
68 | - * If false, an array is returned even if it has only one value. |
|
69 | - * |
|
70 | - * One of these parameters must be provided, otherwise an exception is thrown. |
|
71 | - */ |
|
72 | - public function __construct($Path = false, $RawData = false, array $Options = null) |
|
73 | - { |
|
74 | - // Checking preconditions for the parser. |
|
75 | - // If path is given, the file should be accessible. |
|
76 | - // If raw data is given, it is taken as it is. |
|
77 | - // In both cases the real content is put in $this -> RawData |
|
78 | - if ($Path) |
|
79 | - { |
|
80 | - if (!is_readable($Path)) |
|
81 | - { |
|
82 | - throw new Exception('vCard: Path not accessible ('.$Path.')'); |
|
83 | - } |
|
84 | - |
|
85 | - $this -> Path = $Path; |
|
86 | - $this -> RawData = file_get_contents($this -> Path); |
|
87 | - } |
|
88 | - elseif ($RawData) |
|
89 | - { |
|
90 | - $this -> RawData = $RawData; |
|
91 | - } |
|
92 | - else |
|
93 | - { |
|
94 | - //throw new Exception('vCard: No content provided'); |
|
95 | - // Not necessary anymore as possibility to create vCards is added |
|
96 | - } |
|
97 | - |
|
98 | - if (!$this -> Path && !$this -> RawData) |
|
99 | - { |
|
100 | - return true; |
|
101 | - } |
|
102 | - |
|
103 | - if ($Options) |
|
104 | - { |
|
105 | - $this -> Options = array_merge($this -> Options, $Options); |
|
106 | - } |
|
107 | - |
|
108 | - // Counting the begin/end separators. If there aren't any or the count doesn't match, there is a problem with the file. |
|
109 | - // If there is only one, this is a single vCard, if more, multiple vCards are combined. |
|
110 | - $Matches = array(); |
|
111 | - $vCardBeginCount = preg_match_all('{^BEGIN\:VCARD}miS', $this -> RawData, $Matches); |
|
112 | - $vCardEndCount = preg_match_all('{^END\:VCARD}miS', $this -> RawData, $Matches); |
|
113 | - |
|
114 | - if (($vCardBeginCount != $vCardEndCount) || !$vCardBeginCount) |
|
115 | - { |
|
116 | - $this -> Mode = vCard::MODE_ERROR; |
|
117 | - throw new Exception('vCard: invalid vCard'); |
|
118 | - } |
|
119 | - |
|
120 | - $this -> Mode = $vCardBeginCount == 1 ? vCard::MODE_SINGLE : vCard::MODE_MULTIPLE; |
|
121 | - |
|
122 | - // Removing/changing inappropriate newlines, i.e., all CRs or multiple newlines are changed to a single newline |
|
123 | - $this -> RawData = str_replace("\r", "\n", $this -> RawData); |
|
124 | - $this -> RawData = preg_replace('{(\n+)}', "\n", $this -> RawData); |
|
125 | - |
|
126 | - // In multiple card mode the raw text is split at card beginning markers and each |
|
127 | - // fragment is parsed in a separate vCard object. |
|
128 | - if ($this -> Mode == self::MODE_MULTIPLE) |
|
129 | - { |
|
130 | - $this -> RawData = explode('BEGIN:VCARD', $this -> RawData); |
|
131 | - $this -> RawData = array_filter($this -> RawData); |
|
132 | - |
|
133 | - foreach ($this -> RawData as $SinglevCardRawData) |
|
134 | - { |
|
135 | - // Prepending "BEGIN:VCARD" to the raw string because we exploded on that one. |
|
136 | - // If there won't be the BEGIN marker in the new object, it will fail. |
|
137 | - $SinglevCardRawData = 'BEGIN:VCARD'."\n".$SinglevCardRawData; |
|
138 | - |
|
139 | - $ClassName = get_class($this); |
|
140 | - $this -> Data[] = new $ClassName(false, $SinglevCardRawData); |
|
141 | - } |
|
142 | - } |
|
143 | - else |
|
144 | - { |
|
145 | - // Protect the BASE64 final = sign (detected by the line beginning with whitespace), otherwise the next replace will get rid of it |
|
146 | - $this -> RawData = preg_replace('{(\n\s.+)=(\n)}', '$1-base64=-$2', $this -> RawData); |
|
147 | - |
|
148 | - // Joining multiple lines that are split with a hard wrap and indicated by an equals sign at the end of line |
|
149 | - // (quoted-printable-encoded values in v2.1 vCards) |
|
150 | - $this -> RawData = str_replace("=\n", '', $this -> RawData); |
|
151 | - |
|
152 | - // Joining multiple lines that are split with a soft wrap (space or tab on the beginning of the next line |
|
153 | - $this -> RawData = str_replace(array("\n ", "\n\t"), '-wrap-', $this -> RawData); |
|
154 | - |
|
155 | - // Restoring the BASE64 final equals sign (see a few lines above) |
|
156 | - $this -> RawData = str_replace("-base64=-\n", "=\n", $this -> RawData); |
|
157 | - |
|
158 | - $Lines = explode("\n", $this -> RawData); |
|
159 | - |
|
160 | - foreach ($Lines as $Line) |
|
161 | - { |
|
162 | - // Lines without colons are skipped because, most likely, they contain no data. |
|
163 | - if (strpos($Line, ':') === false) |
|
164 | - { |
|
165 | - continue; |
|
166 | - } |
|
167 | - |
|
168 | - // Each line is split into two parts. The key contains the element name and additional parameters, if present, |
|
169 | - // value is just the value |
|
170 | - list($Key, $Value) = explode(':', $Line, 2); |
|
171 | - |
|
172 | - // Key is transformed to lowercase because, even though the element and parameter names are written in uppercase, |
|
173 | - // it is quite possible that they will be in lower- or mixed case. |
|
174 | - // The key is trimmed to allow for non-significant WSP characters as allowed by v2.1 |
|
175 | - $Key = strtolower(trim(self::Unescape($Key))); |
|
176 | - |
|
177 | - // These two lines can be skipped as they aren't necessary at all. |
|
178 | - if ($Key == 'begin' || $Key == 'end') |
|
179 | - { |
|
180 | - continue; |
|
181 | - } |
|
182 | - |
|
183 | - if ((strpos($Key, 'agent') === 0) && (stripos($Value, 'begin:vcard') !== false)) |
|
184 | - { |
|
185 | - $ClassName = get_class($this); |
|
186 | - $Value = new $ClassName(false, str_replace('-wrap-', "\n", $Value)); |
|
187 | - if (!isset($this -> Data[$Key])) |
|
188 | - { |
|
189 | - $this -> Data[$Key] = array(); |
|
190 | - } |
|
191 | - $this -> Data[$Key][] = $Value; |
|
192 | - continue; |
|
193 | - } |
|
194 | - else |
|
195 | - { |
|
196 | - $Value = str_replace('-wrap-', '', $Value); |
|
197 | - } |
|
198 | - |
|
199 | - $Value = trim(self::Unescape($Value)); |
|
200 | - $Type = array(); |
|
201 | - |
|
202 | - // Here additional parameters are parsed |
|
203 | - $KeyParts = explode(';', $Key); |
|
204 | - $Key = $KeyParts[0]; |
|
205 | - $Encoding = false; |
|
206 | - |
|
207 | - if (strpos($Key, 'item') === 0) |
|
208 | - { |
|
209 | - $TmpKey = explode('.', $Key, 2); |
|
210 | - $Key = $TmpKey[1]; |
|
211 | - $ItemIndex = (int)str_ireplace('item', '', $TmpKey[0]); |
|
212 | - } |
|
213 | - |
|
214 | - if (count($KeyParts) > 1) |
|
215 | - { |
|
216 | - $Parameters = self::ParseParameters($Key, array_slice($KeyParts, 1)); |
|
217 | - |
|
218 | - foreach ($Parameters as $ParamKey => $ParamValue) |
|
219 | - { |
|
220 | - switch ($ParamKey) |
|
221 | - { |
|
222 | - case 'encoding': |
|
223 | - $Encoding = $ParamValue; |
|
224 | - if (in_array($ParamValue, array('b', 'base64'))) |
|
225 | - { |
|
226 | - //$Value = base64_decode($Value); |
|
227 | - } |
|
228 | - elseif ($ParamValue == 'quoted-printable') // v2.1 |
|
229 | - { |
|
230 | - $Value = quoted_printable_decode($Value); |
|
231 | - } |
|
232 | - break; |
|
233 | - case 'charset': // v2.1 |
|
234 | - if ($ParamValue != 'utf-8' && $ParamValue != 'utf8') |
|
235 | - { |
|
236 | - $Value = mb_convert_encoding($Value, 'UTF-8', $ParamValue); |
|
237 | - } |
|
238 | - break; |
|
239 | - case 'type': |
|
240 | - $Type = $ParamValue; |
|
241 | - break; |
|
242 | - } |
|
243 | - } |
|
244 | - } |
|
245 | - |
|
246 | - // Checking files for colon-separated additional parameters (Apple's Address Book does this), for example, "X-ABCROP-RECTANGLE" for photos |
|
247 | - if (in_array($Key, self::$Spec_FileElements) && isset($Parameters['encoding']) && in_array($Parameters['encoding'], array('b', 'base64'))) |
|
248 | - { |
|
249 | - // If colon is present in the value, it must contain Address Book parameters |
|
250 | - // (colon is an invalid character for base64 so it shouldn't appear in valid files) |
|
251 | - if (strpos($Value, ':') !== false) |
|
252 | - { |
|
253 | - $Value = explode(':', $Value); |
|
254 | - $Value = array_pop($Value); |
|
255 | - } |
|
256 | - } |
|
257 | - |
|
258 | - // Values are parsed according to their type |
|
259 | - if (isset(self::$Spec_StructuredElements[$Key])) |
|
260 | - { |
|
261 | - $Value = self::ParseStructuredValue($Value, $Key); |
|
262 | - if ($Type) |
|
263 | - { |
|
264 | - $Value['type'] = $Type; |
|
265 | - } |
|
266 | - } |
|
267 | - else |
|
268 | - { |
|
269 | - if (in_array($Key, self::$Spec_MultipleValueElements)) |
|
270 | - { |
|
271 | - $Value = self::ParseMultipleTextValue($Value, $Key); |
|
272 | - } |
|
273 | - |
|
274 | - if ($Type) |
|
275 | - { |
|
276 | - $Value = array( |
|
277 | - 'value' => $Value, |
|
278 | - 'type' => $Type |
|
279 | - ); |
|
280 | - } |
|
281 | - } |
|
282 | - |
|
283 | - if (is_array($Value) && $Encoding) |
|
284 | - { |
|
285 | - $Value['encoding'] = $Encoding; |
|
286 | - } |
|
287 | - |
|
288 | - if (!isset($this -> Data[$Key])) |
|
289 | - { |
|
290 | - $this -> Data[$Key] = array(); |
|
291 | - } |
|
292 | - |
|
293 | - $this -> Data[$Key][] = $Value; |
|
294 | - } |
|
295 | - } |
|
296 | - } |
|
297 | - |
|
298 | - /** |
|
299 | - * Magic method to get the various vCard values as object members, e.g. |
|
300 | - * a call to $vCard -> N gets the "N" value |
|
301 | - * |
|
302 | - * @param string Key |
|
303 | - * |
|
304 | - * @return mixed Value |
|
305 | - */ |
|
306 | - public function __get($Key) |
|
307 | - { |
|
308 | - $Key = strtolower($Key); |
|
309 | - if (isset($this -> Data[$Key])) |
|
310 | - { |
|
311 | - if ($Key == 'agent') |
|
312 | - { |
|
313 | - return $this -> Data[$Key]; |
|
314 | - } |
|
315 | - elseif (in_array($Key, self::$Spec_FileElements)) |
|
316 | - { |
|
317 | - $Value = $this -> Data[$Key]; |
|
318 | - foreach ($Value as $K => $V) |
|
319 | - { |
|
320 | - if (stripos($V['value'], 'uri:') === 0) |
|
321 | - { |
|
322 | - $Value[$K]['value'] = substr($V, 4); |
|
323 | - $Value[$K]['encoding'] = 'uri'; |
|
324 | - } |
|
325 | - } |
|
326 | - return $Value; |
|
327 | - } |
|
328 | - |
|
329 | - if ($this -> Options['Collapse'] && is_array($this -> Data[$Key]) && (count($this -> Data[$Key]) == 1)) |
|
330 | - { |
|
331 | - return $this -> Data[$Key][0]; |
|
332 | - } |
|
333 | - return $this -> Data[$Key]; |
|
334 | - } |
|
335 | - elseif ($Key == 'Mode') |
|
336 | - { |
|
337 | - return $this -> Mode; |
|
338 | - } |
|
339 | - return array(); |
|
340 | - } |
|
341 | - |
|
342 | - /** |
|
343 | - * Saves an embedded file |
|
344 | - * |
|
345 | - * @param string Key |
|
346 | - * @param int Index of the file, defaults to 0 |
|
347 | - * @param string Target path where the file should be saved, including the filename |
|
348 | - * |
|
349 | - * @return bool Operation status |
|
350 | - */ |
|
351 | - public function SaveFile($Key, $Index = 0, $TargetPath = '') |
|
352 | - { |
|
353 | - if (!isset($this -> Data[$Key])) |
|
354 | - { |
|
355 | - return false; |
|
356 | - } |
|
357 | - if (!isset($this -> Data[$Key][$Index])) |
|
358 | - { |
|
359 | - return false; |
|
360 | - } |
|
361 | - |
|
362 | - // Returing false if it is an image URL |
|
363 | - if (stripos($this -> Data[$Key][$Index]['value'], 'uri:') === 0) |
|
364 | - { |
|
365 | - return false; |
|
366 | - } |
|
367 | - |
|
368 | - if (is_writable($TargetPath) || (!file_exists($TargetPath) && is_writable(dirname($TargetPath)))) |
|
369 | - { |
|
370 | - $RawContent = $this -> Data[$Key][$Index]['value']; |
|
371 | - if (isset($this -> Data[$Key][$Index]['encoding']) && $this -> Data[$Key][$Index]['encoding'] == 'b') |
|
372 | - { |
|
373 | - $RawContent = base64_decode($RawContent); |
|
374 | - } |
|
375 | - $Status = file_put_contents($TargetPath, $RawContent); |
|
376 | - return (bool)$Status; |
|
377 | - } |
|
378 | - else |
|
379 | - { |
|
380 | - throw new Exception('vCard: Cannot save file ('.$Key.'), target path not writable ('.$TargetPath.')'); |
|
381 | - } |
|
382 | - return false; |
|
383 | - } |
|
384 | - |
|
385 | - /** |
|
386 | - * Magic method for adding data to the vCard |
|
387 | - * |
|
388 | - * @param string Key |
|
389 | - * @param string Method call arguments. First element is value. |
|
390 | - * |
|
391 | - * @return vCard Current object for method chaining |
|
392 | - */ |
|
393 | - public function __call($Key, $Arguments) |
|
394 | - { |
|
395 | - $Key = strtolower($Key); |
|
396 | - |
|
397 | - if (!isset($this -> Data[$Key])) |
|
398 | - { |
|
399 | - $this -> Data[$Key] = array(); |
|
400 | - } |
|
401 | - |
|
402 | - $Value = isset($Arguments[0]) ? $Arguments[0] : false; |
|
403 | - |
|
404 | - if (count($Arguments) > 1) |
|
405 | - { |
|
406 | - $Types = array_map('strtolower', array_values(array_slice($Arguments, 1))); |
|
407 | - |
|
408 | - if (isset(self::$Spec_StructuredElements[$Key]) && |
|
409 | - in_array(strtolower($Arguments[1]), self::$Spec_StructuredElements[$Key]) |
|
410 | - ) |
|
411 | - { |
|
412 | - $LastElementIndex = 0; |
|
413 | - |
|
414 | - if (count($this -> Data[$Key])) |
|
415 | - { |
|
416 | - $LastElementIndex = count($this -> Data[$Key]) - 1; |
|
417 | - } |
|
418 | - |
|
419 | - if (isset($this -> Data[$Key][$LastElementIndex])) |
|
420 | - { |
|
421 | - if (empty($this -> Data[$Key][$LastElementIndex][$Types[0]])) |
|
422 | - { |
|
423 | - $this -> Data[$Key][$LastElementIndex][$Types[0]] = $Value; |
|
424 | - } |
|
425 | - else |
|
426 | - { |
|
427 | - $LastElementIndex++; |
|
428 | - } |
|
429 | - } |
|
430 | - |
|
431 | - if (!isset($this -> Data[$Key][$LastElementIndex])) |
|
432 | - { |
|
433 | - $this -> Data[$Key][$LastElementIndex] = array( |
|
434 | - $Types[0] => $Value |
|
435 | - ); |
|
436 | - } |
|
437 | - } |
|
438 | - elseif (isset(self::$Spec_ElementTypes[$Key])) |
|
439 | - { |
|
440 | - $this -> Data[$Key][] = array( |
|
441 | - 'value' => $Value, |
|
442 | - 'type' => $Types |
|
443 | - ); |
|
444 | - } |
|
445 | - } |
|
446 | - elseif ($Value) |
|
447 | - { |
|
448 | - $this -> Data[$Key][] = $Value; |
|
449 | - } |
|
450 | - |
|
451 | - return $this; |
|
452 | - } |
|
453 | - |
|
454 | - /** |
|
455 | - * Magic method for getting vCard content out |
|
456 | - * |
|
457 | - * @return string Raw vCard content |
|
458 | - */ |
|
459 | - public function __toString() |
|
460 | - { |
|
461 | - $Text = 'BEGIN:VCARD'.self::endl; |
|
462 | - $Text .= 'VERSION:3.0'.self::endl; |
|
463 | - |
|
464 | - foreach ($this -> Data as $Key => $Values) |
|
465 | - { |
|
466 | - $KeyUC = strtoupper($Key); |
|
467 | - $Key = strtolower($Key); |
|
468 | - |
|
469 | - if (in_array($KeyUC, array('PHOTO', 'VERSION'))) |
|
470 | - { |
|
471 | - continue; |
|
472 | - } |
|
473 | - |
|
474 | - foreach ($Values as $Index => $Value) |
|
475 | - { |
|
476 | - $Text .= $KeyUC; |
|
477 | - if (is_array($Value) && isset($Value['type'])) |
|
478 | - { |
|
479 | - $Text .= ';TYPE='.self::PrepareTypeStrForOutput($Value['type']); |
|
480 | - } |
|
481 | - $Text .= ':'; |
|
482 | - |
|
483 | - if (isset(self::$Spec_StructuredElements[$Key])) |
|
484 | - { |
|
485 | - $PartArray = array(); |
|
486 | - foreach (self::$Spec_StructuredElements[$Key] as $Part) |
|
487 | - { |
|
488 | - $PartArray[] = isset($Value[$Part]) ? $Value[$Part] : ''; |
|
489 | - } |
|
490 | - $Text .= implode(';', $PartArray); |
|
491 | - } |
|
492 | - elseif (is_array($Value) && isset(self::$Spec_ElementTypes[$Key])) |
|
493 | - { |
|
494 | - $Text .= $Value['value']; |
|
495 | - } |
|
496 | - else |
|
497 | - { |
|
498 | - $Text .= $Value; |
|
499 | - } |
|
500 | - |
|
501 | - $Text .= self::endl; |
|
502 | - } |
|
503 | - } |
|
504 | - |
|
505 | - $Text .= 'END:VCARD'.self::endl; |
|
506 | - return $Text; |
|
507 | - } |
|
508 | - |
|
509 | - // !Helper methods |
|
510 | - |
|
511 | - private static function PrepareTypeStrForOutput($Type) |
|
512 | - { |
|
513 | - return implode(',', array_map('strtoupper', $Type)); |
|
514 | - } |
|
515 | - |
|
516 | - /** |
|
517 | - * Removes the escaping slashes from the text. |
|
518 | - * |
|
519 | - * @access private |
|
520 | - * |
|
521 | - * @param string Text to prepare. |
|
522 | - * |
|
523 | - * @return string Resulting text. |
|
524 | - */ |
|
525 | - private static function Unescape($Text) |
|
526 | - { |
|
527 | - return str_replace(array('\:', '\;', '\,', "\n"), array(':', ';', ',', ''), $Text); |
|
528 | - } |
|
529 | - |
|
530 | - /** |
|
531 | - * Separates the various parts of a structured value according to the spec. |
|
532 | - * |
|
533 | - * @access private |
|
534 | - * |
|
535 | - * @param string Raw text string |
|
536 | - * @param string Key (e.g., N, ADR, ORG, etc.) |
|
537 | - * |
|
538 | - * @return array Parts in an associative array. |
|
539 | - */ |
|
540 | - private static function ParseStructuredValue($Text, $Key) |
|
541 | - { |
|
542 | - $Text = array_map('trim', explode(';', $Text)); |
|
543 | - |
|
544 | - $Result = array(); |
|
545 | - $Ctr = 0; |
|
546 | - |
|
547 | - foreach (self::$Spec_StructuredElements[$Key] as $Index => $StructurePart) |
|
548 | - { |
|
549 | - $Result[$StructurePart] = isset($Text[$Index]) ? $Text[$Index] : null; |
|
550 | - } |
|
551 | - return $Result; |
|
552 | - } |
|
553 | - |
|
554 | - /** |
|
555 | - * @access private |
|
556 | - */ |
|
557 | - private static function ParseMultipleTextValue($Text) |
|
558 | - { |
|
559 | - return explode(',', $Text); |
|
560 | - } |
|
561 | - |
|
562 | - /** |
|
563 | - * @access private |
|
564 | - */ |
|
565 | - private static function ParseParameters($Key, array $RawParams = null) |
|
566 | - { |
|
567 | - if (!$RawParams) |
|
568 | - { |
|
569 | - return array(); |
|
570 | - } |
|
571 | - |
|
572 | - // Parameters are split into (key, value) pairs |
|
573 | - $Parameters = array(); |
|
574 | - foreach ($RawParams as $Item) |
|
575 | - { |
|
576 | - $Parameters[] = explode('=', strtolower($Item)); |
|
577 | - } |
|
578 | - |
|
579 | - $Type = array(); |
|
580 | - $Result = array(); |
|
581 | - |
|
582 | - // And each parameter is checked whether anything can/should be done because of it |
|
583 | - foreach ($Parameters as $Index => $Parameter) |
|
584 | - { |
|
585 | - // Skipping empty elements |
|
586 | - if (!$Parameter) |
|
587 | - { |
|
588 | - continue; |
|
589 | - } |
|
590 | - |
|
591 | - // Handling type parameters without the explicit TYPE parameter name (2.1 valid) |
|
592 | - if (count($Parameter) == 1) |
|
593 | - { |
|
594 | - // Checks if the type value is allowed for the specific element |
|
595 | - // The second part of the "if" statement means that email elements can have non-standard types (see the spec) |
|
596 | - if ( |
|
597 | - (isset(self::$Spec_ElementTypes[$Key]) && in_array($Parameter[0], self::$Spec_ElementTypes[$Key])) || |
|
598 | - ($Key == 'email' && is_scalar($Parameter[0])) |
|
599 | - ) |
|
600 | - { |
|
601 | - $Type[] = $Parameter[0]; |
|
602 | - } |
|
603 | - } |
|
604 | - elseif (count($Parameter) > 2) |
|
605 | - { |
|
606 | - if(count(explode(',', $RawParams[$Index], -1)) > 0) |
|
607 | - { |
|
608 | - $TempTypeParams = self::ParseParameters($Key, explode(',', $RawParams[$Index])); |
|
609 | - if ($TempTypeParams['type']) |
|
610 | - { |
|
611 | - $Type = array_merge($Type, $TempTypeParams['type']); |
|
612 | - } |
|
613 | - } |
|
614 | - } |
|
615 | - else |
|
616 | - { |
|
617 | - switch ($Parameter[0]) |
|
618 | - { |
|
619 | - case 'encoding': |
|
620 | - if (in_array($Parameter[1], array('quoted-printable', 'b', 'base64'))) |
|
621 | - { |
|
622 | - $Result['encoding'] = $Parameter[1] == 'base64' ? 'b' : $Parameter[1]; |
|
623 | - } |
|
624 | - break; |
|
625 | - case 'charset': |
|
626 | - $Result['charset'] = $Parameter[1]; |
|
627 | - break; |
|
628 | - case 'type': |
|
629 | - $Type = array_merge($Type, explode(',', $Parameter[1])); |
|
630 | - break; |
|
631 | - case 'value': |
|
632 | - if (strtolower($Parameter[1]) == 'url') |
|
633 | - { |
|
634 | - $Result['encoding'] = 'uri'; |
|
635 | - } |
|
636 | - break; |
|
637 | - } |
|
638 | - } |
|
639 | - } |
|
640 | - |
|
641 | - $Result['type'] = $Type; |
|
642 | - |
|
643 | - return $Result; |
|
644 | - } |
|
645 | - |
|
646 | - // !Interface methods |
|
647 | - |
|
648 | - // Countable interface |
|
649 | - public function count() |
|
650 | - { |
|
651 | - switch ($this -> Mode) |
|
652 | - { |
|
653 | - case self::MODE_ERROR: |
|
654 | - return 0; |
|
655 | - break; |
|
656 | - case self::MODE_SINGLE: |
|
657 | - return 1; |
|
658 | - break; |
|
659 | - case self::MODE_MULTIPLE: |
|
660 | - return count($this -> Data); |
|
661 | - break; |
|
662 | - } |
|
663 | - return 0; |
|
664 | - } |
|
665 | - |
|
666 | - // Iterator interface |
|
667 | - public function rewind() |
|
668 | - { |
|
669 | - reset($this -> Data); |
|
670 | - } |
|
671 | - |
|
672 | - public function current() |
|
673 | - { |
|
674 | - return current($this -> Data); |
|
675 | - } |
|
676 | - |
|
677 | - public function next() |
|
678 | - { |
|
679 | - return next($this -> Data); |
|
680 | - } |
|
681 | - |
|
682 | - public function valid() |
|
683 | - { |
|
684 | - return ($this -> current() !== false); |
|
685 | - } |
|
686 | - |
|
687 | - public function key() |
|
688 | - { |
|
689 | - return key($this -> Data); |
|
690 | - } |
|
691 | - } |
|
10 | + class vCard implements Countable, Iterator |
|
11 | + { |
|
12 | + const MODE_ERROR = 'error'; |
|
13 | + const MODE_SINGLE = 'single'; |
|
14 | + const MODE_MULTIPLE = 'multiple'; |
|
15 | + |
|
16 | + const endl = "\n"; |
|
17 | + |
|
18 | + /** |
|
19 | + * @var string Current object mode - error, single or multiple (for a single vCard within a file and multiple combined vCards) |
|
20 | + */ |
|
21 | + private $Mode; //single, multiple, error |
|
22 | + |
|
23 | + private $Path = ''; |
|
24 | + private $RawData = ''; |
|
25 | + |
|
26 | + /** |
|
27 | + * @var array Internal options container. Options: |
|
28 | + * bool Collapse: If true, elements that can have multiple values but have only a single value are returned as that value instead of an array |
|
29 | + * If false, an array is returned even if it has only one value. |
|
30 | + */ |
|
31 | + private $Options = array( |
|
32 | + 'Collapse' => false |
|
33 | + ); |
|
34 | + |
|
35 | + /** |
|
36 | + * @var array Internal data container. Contains vCard objects for multiple vCards and just the data for single vCards. |
|
37 | + */ |
|
38 | + private $Data = array(); |
|
39 | + |
|
40 | + /** |
|
41 | + * @static Parts of structured elements according to the spec. |
|
42 | + */ |
|
43 | + private static $Spec_StructuredElements = array( |
|
44 | + 'n' => array('lastname', 'firstname', 'additionalnames', 'prefixes', 'suffixes'), |
|
45 | + 'adr' => array('pobox', 'extendedaddress', 'streetaddress', 'locality', 'region', 'postalcode', 'country'), |
|
46 | + 'geo' => array('latitude', 'longitude'), |
|
47 | + 'org' => array('name', 'unit1', 'unit2') |
|
48 | + ); |
|
49 | + private static $Spec_MultipleValueElements = array('nickname', 'categories'); |
|
50 | + |
|
51 | + private static $Spec_ElementTypes = array( |
|
52 | + 'email' => array('internet', 'x400', 'pref', 'home', 'work'), |
|
53 | + 'adr' => array('dom', 'intl', 'postal', 'parcel', 'home', 'work', 'pref'), |
|
54 | + 'label' => array('dom', 'intl', 'postal', 'parcel', 'home', 'work', 'pref'), |
|
55 | + 'tel' => array('home', 'msg', 'work', 'pref', 'voice', 'fax', 'cell', 'video', 'pager', 'bbs', 'modem', 'car', 'isdn', 'pcs'), |
|
56 | + 'impp' => array('personal', 'business', 'home', 'work', 'mobile', 'pref') |
|
57 | + ); |
|
58 | + |
|
59 | + private static $Spec_FileElements = array('photo', 'logo', 'sound'); |
|
60 | + |
|
61 | + /** |
|
62 | + * vCard constructor |
|
63 | + * |
|
64 | + * @param string Path to file, optional. |
|
65 | + * @param string Raw data, optional. |
|
66 | + * @param array Additional options, optional. Currently supported options: |
|
67 | + * bool Collapse: If true, elements that can have multiple values but have only a single value are returned as that value instead of an array |
|
68 | + * If false, an array is returned even if it has only one value. |
|
69 | + * |
|
70 | + * One of these parameters must be provided, otherwise an exception is thrown. |
|
71 | + */ |
|
72 | + public function __construct($Path = false, $RawData = false, array $Options = null) |
|
73 | + { |
|
74 | + // Checking preconditions for the parser. |
|
75 | + // If path is given, the file should be accessible. |
|
76 | + // If raw data is given, it is taken as it is. |
|
77 | + // In both cases the real content is put in $this -> RawData |
|
78 | + if ($Path) |
|
79 | + { |
|
80 | + if (!is_readable($Path)) |
|
81 | + { |
|
82 | + throw new Exception('vCard: Path not accessible ('.$Path.')'); |
|
83 | + } |
|
84 | + |
|
85 | + $this -> Path = $Path; |
|
86 | + $this -> RawData = file_get_contents($this -> Path); |
|
87 | + } |
|
88 | + elseif ($RawData) |
|
89 | + { |
|
90 | + $this -> RawData = $RawData; |
|
91 | + } |
|
92 | + else |
|
93 | + { |
|
94 | + //throw new Exception('vCard: No content provided'); |
|
95 | + // Not necessary anymore as possibility to create vCards is added |
|
96 | + } |
|
97 | + |
|
98 | + if (!$this -> Path && !$this -> RawData) |
|
99 | + { |
|
100 | + return true; |
|
101 | + } |
|
102 | + |
|
103 | + if ($Options) |
|
104 | + { |
|
105 | + $this -> Options = array_merge($this -> Options, $Options); |
|
106 | + } |
|
107 | + |
|
108 | + // Counting the begin/end separators. If there aren't any or the count doesn't match, there is a problem with the file. |
|
109 | + // If there is only one, this is a single vCard, if more, multiple vCards are combined. |
|
110 | + $Matches = array(); |
|
111 | + $vCardBeginCount = preg_match_all('{^BEGIN\:VCARD}miS', $this -> RawData, $Matches); |
|
112 | + $vCardEndCount = preg_match_all('{^END\:VCARD}miS', $this -> RawData, $Matches); |
|
113 | + |
|
114 | + if (($vCardBeginCount != $vCardEndCount) || !$vCardBeginCount) |
|
115 | + { |
|
116 | + $this -> Mode = vCard::MODE_ERROR; |
|
117 | + throw new Exception('vCard: invalid vCard'); |
|
118 | + } |
|
119 | + |
|
120 | + $this -> Mode = $vCardBeginCount == 1 ? vCard::MODE_SINGLE : vCard::MODE_MULTIPLE; |
|
121 | + |
|
122 | + // Removing/changing inappropriate newlines, i.e., all CRs or multiple newlines are changed to a single newline |
|
123 | + $this -> RawData = str_replace("\r", "\n", $this -> RawData); |
|
124 | + $this -> RawData = preg_replace('{(\n+)}', "\n", $this -> RawData); |
|
125 | + |
|
126 | + // In multiple card mode the raw text is split at card beginning markers and each |
|
127 | + // fragment is parsed in a separate vCard object. |
|
128 | + if ($this -> Mode == self::MODE_MULTIPLE) |
|
129 | + { |
|
130 | + $this -> RawData = explode('BEGIN:VCARD', $this -> RawData); |
|
131 | + $this -> RawData = array_filter($this -> RawData); |
|
132 | + |
|
133 | + foreach ($this -> RawData as $SinglevCardRawData) |
|
134 | + { |
|
135 | + // Prepending "BEGIN:VCARD" to the raw string because we exploded on that one. |
|
136 | + // If there won't be the BEGIN marker in the new object, it will fail. |
|
137 | + $SinglevCardRawData = 'BEGIN:VCARD'."\n".$SinglevCardRawData; |
|
138 | + |
|
139 | + $ClassName = get_class($this); |
|
140 | + $this -> Data[] = new $ClassName(false, $SinglevCardRawData); |
|
141 | + } |
|
142 | + } |
|
143 | + else |
|
144 | + { |
|
145 | + // Protect the BASE64 final = sign (detected by the line beginning with whitespace), otherwise the next replace will get rid of it |
|
146 | + $this -> RawData = preg_replace('{(\n\s.+)=(\n)}', '$1-base64=-$2', $this -> RawData); |
|
147 | + |
|
148 | + // Joining multiple lines that are split with a hard wrap and indicated by an equals sign at the end of line |
|
149 | + // (quoted-printable-encoded values in v2.1 vCards) |
|
150 | + $this -> RawData = str_replace("=\n", '', $this -> RawData); |
|
151 | + |
|
152 | + // Joining multiple lines that are split with a soft wrap (space or tab on the beginning of the next line |
|
153 | + $this -> RawData = str_replace(array("\n ", "\n\t"), '-wrap-', $this -> RawData); |
|
154 | + |
|
155 | + // Restoring the BASE64 final equals sign (see a few lines above) |
|
156 | + $this -> RawData = str_replace("-base64=-\n", "=\n", $this -> RawData); |
|
157 | + |
|
158 | + $Lines = explode("\n", $this -> RawData); |
|
159 | + |
|
160 | + foreach ($Lines as $Line) |
|
161 | + { |
|
162 | + // Lines without colons are skipped because, most likely, they contain no data. |
|
163 | + if (strpos($Line, ':') === false) |
|
164 | + { |
|
165 | + continue; |
|
166 | + } |
|
167 | + |
|
168 | + // Each line is split into two parts. The key contains the element name and additional parameters, if present, |
|
169 | + // value is just the value |
|
170 | + list($Key, $Value) = explode(':', $Line, 2); |
|
171 | + |
|
172 | + // Key is transformed to lowercase because, even though the element and parameter names are written in uppercase, |
|
173 | + // it is quite possible that they will be in lower- or mixed case. |
|
174 | + // The key is trimmed to allow for non-significant WSP characters as allowed by v2.1 |
|
175 | + $Key = strtolower(trim(self::Unescape($Key))); |
|
176 | + |
|
177 | + // These two lines can be skipped as they aren't necessary at all. |
|
178 | + if ($Key == 'begin' || $Key == 'end') |
|
179 | + { |
|
180 | + continue; |
|
181 | + } |
|
182 | + |
|
183 | + if ((strpos($Key, 'agent') === 0) && (stripos($Value, 'begin:vcard') !== false)) |
|
184 | + { |
|
185 | + $ClassName = get_class($this); |
|
186 | + $Value = new $ClassName(false, str_replace('-wrap-', "\n", $Value)); |
|
187 | + if (!isset($this -> Data[$Key])) |
|
188 | + { |
|
189 | + $this -> Data[$Key] = array(); |
|
190 | + } |
|
191 | + $this -> Data[$Key][] = $Value; |
|
192 | + continue; |
|
193 | + } |
|
194 | + else |
|
195 | + { |
|
196 | + $Value = str_replace('-wrap-', '', $Value); |
|
197 | + } |
|
198 | + |
|
199 | + $Value = trim(self::Unescape($Value)); |
|
200 | + $Type = array(); |
|
201 | + |
|
202 | + // Here additional parameters are parsed |
|
203 | + $KeyParts = explode(';', $Key); |
|
204 | + $Key = $KeyParts[0]; |
|
205 | + $Encoding = false; |
|
206 | + |
|
207 | + if (strpos($Key, 'item') === 0) |
|
208 | + { |
|
209 | + $TmpKey = explode('.', $Key, 2); |
|
210 | + $Key = $TmpKey[1]; |
|
211 | + $ItemIndex = (int)str_ireplace('item', '', $TmpKey[0]); |
|
212 | + } |
|
213 | + |
|
214 | + if (count($KeyParts) > 1) |
|
215 | + { |
|
216 | + $Parameters = self::ParseParameters($Key, array_slice($KeyParts, 1)); |
|
217 | + |
|
218 | + foreach ($Parameters as $ParamKey => $ParamValue) |
|
219 | + { |
|
220 | + switch ($ParamKey) |
|
221 | + { |
|
222 | + case 'encoding': |
|
223 | + $Encoding = $ParamValue; |
|
224 | + if (in_array($ParamValue, array('b', 'base64'))) |
|
225 | + { |
|
226 | + //$Value = base64_decode($Value); |
|
227 | + } |
|
228 | + elseif ($ParamValue == 'quoted-printable') // v2.1 |
|
229 | + { |
|
230 | + $Value = quoted_printable_decode($Value); |
|
231 | + } |
|
232 | + break; |
|
233 | + case 'charset': // v2.1 |
|
234 | + if ($ParamValue != 'utf-8' && $ParamValue != 'utf8') |
|
235 | + { |
|
236 | + $Value = mb_convert_encoding($Value, 'UTF-8', $ParamValue); |
|
237 | + } |
|
238 | + break; |
|
239 | + case 'type': |
|
240 | + $Type = $ParamValue; |
|
241 | + break; |
|
242 | + } |
|
243 | + } |
|
244 | + } |
|
245 | + |
|
246 | + // Checking files for colon-separated additional parameters (Apple's Address Book does this), for example, "X-ABCROP-RECTANGLE" for photos |
|
247 | + if (in_array($Key, self::$Spec_FileElements) && isset($Parameters['encoding']) && in_array($Parameters['encoding'], array('b', 'base64'))) |
|
248 | + { |
|
249 | + // If colon is present in the value, it must contain Address Book parameters |
|
250 | + // (colon is an invalid character for base64 so it shouldn't appear in valid files) |
|
251 | + if (strpos($Value, ':') !== false) |
|
252 | + { |
|
253 | + $Value = explode(':', $Value); |
|
254 | + $Value = array_pop($Value); |
|
255 | + } |
|
256 | + } |
|
257 | + |
|
258 | + // Values are parsed according to their type |
|
259 | + if (isset(self::$Spec_StructuredElements[$Key])) |
|
260 | + { |
|
261 | + $Value = self::ParseStructuredValue($Value, $Key); |
|
262 | + if ($Type) |
|
263 | + { |
|
264 | + $Value['type'] = $Type; |
|
265 | + } |
|
266 | + } |
|
267 | + else |
|
268 | + { |
|
269 | + if (in_array($Key, self::$Spec_MultipleValueElements)) |
|
270 | + { |
|
271 | + $Value = self::ParseMultipleTextValue($Value, $Key); |
|
272 | + } |
|
273 | + |
|
274 | + if ($Type) |
|
275 | + { |
|
276 | + $Value = array( |
|
277 | + 'value' => $Value, |
|
278 | + 'type' => $Type |
|
279 | + ); |
|
280 | + } |
|
281 | + } |
|
282 | + |
|
283 | + if (is_array($Value) && $Encoding) |
|
284 | + { |
|
285 | + $Value['encoding'] = $Encoding; |
|
286 | + } |
|
287 | + |
|
288 | + if (!isset($this -> Data[$Key])) |
|
289 | + { |
|
290 | + $this -> Data[$Key] = array(); |
|
291 | + } |
|
292 | + |
|
293 | + $this -> Data[$Key][] = $Value; |
|
294 | + } |
|
295 | + } |
|
296 | + } |
|
297 | + |
|
298 | + /** |
|
299 | + * Magic method to get the various vCard values as object members, e.g. |
|
300 | + * a call to $vCard -> N gets the "N" value |
|
301 | + * |
|
302 | + * @param string Key |
|
303 | + * |
|
304 | + * @return mixed Value |
|
305 | + */ |
|
306 | + public function __get($Key) |
|
307 | + { |
|
308 | + $Key = strtolower($Key); |
|
309 | + if (isset($this -> Data[$Key])) |
|
310 | + { |
|
311 | + if ($Key == 'agent') |
|
312 | + { |
|
313 | + return $this -> Data[$Key]; |
|
314 | + } |
|
315 | + elseif (in_array($Key, self::$Spec_FileElements)) |
|
316 | + { |
|
317 | + $Value = $this -> Data[$Key]; |
|
318 | + foreach ($Value as $K => $V) |
|
319 | + { |
|
320 | + if (stripos($V['value'], 'uri:') === 0) |
|
321 | + { |
|
322 | + $Value[$K]['value'] = substr($V, 4); |
|
323 | + $Value[$K]['encoding'] = 'uri'; |
|
324 | + } |
|
325 | + } |
|
326 | + return $Value; |
|
327 | + } |
|
328 | + |
|
329 | + if ($this -> Options['Collapse'] && is_array($this -> Data[$Key]) && (count($this -> Data[$Key]) == 1)) |
|
330 | + { |
|
331 | + return $this -> Data[$Key][0]; |
|
332 | + } |
|
333 | + return $this -> Data[$Key]; |
|
334 | + } |
|
335 | + elseif ($Key == 'Mode') |
|
336 | + { |
|
337 | + return $this -> Mode; |
|
338 | + } |
|
339 | + return array(); |
|
340 | + } |
|
341 | + |
|
342 | + /** |
|
343 | + * Saves an embedded file |
|
344 | + * |
|
345 | + * @param string Key |
|
346 | + * @param int Index of the file, defaults to 0 |
|
347 | + * @param string Target path where the file should be saved, including the filename |
|
348 | + * |
|
349 | + * @return bool Operation status |
|
350 | + */ |
|
351 | + public function SaveFile($Key, $Index = 0, $TargetPath = '') |
|
352 | + { |
|
353 | + if (!isset($this -> Data[$Key])) |
|
354 | + { |
|
355 | + return false; |
|
356 | + } |
|
357 | + if (!isset($this -> Data[$Key][$Index])) |
|
358 | + { |
|
359 | + return false; |
|
360 | + } |
|
361 | + |
|
362 | + // Returing false if it is an image URL |
|
363 | + if (stripos($this -> Data[$Key][$Index]['value'], 'uri:') === 0) |
|
364 | + { |
|
365 | + return false; |
|
366 | + } |
|
367 | + |
|
368 | + if (is_writable($TargetPath) || (!file_exists($TargetPath) && is_writable(dirname($TargetPath)))) |
|
369 | + { |
|
370 | + $RawContent = $this -> Data[$Key][$Index]['value']; |
|
371 | + if (isset($this -> Data[$Key][$Index]['encoding']) && $this -> Data[$Key][$Index]['encoding'] == 'b') |
|
372 | + { |
|
373 | + $RawContent = base64_decode($RawContent); |
|
374 | + } |
|
375 | + $Status = file_put_contents($TargetPath, $RawContent); |
|
376 | + return (bool)$Status; |
|
377 | + } |
|
378 | + else |
|
379 | + { |
|
380 | + throw new Exception('vCard: Cannot save file ('.$Key.'), target path not writable ('.$TargetPath.')'); |
|
381 | + } |
|
382 | + return false; |
|
383 | + } |
|
384 | + |
|
385 | + /** |
|
386 | + * Magic method for adding data to the vCard |
|
387 | + * |
|
388 | + * @param string Key |
|
389 | + * @param string Method call arguments. First element is value. |
|
390 | + * |
|
391 | + * @return vCard Current object for method chaining |
|
392 | + */ |
|
393 | + public function __call($Key, $Arguments) |
|
394 | + { |
|
395 | + $Key = strtolower($Key); |
|
396 | + |
|
397 | + if (!isset($this -> Data[$Key])) |
|
398 | + { |
|
399 | + $this -> Data[$Key] = array(); |
|
400 | + } |
|
401 | + |
|
402 | + $Value = isset($Arguments[0]) ? $Arguments[0] : false; |
|
403 | + |
|
404 | + if (count($Arguments) > 1) |
|
405 | + { |
|
406 | + $Types = array_map('strtolower', array_values(array_slice($Arguments, 1))); |
|
407 | + |
|
408 | + if (isset(self::$Spec_StructuredElements[$Key]) && |
|
409 | + in_array(strtolower($Arguments[1]), self::$Spec_StructuredElements[$Key]) |
|
410 | + ) |
|
411 | + { |
|
412 | + $LastElementIndex = 0; |
|
413 | + |
|
414 | + if (count($this -> Data[$Key])) |
|
415 | + { |
|
416 | + $LastElementIndex = count($this -> Data[$Key]) - 1; |
|
417 | + } |
|
418 | + |
|
419 | + if (isset($this -> Data[$Key][$LastElementIndex])) |
|
420 | + { |
|
421 | + if (empty($this -> Data[$Key][$LastElementIndex][$Types[0]])) |
|
422 | + { |
|
423 | + $this -> Data[$Key][$LastElementIndex][$Types[0]] = $Value; |
|
424 | + } |
|
425 | + else |
|
426 | + { |
|
427 | + $LastElementIndex++; |
|
428 | + } |
|
429 | + } |
|
430 | + |
|
431 | + if (!isset($this -> Data[$Key][$LastElementIndex])) |
|
432 | + { |
|
433 | + $this -> Data[$Key][$LastElementIndex] = array( |
|
434 | + $Types[0] => $Value |
|
435 | + ); |
|
436 | + } |
|
437 | + } |
|
438 | + elseif (isset(self::$Spec_ElementTypes[$Key])) |
|
439 | + { |
|
440 | + $this -> Data[$Key][] = array( |
|
441 | + 'value' => $Value, |
|
442 | + 'type' => $Types |
|
443 | + ); |
|
444 | + } |
|
445 | + } |
|
446 | + elseif ($Value) |
|
447 | + { |
|
448 | + $this -> Data[$Key][] = $Value; |
|
449 | + } |
|
450 | + |
|
451 | + return $this; |
|
452 | + } |
|
453 | + |
|
454 | + /** |
|
455 | + * Magic method for getting vCard content out |
|
456 | + * |
|
457 | + * @return string Raw vCard content |
|
458 | + */ |
|
459 | + public function __toString() |
|
460 | + { |
|
461 | + $Text = 'BEGIN:VCARD'.self::endl; |
|
462 | + $Text .= 'VERSION:3.0'.self::endl; |
|
463 | + |
|
464 | + foreach ($this -> Data as $Key => $Values) |
|
465 | + { |
|
466 | + $KeyUC = strtoupper($Key); |
|
467 | + $Key = strtolower($Key); |
|
468 | + |
|
469 | + if (in_array($KeyUC, array('PHOTO', 'VERSION'))) |
|
470 | + { |
|
471 | + continue; |
|
472 | + } |
|
473 | + |
|
474 | + foreach ($Values as $Index => $Value) |
|
475 | + { |
|
476 | + $Text .= $KeyUC; |
|
477 | + if (is_array($Value) && isset($Value['type'])) |
|
478 | + { |
|
479 | + $Text .= ';TYPE='.self::PrepareTypeStrForOutput($Value['type']); |
|
480 | + } |
|
481 | + $Text .= ':'; |
|
482 | + |
|
483 | + if (isset(self::$Spec_StructuredElements[$Key])) |
|
484 | + { |
|
485 | + $PartArray = array(); |
|
486 | + foreach (self::$Spec_StructuredElements[$Key] as $Part) |
|
487 | + { |
|
488 | + $PartArray[] = isset($Value[$Part]) ? $Value[$Part] : ''; |
|
489 | + } |
|
490 | + $Text .= implode(';', $PartArray); |
|
491 | + } |
|
492 | + elseif (is_array($Value) && isset(self::$Spec_ElementTypes[$Key])) |
|
493 | + { |
|
494 | + $Text .= $Value['value']; |
|
495 | + } |
|
496 | + else |
|
497 | + { |
|
498 | + $Text .= $Value; |
|
499 | + } |
|
500 | + |
|
501 | + $Text .= self::endl; |
|
502 | + } |
|
503 | + } |
|
504 | + |
|
505 | + $Text .= 'END:VCARD'.self::endl; |
|
506 | + return $Text; |
|
507 | + } |
|
508 | + |
|
509 | + // !Helper methods |
|
510 | + |
|
511 | + private static function PrepareTypeStrForOutput($Type) |
|
512 | + { |
|
513 | + return implode(',', array_map('strtoupper', $Type)); |
|
514 | + } |
|
515 | + |
|
516 | + /** |
|
517 | + * Removes the escaping slashes from the text. |
|
518 | + * |
|
519 | + * @access private |
|
520 | + * |
|
521 | + * @param string Text to prepare. |
|
522 | + * |
|
523 | + * @return string Resulting text. |
|
524 | + */ |
|
525 | + private static function Unescape($Text) |
|
526 | + { |
|
527 | + return str_replace(array('\:', '\;', '\,', "\n"), array(':', ';', ',', ''), $Text); |
|
528 | + } |
|
529 | + |
|
530 | + /** |
|
531 | + * Separates the various parts of a structured value according to the spec. |
|
532 | + * |
|
533 | + * @access private |
|
534 | + * |
|
535 | + * @param string Raw text string |
|
536 | + * @param string Key (e.g., N, ADR, ORG, etc.) |
|
537 | + * |
|
538 | + * @return array Parts in an associative array. |
|
539 | + */ |
|
540 | + private static function ParseStructuredValue($Text, $Key) |
|
541 | + { |
|
542 | + $Text = array_map('trim', explode(';', $Text)); |
|
543 | + |
|
544 | + $Result = array(); |
|
545 | + $Ctr = 0; |
|
546 | + |
|
547 | + foreach (self::$Spec_StructuredElements[$Key] as $Index => $StructurePart) |
|
548 | + { |
|
549 | + $Result[$StructurePart] = isset($Text[$Index]) ? $Text[$Index] : null; |
|
550 | + } |
|
551 | + return $Result; |
|
552 | + } |
|
553 | + |
|
554 | + /** |
|
555 | + * @access private |
|
556 | + */ |
|
557 | + private static function ParseMultipleTextValue($Text) |
|
558 | + { |
|
559 | + return explode(',', $Text); |
|
560 | + } |
|
561 | + |
|
562 | + /** |
|
563 | + * @access private |
|
564 | + */ |
|
565 | + private static function ParseParameters($Key, array $RawParams = null) |
|
566 | + { |
|
567 | + if (!$RawParams) |
|
568 | + { |
|
569 | + return array(); |
|
570 | + } |
|
571 | + |
|
572 | + // Parameters are split into (key, value) pairs |
|
573 | + $Parameters = array(); |
|
574 | + foreach ($RawParams as $Item) |
|
575 | + { |
|
576 | + $Parameters[] = explode('=', strtolower($Item)); |
|
577 | + } |
|
578 | + |
|
579 | + $Type = array(); |
|
580 | + $Result = array(); |
|
581 | + |
|
582 | + // And each parameter is checked whether anything can/should be done because of it |
|
583 | + foreach ($Parameters as $Index => $Parameter) |
|
584 | + { |
|
585 | + // Skipping empty elements |
|
586 | + if (!$Parameter) |
|
587 | + { |
|
588 | + continue; |
|
589 | + } |
|
590 | + |
|
591 | + // Handling type parameters without the explicit TYPE parameter name (2.1 valid) |
|
592 | + if (count($Parameter) == 1) |
|
593 | + { |
|
594 | + // Checks if the type value is allowed for the specific element |
|
595 | + // The second part of the "if" statement means that email elements can have non-standard types (see the spec) |
|
596 | + if ( |
|
597 | + (isset(self::$Spec_ElementTypes[$Key]) && in_array($Parameter[0], self::$Spec_ElementTypes[$Key])) || |
|
598 | + ($Key == 'email' && is_scalar($Parameter[0])) |
|
599 | + ) |
|
600 | + { |
|
601 | + $Type[] = $Parameter[0]; |
|
602 | + } |
|
603 | + } |
|
604 | + elseif (count($Parameter) > 2) |
|
605 | + { |
|
606 | + if(count(explode(',', $RawParams[$Index], -1)) > 0) |
|
607 | + { |
|
608 | + $TempTypeParams = self::ParseParameters($Key, explode(',', $RawParams[$Index])); |
|
609 | + if ($TempTypeParams['type']) |
|
610 | + { |
|
611 | + $Type = array_merge($Type, $TempTypeParams['type']); |
|
612 | + } |
|
613 | + } |
|
614 | + } |
|
615 | + else |
|
616 | + { |
|
617 | + switch ($Parameter[0]) |
|
618 | + { |
|
619 | + case 'encoding': |
|
620 | + if (in_array($Parameter[1], array('quoted-printable', 'b', 'base64'))) |
|
621 | + { |
|
622 | + $Result['encoding'] = $Parameter[1] == 'base64' ? 'b' : $Parameter[1]; |
|
623 | + } |
|
624 | + break; |
|
625 | + case 'charset': |
|
626 | + $Result['charset'] = $Parameter[1]; |
|
627 | + break; |
|
628 | + case 'type': |
|
629 | + $Type = array_merge($Type, explode(',', $Parameter[1])); |
|
630 | + break; |
|
631 | + case 'value': |
|
632 | + if (strtolower($Parameter[1]) == 'url') |
|
633 | + { |
|
634 | + $Result['encoding'] = 'uri'; |
|
635 | + } |
|
636 | + break; |
|
637 | + } |
|
638 | + } |
|
639 | + } |
|
640 | + |
|
641 | + $Result['type'] = $Type; |
|
642 | + |
|
643 | + return $Result; |
|
644 | + } |
|
645 | + |
|
646 | + // !Interface methods |
|
647 | + |
|
648 | + // Countable interface |
|
649 | + public function count() |
|
650 | + { |
|
651 | + switch ($this -> Mode) |
|
652 | + { |
|
653 | + case self::MODE_ERROR: |
|
654 | + return 0; |
|
655 | + break; |
|
656 | + case self::MODE_SINGLE: |
|
657 | + return 1; |
|
658 | + break; |
|
659 | + case self::MODE_MULTIPLE: |
|
660 | + return count($this -> Data); |
|
661 | + break; |
|
662 | + } |
|
663 | + return 0; |
|
664 | + } |
|
665 | + |
|
666 | + // Iterator interface |
|
667 | + public function rewind() |
|
668 | + { |
|
669 | + reset($this -> Data); |
|
670 | + } |
|
671 | + |
|
672 | + public function current() |
|
673 | + { |
|
674 | + return current($this -> Data); |
|
675 | + } |
|
676 | + |
|
677 | + public function next() |
|
678 | + { |
|
679 | + return next($this -> Data); |
|
680 | + } |
|
681 | + |
|
682 | + public function valid() |
|
683 | + { |
|
684 | + return ($this -> current() !== false); |
|
685 | + } |
|
686 | + |
|
687 | + public function key() |
|
688 | + { |
|
689 | + return key($this -> Data); |
|
690 | + } |
|
691 | + } |
|
692 | 692 | ?> |
@@ -18,7 +18,7 @@ discard block |
||
18 | 18 | /** |
19 | 19 | * @var string Current object mode - error, single or multiple (for a single vCard within a file and multiple combined vCards) |
20 | 20 | */ |
21 | - private $Mode; //single, multiple, error |
|
21 | + private $Mode; //single, multiple, error |
|
22 | 22 | |
23 | 23 | private $Path = ''; |
24 | 24 | private $RawData = ''; |
@@ -79,7 +79,7 @@ discard block |
||
79 | 79 | { |
80 | 80 | if (!is_readable($Path)) |
81 | 81 | { |
82 | - throw new Exception('vCard: Path not accessible ('.$Path.')'); |
|
82 | + throw new Exception('vCard: Path not accessible (' . $Path . ')'); |
|
83 | 83 | } |
84 | 84 | |
85 | 85 | $this -> Path = $Path; |
@@ -134,7 +134,7 @@ discard block |
||
134 | 134 | { |
135 | 135 | // Prepending "BEGIN:VCARD" to the raw string because we exploded on that one. |
136 | 136 | // If there won't be the BEGIN marker in the new object, it will fail. |
137 | - $SinglevCardRawData = 'BEGIN:VCARD'."\n".$SinglevCardRawData; |
|
137 | + $SinglevCardRawData = 'BEGIN:VCARD' . "\n" . $SinglevCardRawData; |
|
138 | 138 | |
139 | 139 | $ClassName = get_class($this); |
140 | 140 | $this -> Data[] = new $ClassName(false, $SinglevCardRawData); |
@@ -377,7 +377,7 @@ discard block |
||
377 | 377 | } |
378 | 378 | else |
379 | 379 | { |
380 | - throw new Exception('vCard: Cannot save file ('.$Key.'), target path not writable ('.$TargetPath.')'); |
|
380 | + throw new Exception('vCard: Cannot save file (' . $Key . '), target path not writable (' . $TargetPath . ')'); |
|
381 | 381 | } |
382 | 382 | return false; |
383 | 383 | } |
@@ -458,8 +458,8 @@ discard block |
||
458 | 458 | */ |
459 | 459 | public function __toString() |
460 | 460 | { |
461 | - $Text = 'BEGIN:VCARD'.self::endl; |
|
462 | - $Text .= 'VERSION:3.0'.self::endl; |
|
461 | + $Text = 'BEGIN:VCARD' . self::endl; |
|
462 | + $Text .= 'VERSION:3.0' . self::endl; |
|
463 | 463 | |
464 | 464 | foreach ($this -> Data as $Key => $Values) |
465 | 465 | { |
@@ -476,7 +476,7 @@ discard block |
||
476 | 476 | $Text .= $KeyUC; |
477 | 477 | if (is_array($Value) && isset($Value['type'])) |
478 | 478 | { |
479 | - $Text .= ';TYPE='.self::PrepareTypeStrForOutput($Value['type']); |
|
479 | + $Text .= ';TYPE=' . self::PrepareTypeStrForOutput($Value['type']); |
|
480 | 480 | } |
481 | 481 | $Text .= ':'; |
482 | 482 | |
@@ -502,7 +502,7 @@ discard block |
||
502 | 502 | } |
503 | 503 | } |
504 | 504 | |
505 | - $Text .= 'END:VCARD'.self::endl; |
|
505 | + $Text .= 'END:VCARD' . self::endl; |
|
506 | 506 | return $Text; |
507 | 507 | } |
508 | 508 | |
@@ -603,7 +603,7 @@ discard block |
||
603 | 603 | } |
604 | 604 | elseif (count($Parameter) > 2) |
605 | 605 | { |
606 | - if(count(explode(',', $RawParams[$Index], -1)) > 0) |
|
606 | + if (count(explode(',', $RawParams[$Index], -1)) > 0) |
|
607 | 607 | { |
608 | 608 | $TempTypeParams = self::ParseParameters($Key, explode(',', $RawParams[$Index])); |
609 | 609 | if ($TempTypeParams['type']) |
@@ -84,12 +84,10 @@ discard block |
||
84 | 84 | |
85 | 85 | $this -> Path = $Path; |
86 | 86 | $this -> RawData = file_get_contents($this -> Path); |
87 | - } |
|
88 | - elseif ($RawData) |
|
87 | + } elseif ($RawData) |
|
89 | 88 | { |
90 | 89 | $this -> RawData = $RawData; |
91 | - } |
|
92 | - else |
|
90 | + } else |
|
93 | 91 | { |
94 | 92 | //throw new Exception('vCard: No content provided'); |
95 | 93 | // Not necessary anymore as possibility to create vCards is added |
@@ -139,8 +137,7 @@ discard block |
||
139 | 137 | $ClassName = get_class($this); |
140 | 138 | $this -> Data[] = new $ClassName(false, $SinglevCardRawData); |
141 | 139 | } |
142 | - } |
|
143 | - else |
|
140 | + } else |
|
144 | 141 | { |
145 | 142 | // Protect the BASE64 final = sign (detected by the line beginning with whitespace), otherwise the next replace will get rid of it |
146 | 143 | $this -> RawData = preg_replace('{(\n\s.+)=(\n)}', '$1-base64=-$2', $this -> RawData); |
@@ -190,8 +187,7 @@ discard block |
||
190 | 187 | } |
191 | 188 | $this -> Data[$Key][] = $Value; |
192 | 189 | continue; |
193 | - } |
|
194 | - else |
|
190 | + } else |
|
195 | 191 | { |
196 | 192 | $Value = str_replace('-wrap-', '', $Value); |
197 | 193 | } |
@@ -224,11 +220,12 @@ discard block |
||
224 | 220 | if (in_array($ParamValue, array('b', 'base64'))) |
225 | 221 | { |
226 | 222 | //$Value = base64_decode($Value); |
227 | - } |
|
228 | - elseif ($ParamValue == 'quoted-printable') // v2.1 |
|
223 | + } elseif ($ParamValue == 'quoted-printable') { |
|
224 | + // v2.1 |
|
229 | 225 | { |
230 | 226 | $Value = quoted_printable_decode($Value); |
231 | 227 | } |
228 | + } |
|
232 | 229 | break; |
233 | 230 | case 'charset': // v2.1 |
234 | 231 | if ($ParamValue != 'utf-8' && $ParamValue != 'utf8') |
@@ -263,8 +260,7 @@ discard block |
||
263 | 260 | { |
264 | 261 | $Value['type'] = $Type; |
265 | 262 | } |
266 | - } |
|
267 | - else |
|
263 | + } else |
|
268 | 264 | { |
269 | 265 | if (in_array($Key, self::$Spec_MultipleValueElements)) |
270 | 266 | { |
@@ -311,8 +307,7 @@ discard block |
||
311 | 307 | if ($Key == 'agent') |
312 | 308 | { |
313 | 309 | return $this -> Data[$Key]; |
314 | - } |
|
315 | - elseif (in_array($Key, self::$Spec_FileElements)) |
|
310 | + } elseif (in_array($Key, self::$Spec_FileElements)) |
|
316 | 311 | { |
317 | 312 | $Value = $this -> Data[$Key]; |
318 | 313 | foreach ($Value as $K => $V) |
@@ -331,8 +326,7 @@ discard block |
||
331 | 326 | return $this -> Data[$Key][0]; |
332 | 327 | } |
333 | 328 | return $this -> Data[$Key]; |
334 | - } |
|
335 | - elseif ($Key == 'Mode') |
|
329 | + } elseif ($Key == 'Mode') |
|
336 | 330 | { |
337 | 331 | return $this -> Mode; |
338 | 332 | } |
@@ -374,8 +368,7 @@ discard block |
||
374 | 368 | } |
375 | 369 | $Status = file_put_contents($TargetPath, $RawContent); |
376 | 370 | return (bool)$Status; |
377 | - } |
|
378 | - else |
|
371 | + } else |
|
379 | 372 | { |
380 | 373 | throw new Exception('vCard: Cannot save file ('.$Key.'), target path not writable ('.$TargetPath.')'); |
381 | 374 | } |
@@ -421,8 +414,7 @@ discard block |
||
421 | 414 | if (empty($this -> Data[$Key][$LastElementIndex][$Types[0]])) |
422 | 415 | { |
423 | 416 | $this -> Data[$Key][$LastElementIndex][$Types[0]] = $Value; |
424 | - } |
|
425 | - else |
|
417 | + } else |
|
426 | 418 | { |
427 | 419 | $LastElementIndex++; |
428 | 420 | } |
@@ -434,16 +426,14 @@ discard block |
||
434 | 426 | $Types[0] => $Value |
435 | 427 | ); |
436 | 428 | } |
437 | - } |
|
438 | - elseif (isset(self::$Spec_ElementTypes[$Key])) |
|
429 | + } elseif (isset(self::$Spec_ElementTypes[$Key])) |
|
439 | 430 | { |
440 | 431 | $this -> Data[$Key][] = array( |
441 | 432 | 'value' => $Value, |
442 | 433 | 'type' => $Types |
443 | 434 | ); |
444 | 435 | } |
445 | - } |
|
446 | - elseif ($Value) |
|
436 | + } elseif ($Value) |
|
447 | 437 | { |
448 | 438 | $this -> Data[$Key][] = $Value; |
449 | 439 | } |
@@ -488,12 +478,10 @@ discard block |
||
488 | 478 | $PartArray[] = isset($Value[$Part]) ? $Value[$Part] : ''; |
489 | 479 | } |
490 | 480 | $Text .= implode(';', $PartArray); |
491 | - } |
|
492 | - elseif (is_array($Value) && isset(self::$Spec_ElementTypes[$Key])) |
|
481 | + } elseif (is_array($Value) && isset(self::$Spec_ElementTypes[$Key])) |
|
493 | 482 | { |
494 | 483 | $Text .= $Value['value']; |
495 | - } |
|
496 | - else |
|
484 | + } else |
|
497 | 485 | { |
498 | 486 | $Text .= $Value; |
499 | 487 | } |
@@ -600,8 +588,7 @@ discard block |
||
600 | 588 | { |
601 | 589 | $Type[] = $Parameter[0]; |
602 | 590 | } |
603 | - } |
|
604 | - elseif (count($Parameter) > 2) |
|
591 | + } elseif (count($Parameter) > 2) |
|
605 | 592 | { |
606 | 593 | if(count(explode(',', $RawParams[$Index], -1)) > 0) |
607 | 594 | { |
@@ -611,8 +598,7 @@ discard block |
||
611 | 598 | $Type = array_merge($Type, $TempTypeParams['type']); |
612 | 599 | } |
613 | 600 | } |
614 | - } |
|
615 | - else |
|
601 | + } else |
|
616 | 602 | { |
617 | 603 | switch ($Parameter[0]) |
618 | 604 | { |
@@ -1,20 +1,20 @@ |
||
1 | 1 | <?php |
2 | - require_once('vCard.php'); |
|
2 | + require_once('vCard.php'); |
|
3 | 3 | |
4 | - $vCard = new vCard; |
|
5 | - $vCard -> n('John', 'FirstName'); |
|
6 | - $vCard -> n('Doe', 'LastName'); |
|
7 | - $vCard -> tel('555-1111'); |
|
8 | - $vCard -> tel('555-1234', 'Work'); |
|
9 | - $vCard -> adr('', 'POBox'); |
|
10 | - $vCard -> adr('', 'ExtendedAddress'); |
|
11 | - $vCard -> adr('42 Plantation St.', 'StreetAddress'); |
|
12 | - $vCard -> adr('Baytown', 'Locality'); |
|
13 | - $vCard -> adr('LA', 'Region'); |
|
14 | - $vCard -> adr('30314', 'PostalCode'); |
|
15 | - $vCard -> adr('USA', 'Country'); |
|
4 | + $vCard = new vCard; |
|
5 | + $vCard -> n('John', 'FirstName'); |
|
6 | + $vCard -> n('Doe', 'LastName'); |
|
7 | + $vCard -> tel('555-1111'); |
|
8 | + $vCard -> tel('555-1234', 'Work'); |
|
9 | + $vCard -> adr('', 'POBox'); |
|
10 | + $vCard -> adr('', 'ExtendedAddress'); |
|
11 | + $vCard -> adr('42 Plantation St.', 'StreetAddress'); |
|
12 | + $vCard -> adr('Baytown', 'Locality'); |
|
13 | + $vCard -> adr('LA', 'Region'); |
|
14 | + $vCard -> adr('30314', 'PostalCode'); |
|
15 | + $vCard -> adr('USA', 'Country'); |
|
16 | 16 | |
17 | - //$vCard = new vCard('Example3.0.vcf'); |
|
17 | + //$vCard = new vCard('Example3.0.vcf'); |
|
18 | 18 | |
19 | - echo '<pre>'.$vCard.'</pre>'; |
|
19 | + echo '<pre>'.$vCard.'</pre>'; |
|
20 | 20 | ?> |
21 | 21 | \ No newline at end of file |
@@ -16,5 +16,5 @@ |
||
16 | 16 | |
17 | 17 | //$vCard = new vCard('Example3.0.vcf'); |
18 | 18 | |
19 | - echo '<pre>'.$vCard.'</pre>'; |
|
19 | + echo '<pre>' . $vCard . '</pre>'; |
|
20 | 20 | ?> |
21 | 21 | \ No newline at end of file |
@@ -26,30 +26,30 @@ discard block |
||
26 | 26 | <body> |
27 | 27 | |
28 | 28 | <?php |
29 | - require_once('vCard.php'); |
|
29 | + require_once('vCard.php'); |
|
30 | 30 | |
31 | - /** |
|
32 | - * Test function for vCard content output |
|
33 | - * @param vCard vCard object |
|
34 | - */ |
|
35 | - function OutputvCard(vCard $vCard) |
|
36 | - { |
|
37 | - echo '<h2>'.$vCard -> FN[0].'</h2>'; |
|
31 | + /** |
|
32 | + * Test function for vCard content output |
|
33 | + * @param vCard vCard object |
|
34 | + */ |
|
35 | + function OutputvCard(vCard $vCard) |
|
36 | + { |
|
37 | + echo '<h2>'.$vCard -> FN[0].'</h2>'; |
|
38 | 38 | |
39 | - if ($vCard -> PHOTO) |
|
40 | - { |
|
41 | - foreach ($vCard -> PHOTO as $Photo) |
|
42 | - { |
|
43 | - if ($Photo['encoding'] == 'b') |
|
44 | - { |
|
45 | - echo '<img src="data:image/'.$Photo['type'][0].';base64,'.$Photo['value'].'" /><br />'; |
|
46 | - } |
|
47 | - else |
|
48 | - { |
|
49 | - echo '<img src="'.$Photo['value'].'" /><br />'; |
|
50 | - } |
|
39 | + if ($vCard -> PHOTO) |
|
40 | + { |
|
41 | + foreach ($vCard -> PHOTO as $Photo) |
|
42 | + { |
|
43 | + if ($Photo['encoding'] == 'b') |
|
44 | + { |
|
45 | + echo '<img src="data:image/'.$Photo['type'][0].';base64,'.$Photo['value'].'" /><br />'; |
|
46 | + } |
|
47 | + else |
|
48 | + { |
|
49 | + echo '<img src="'.$Photo['value'].'" /><br />'; |
|
50 | + } |
|
51 | 51 | |
52 | - /* |
|
52 | + /* |
|
53 | 53 | // It can also be saved to a file |
54 | 54 | try |
55 | 55 | { |
@@ -64,153 +64,153 @@ discard block |
||
64 | 64 | // Target path not writable |
65 | 65 | } |
66 | 66 | */ |
67 | - } |
|
68 | - } |
|
67 | + } |
|
68 | + } |
|
69 | 69 | |
70 | - foreach ($vCard -> N as $Name) |
|
71 | - { |
|
72 | - echo '<h3>Name: '.$Name['firstname'].' '.$Name['lastname'].'</h3>'; |
|
73 | - } |
|
70 | + foreach ($vCard -> N as $Name) |
|
71 | + { |
|
72 | + echo '<h3>Name: '.$Name['firstname'].' '.$Name['lastname'].'</h3>'; |
|
73 | + } |
|
74 | 74 | |
75 | - foreach ($vCard -> ORG as $Organization) |
|
76 | - { |
|
77 | - echo '<h3>Organization: '.$Organization['name']. |
|
78 | - ($Organization['unit1'] || $Organization['unit2'] ? |
|
79 | - ' ('.implode(', ', array($Organization['unit1'], $Organization['unit2'])).')' : |
|
80 | - '' |
|
81 | - ).'</h3>'; |
|
82 | - } |
|
75 | + foreach ($vCard -> ORG as $Organization) |
|
76 | + { |
|
77 | + echo '<h3>Organization: '.$Organization['name']. |
|
78 | + ($Organization['unit1'] || $Organization['unit2'] ? |
|
79 | + ' ('.implode(', ', array($Organization['unit1'], $Organization['unit2'])).')' : |
|
80 | + '' |
|
81 | + ).'</h3>'; |
|
82 | + } |
|
83 | 83 | |
84 | - if ($vCard -> TEL) |
|
85 | - { |
|
86 | - echo '<p><h4>Phone</h4>'; |
|
87 | - foreach ($vCard -> TEL as $Tel) |
|
88 | - { |
|
89 | - if (is_scalar($Tel)) |
|
90 | - { |
|
91 | - echo $Tel.'<br />'; |
|
92 | - } |
|
93 | - else |
|
94 | - { |
|
95 | - echo $Tel['value'].' ('.implode(', ', $Tel['type']).')<br />'; |
|
96 | - } |
|
97 | - } |
|
98 | - echo '</p>'; |
|
99 | - } |
|
84 | + if ($vCard -> TEL) |
|
85 | + { |
|
86 | + echo '<p><h4>Phone</h4>'; |
|
87 | + foreach ($vCard -> TEL as $Tel) |
|
88 | + { |
|
89 | + if (is_scalar($Tel)) |
|
90 | + { |
|
91 | + echo $Tel.'<br />'; |
|
92 | + } |
|
93 | + else |
|
94 | + { |
|
95 | + echo $Tel['value'].' ('.implode(', ', $Tel['type']).')<br />'; |
|
96 | + } |
|
97 | + } |
|
98 | + echo '</p>'; |
|
99 | + } |
|
100 | 100 | |
101 | - if ($vCard -> EMAIL) |
|
102 | - { |
|
103 | - echo '<p><h4>Email</h4>'; |
|
104 | - foreach ($vCard -> EMAIL as $Email) |
|
105 | - { |
|
106 | - if (is_scalar($Email)) |
|
107 | - { |
|
108 | - echo $Email; |
|
109 | - } |
|
110 | - else |
|
111 | - { |
|
112 | - echo $Email['value'].' ('.implode(', ', $Email['type']).')<br />'; |
|
113 | - } |
|
114 | - } |
|
115 | - echo '</p>'; |
|
116 | - } |
|
101 | + if ($vCard -> EMAIL) |
|
102 | + { |
|
103 | + echo '<p><h4>Email</h4>'; |
|
104 | + foreach ($vCard -> EMAIL as $Email) |
|
105 | + { |
|
106 | + if (is_scalar($Email)) |
|
107 | + { |
|
108 | + echo $Email; |
|
109 | + } |
|
110 | + else |
|
111 | + { |
|
112 | + echo $Email['value'].' ('.implode(', ', $Email['type']).')<br />'; |
|
113 | + } |
|
114 | + } |
|
115 | + echo '</p>'; |
|
116 | + } |
|
117 | 117 | |
118 | - if ($vCard -> URL) |
|
119 | - { |
|
120 | - echo '<p><h4>URL</h4>'; |
|
121 | - foreach ($vCard -> URL as $URL) |
|
122 | - { |
|
123 | - if (is_scalar($URL)) |
|
124 | - { |
|
125 | - echo $URL.'<br />'; |
|
126 | - } |
|
127 | - else |
|
128 | - { |
|
129 | - echo $URL['value'].'<br />'; |
|
130 | - } |
|
131 | - } |
|
132 | - echo '</p>'; |
|
133 | - } |
|
118 | + if ($vCard -> URL) |
|
119 | + { |
|
120 | + echo '<p><h4>URL</h4>'; |
|
121 | + foreach ($vCard -> URL as $URL) |
|
122 | + { |
|
123 | + if (is_scalar($URL)) |
|
124 | + { |
|
125 | + echo $URL.'<br />'; |
|
126 | + } |
|
127 | + else |
|
128 | + { |
|
129 | + echo $URL['value'].'<br />'; |
|
130 | + } |
|
131 | + } |
|
132 | + echo '</p>'; |
|
133 | + } |
|
134 | 134 | |
135 | - if ($vCard -> IMPP) |
|
136 | - { |
|
137 | - echo '<p><h4>Instant messaging</h4>'; |
|
138 | - foreach ($vCard -> IMPP as $IMPP) |
|
139 | - { |
|
140 | - if (is_scalar($IMPP)) |
|
141 | - { |
|
142 | - echo $IMPP.'<br />'; |
|
143 | - } |
|
144 | - else |
|
145 | - { |
|
146 | - echo $IMPP['value'].'<br/ >'; |
|
147 | - } |
|
148 | - } |
|
149 | - echo '</p>'; |
|
150 | - } |
|
135 | + if ($vCard -> IMPP) |
|
136 | + { |
|
137 | + echo '<p><h4>Instant messaging</h4>'; |
|
138 | + foreach ($vCard -> IMPP as $IMPP) |
|
139 | + { |
|
140 | + if (is_scalar($IMPP)) |
|
141 | + { |
|
142 | + echo $IMPP.'<br />'; |
|
143 | + } |
|
144 | + else |
|
145 | + { |
|
146 | + echo $IMPP['value'].'<br/ >'; |
|
147 | + } |
|
148 | + } |
|
149 | + echo '</p>'; |
|
150 | + } |
|
151 | 151 | |
152 | - if ($vCard -> ADR) |
|
153 | - { |
|
154 | - foreach ($vCard -> ADR as $Address) |
|
155 | - { |
|
156 | - echo '<p><h4>Address ('.implode(', ', $Address['type']).')</h4>'; |
|
157 | - echo 'Street address: <strong>'.($Address['streetaddress'] ? $Address['streetaddress'] : '-').'</strong><br />'. |
|
158 | - 'PO Box: <strong>'.($Address['pobox'] ? $Address['pobox'] : '-').'</strong><br />'. |
|
159 | - 'Extended address: <strong>'.($Address['extendedaddress'] ? $Address['extendedaddress'] : '-').'</strong><br />'. |
|
160 | - 'Locality: <strong>'.($Address['locality'] ? $Address['locality'] : '-').'</strong><br />'. |
|
161 | - 'Region: <strong>'.($Address['region'] ? $Address['region'] : '-').'</strong><br />'. |
|
162 | - 'ZIP/Post code: <strong>'.($Address['postalcode'] ? $Address['postalcode'] : '-').'</strong><br />'. |
|
163 | - 'Country: <strong>'.($Address['country'] ? $Address['country'] : '-').'</strong>'; |
|
164 | - } |
|
165 | - echo '</p>'; |
|
166 | - } |
|
152 | + if ($vCard -> ADR) |
|
153 | + { |
|
154 | + foreach ($vCard -> ADR as $Address) |
|
155 | + { |
|
156 | + echo '<p><h4>Address ('.implode(', ', $Address['type']).')</h4>'; |
|
157 | + echo 'Street address: <strong>'.($Address['streetaddress'] ? $Address['streetaddress'] : '-').'</strong><br />'. |
|
158 | + 'PO Box: <strong>'.($Address['pobox'] ? $Address['pobox'] : '-').'</strong><br />'. |
|
159 | + 'Extended address: <strong>'.($Address['extendedaddress'] ? $Address['extendedaddress'] : '-').'</strong><br />'. |
|
160 | + 'Locality: <strong>'.($Address['locality'] ? $Address['locality'] : '-').'</strong><br />'. |
|
161 | + 'Region: <strong>'.($Address['region'] ? $Address['region'] : '-').'</strong><br />'. |
|
162 | + 'ZIP/Post code: <strong>'.($Address['postalcode'] ? $Address['postalcode'] : '-').'</strong><br />'. |
|
163 | + 'Country: <strong>'.($Address['country'] ? $Address['country'] : '-').'</strong>'; |
|
164 | + } |
|
165 | + echo '</p>'; |
|
166 | + } |
|
167 | 167 | |
168 | - if ($vCard -> AGENT) |
|
169 | - { |
|
170 | - echo '<h4>Agents</h4>'; |
|
171 | - foreach ($vCard -> AGENT as $Agent) |
|
172 | - { |
|
173 | - if (is_scalar($Agent)) |
|
174 | - { |
|
175 | - echo '<div class="Agent">'.$Agent.'</div>'; |
|
176 | - } |
|
177 | - elseif (is_a($Agent, 'vCard')) |
|
178 | - { |
|
179 | - echo '<div class="Agent">'; |
|
180 | - OutputvCard($Agent); |
|
181 | - echo '</div>'; |
|
182 | - } |
|
183 | - } |
|
184 | - } |
|
185 | - } |
|
168 | + if ($vCard -> AGENT) |
|
169 | + { |
|
170 | + echo '<h4>Agents</h4>'; |
|
171 | + foreach ($vCard -> AGENT as $Agent) |
|
172 | + { |
|
173 | + if (is_scalar($Agent)) |
|
174 | + { |
|
175 | + echo '<div class="Agent">'.$Agent.'</div>'; |
|
176 | + } |
|
177 | + elseif (is_a($Agent, 'vCard')) |
|
178 | + { |
|
179 | + echo '<div class="Agent">'; |
|
180 | + OutputvCard($Agent); |
|
181 | + echo '</div>'; |
|
182 | + } |
|
183 | + } |
|
184 | + } |
|
185 | + } |
|
186 | 186 | |
187 | - $vCard = new vCard( |
|
188 | - 'Example3.0.vcf', // Path to vCard file |
|
189 | - false, // Raw vCard text, can be used instead of a file |
|
190 | - array( // Option array |
|
191 | - // This lets you get single values for elements that could contain multiple values but have only one value. |
|
192 | - // This defaults to false so every value that could have multiple values is returned as array. |
|
193 | - 'Collapse' => false |
|
194 | - ) |
|
195 | - ); |
|
187 | + $vCard = new vCard( |
|
188 | + 'Example3.0.vcf', // Path to vCard file |
|
189 | + false, // Raw vCard text, can be used instead of a file |
|
190 | + array( // Option array |
|
191 | + // This lets you get single values for elements that could contain multiple values but have only one value. |
|
192 | + // This defaults to false so every value that could have multiple values is returned as array. |
|
193 | + 'Collapse' => false |
|
194 | + ) |
|
195 | + ); |
|
196 | 196 | |
197 | - if (count($vCard) == 0) |
|
198 | - { |
|
199 | - throw new Exception('vCard test: empty vCard!'); |
|
200 | - } |
|
201 | - // if the file contains a single vCard, it is accessible directly. |
|
202 | - elseif (count($vCard) == 1) |
|
203 | - { |
|
204 | - OutputvCard($vCard); |
|
205 | - } |
|
206 | - // if the file contains multiple vCards, they are accessible as elements of an array |
|
207 | - else |
|
208 | - { |
|
209 | - foreach ($vCard as $Index => $vCardPart) |
|
210 | - { |
|
211 | - OutputvCard($vCardPart); |
|
212 | - } |
|
213 | - } |
|
197 | + if (count($vCard) == 0) |
|
198 | + { |
|
199 | + throw new Exception('vCard test: empty vCard!'); |
|
200 | + } |
|
201 | + // if the file contains a single vCard, it is accessible directly. |
|
202 | + elseif (count($vCard) == 1) |
|
203 | + { |
|
204 | + OutputvCard($vCard); |
|
205 | + } |
|
206 | + // if the file contains multiple vCards, they are accessible as elements of an array |
|
207 | + else |
|
208 | + { |
|
209 | + foreach ($vCard as $Index => $vCardPart) |
|
210 | + { |
|
211 | + OutputvCard($vCardPart); |
|
212 | + } |
|
213 | + } |
|
214 | 214 | ?> |
215 | 215 | </body> |
216 | 216 | </html> |
@@ -34,7 +34,7 @@ discard block |
||
34 | 34 | */ |
35 | 35 | function OutputvCard(vCard $vCard) |
36 | 36 | { |
37 | - echo '<h2>'.$vCard -> FN[0].'</h2>'; |
|
37 | + echo '<h2>' . $vCard -> FN[0] . '</h2>'; |
|
38 | 38 | |
39 | 39 | if ($vCard -> PHOTO) |
40 | 40 | { |
@@ -42,11 +42,11 @@ discard block |
||
42 | 42 | { |
43 | 43 | if ($Photo['encoding'] == 'b') |
44 | 44 | { |
45 | - echo '<img src="data:image/'.$Photo['type'][0].';base64,'.$Photo['value'].'" /><br />'; |
|
45 | + echo '<img src="data:image/' . $Photo['type'][0] . ';base64,' . $Photo['value'] . '" /><br />'; |
|
46 | 46 | } |
47 | 47 | else |
48 | 48 | { |
49 | - echo '<img src="'.$Photo['value'].'" /><br />'; |
|
49 | + echo '<img src="' . $Photo['value'] . '" /><br />'; |
|
50 | 50 | } |
51 | 51 | |
52 | 52 | /* |
@@ -69,16 +69,15 @@ discard block |
||
69 | 69 | |
70 | 70 | foreach ($vCard -> N as $Name) |
71 | 71 | { |
72 | - echo '<h3>Name: '.$Name['firstname'].' '.$Name['lastname'].'</h3>'; |
|
72 | + echo '<h3>Name: ' . $Name['firstname'] . ' ' . $Name['lastname'] . '</h3>'; |
|
73 | 73 | } |
74 | 74 | |
75 | 75 | foreach ($vCard -> ORG as $Organization) |
76 | 76 | { |
77 | - echo '<h3>Organization: '.$Organization['name']. |
|
77 | + echo '<h3>Organization: ' . $Organization['name'] . |
|
78 | 78 | ($Organization['unit1'] || $Organization['unit2'] ? |
79 | - ' ('.implode(', ', array($Organization['unit1'], $Organization['unit2'])).')' : |
|
80 | - '' |
|
81 | - ).'</h3>'; |
|
79 | + ' (' . implode(', ', array($Organization['unit1'], $Organization['unit2'])) . ')' : '' |
|
80 | + ) . '</h3>'; |
|
82 | 81 | } |
83 | 82 | |
84 | 83 | if ($vCard -> TEL) |
@@ -88,11 +87,11 @@ discard block |
||
88 | 87 | { |
89 | 88 | if (is_scalar($Tel)) |
90 | 89 | { |
91 | - echo $Tel.'<br />'; |
|
90 | + echo $Tel . '<br />'; |
|
92 | 91 | } |
93 | 92 | else |
94 | 93 | { |
95 | - echo $Tel['value'].' ('.implode(', ', $Tel['type']).')<br />'; |
|
94 | + echo $Tel['value'] . ' (' . implode(', ', $Tel['type']) . ')<br />'; |
|
96 | 95 | } |
97 | 96 | } |
98 | 97 | echo '</p>'; |
@@ -109,7 +108,7 @@ discard block |
||
109 | 108 | } |
110 | 109 | else |
111 | 110 | { |
112 | - echo $Email['value'].' ('.implode(', ', $Email['type']).')<br />'; |
|
111 | + echo $Email['value'] . ' (' . implode(', ', $Email['type']) . ')<br />'; |
|
113 | 112 | } |
114 | 113 | } |
115 | 114 | echo '</p>'; |
@@ -122,11 +121,11 @@ discard block |
||
122 | 121 | { |
123 | 122 | if (is_scalar($URL)) |
124 | 123 | { |
125 | - echo $URL.'<br />'; |
|
124 | + echo $URL . '<br />'; |
|
126 | 125 | } |
127 | 126 | else |
128 | 127 | { |
129 | - echo $URL['value'].'<br />'; |
|
128 | + echo $URL['value'] . '<br />'; |
|
130 | 129 | } |
131 | 130 | } |
132 | 131 | echo '</p>'; |
@@ -139,11 +138,11 @@ discard block |
||
139 | 138 | { |
140 | 139 | if (is_scalar($IMPP)) |
141 | 140 | { |
142 | - echo $IMPP.'<br />'; |
|
141 | + echo $IMPP . '<br />'; |
|
143 | 142 | } |
144 | 143 | else |
145 | 144 | { |
146 | - echo $IMPP['value'].'<br/ >'; |
|
145 | + echo $IMPP['value'] . '<br/ >'; |
|
147 | 146 | } |
148 | 147 | } |
149 | 148 | echo '</p>'; |
@@ -153,14 +152,14 @@ discard block |
||
153 | 152 | { |
154 | 153 | foreach ($vCard -> ADR as $Address) |
155 | 154 | { |
156 | - echo '<p><h4>Address ('.implode(', ', $Address['type']).')</h4>'; |
|
157 | - echo 'Street address: <strong>'.($Address['streetaddress'] ? $Address['streetaddress'] : '-').'</strong><br />'. |
|
158 | - 'PO Box: <strong>'.($Address['pobox'] ? $Address['pobox'] : '-').'</strong><br />'. |
|
159 | - 'Extended address: <strong>'.($Address['extendedaddress'] ? $Address['extendedaddress'] : '-').'</strong><br />'. |
|
160 | - 'Locality: <strong>'.($Address['locality'] ? $Address['locality'] : '-').'</strong><br />'. |
|
161 | - 'Region: <strong>'.($Address['region'] ? $Address['region'] : '-').'</strong><br />'. |
|
162 | - 'ZIP/Post code: <strong>'.($Address['postalcode'] ? $Address['postalcode'] : '-').'</strong><br />'. |
|
163 | - 'Country: <strong>'.($Address['country'] ? $Address['country'] : '-').'</strong>'; |
|
155 | + echo '<p><h4>Address (' . implode(', ', $Address['type']) . ')</h4>'; |
|
156 | + echo 'Street address: <strong>' . ($Address['streetaddress'] ? $Address['streetaddress'] : '-') . '</strong><br />' . |
|
157 | + 'PO Box: <strong>' . ($Address['pobox'] ? $Address['pobox'] : '-') . '</strong><br />' . |
|
158 | + 'Extended address: <strong>' . ($Address['extendedaddress'] ? $Address['extendedaddress'] : '-') . '</strong><br />' . |
|
159 | + 'Locality: <strong>' . ($Address['locality'] ? $Address['locality'] : '-') . '</strong><br />' . |
|
160 | + 'Region: <strong>' . ($Address['region'] ? $Address['region'] : '-') . '</strong><br />' . |
|
161 | + 'ZIP/Post code: <strong>' . ($Address['postalcode'] ? $Address['postalcode'] : '-') . '</strong><br />' . |
|
162 | + 'Country: <strong>' . ($Address['country'] ? $Address['country'] : '-') . '</strong>'; |
|
164 | 163 | } |
165 | 164 | echo '</p>'; |
166 | 165 | } |
@@ -172,7 +171,7 @@ discard block |
||
172 | 171 | { |
173 | 172 | if (is_scalar($Agent)) |
174 | 173 | { |
175 | - echo '<div class="Agent">'.$Agent.'</div>'; |
|
174 | + echo '<div class="Agent">' . $Agent . '</div>'; |
|
176 | 175 | } |
177 | 176 | elseif (is_a($Agent, 'vCard')) |
178 | 177 | { |
@@ -43,8 +43,7 @@ discard block |
||
43 | 43 | if ($Photo['encoding'] == 'b') |
44 | 44 | { |
45 | 45 | echo '<img src="data:image/'.$Photo['type'][0].';base64,'.$Photo['value'].'" /><br />'; |
46 | - } |
|
47 | - else |
|
46 | + } else |
|
48 | 47 | { |
49 | 48 | echo '<img src="'.$Photo['value'].'" /><br />'; |
50 | 49 | } |
@@ -89,8 +88,7 @@ discard block |
||
89 | 88 | if (is_scalar($Tel)) |
90 | 89 | { |
91 | 90 | echo $Tel.'<br />'; |
92 | - } |
|
93 | - else |
|
91 | + } else |
|
94 | 92 | { |
95 | 93 | echo $Tel['value'].' ('.implode(', ', $Tel['type']).')<br />'; |
96 | 94 | } |
@@ -106,8 +104,7 @@ discard block |
||
106 | 104 | if (is_scalar($Email)) |
107 | 105 | { |
108 | 106 | echo $Email; |
109 | - } |
|
110 | - else |
|
107 | + } else |
|
111 | 108 | { |
112 | 109 | echo $Email['value'].' ('.implode(', ', $Email['type']).')<br />'; |
113 | 110 | } |
@@ -123,8 +120,7 @@ discard block |
||
123 | 120 | if (is_scalar($URL)) |
124 | 121 | { |
125 | 122 | echo $URL.'<br />'; |
126 | - } |
|
127 | - else |
|
123 | + } else |
|
128 | 124 | { |
129 | 125 | echo $URL['value'].'<br />'; |
130 | 126 | } |
@@ -140,8 +136,7 @@ discard block |
||
140 | 136 | if (is_scalar($IMPP)) |
141 | 137 | { |
142 | 138 | echo $IMPP.'<br />'; |
143 | - } |
|
144 | - else |
|
139 | + } else |
|
145 | 140 | { |
146 | 141 | echo $IMPP['value'].'<br/ >'; |
147 | 142 | } |
@@ -173,8 +168,7 @@ discard block |
||
173 | 168 | if (is_scalar($Agent)) |
174 | 169 | { |
175 | 170 | echo '<div class="Agent">'.$Agent.'</div>'; |
176 | - } |
|
177 | - elseif (is_a($Agent, 'vCard')) |
|
171 | + } elseif (is_a($Agent, 'vCard')) |
|
178 | 172 | { |
179 | 173 | echo '<div class="Agent">'; |
180 | 174 | OutputvCard($Agent); |
@@ -44,7 +44,7 @@ |
||
44 | 44 | } |
45 | 45 | |
46 | 46 | // log the result |
47 | -if ( isset($fritz) && is_object($fritz) && get_class($fritz) == 'fritzbox_api' ) |
|
47 | +if (isset($fritz) && is_object($fritz) && get_class($fritz) == 'fritzbox_api') |
|
48 | 48 | { |
49 | 49 | $fritz->logMessage($message); |
50 | 50 | } |
@@ -54,8 +54,7 @@ discard block |
||
54 | 54 | |
55 | 55 | // set a log message |
56 | 56 | $message .= 'Call list sucessfully downloaded'; |
57 | -} |
|
58 | -catch (Exception $e) |
|
57 | +} catch (Exception $e) |
|
59 | 58 | { |
60 | 59 | $message .= $e->getMessage(); |
61 | 60 | } |
@@ -64,8 +63,7 @@ discard block |
||
64 | 63 | if ( isset($fritz) && is_object($fritz) && get_class($fritz) == 'fritzbox_api' ) |
65 | 64 | { |
66 | 65 | $fritz->logMessage($message); |
67 | -} |
|
68 | -else |
|
66 | +} else |
|
69 | 67 | { |
70 | 68 | echo($message); |
71 | 69 | } |
@@ -44,7 +44,7 @@ |
||
44 | 44 | } |
45 | 45 | |
46 | 46 | // log the result |
47 | -if ( isset($fritz) && is_object($fritz) && get_class($fritz) == 'fritzbox_api' ) |
|
47 | +if (isset($fritz) && is_object($fritz) && get_class($fritz) == 'fritzbox_api') |
|
48 | 48 | { |
49 | 49 | $fritz->logMessage($message); |
50 | 50 | } |
@@ -54,8 +54,7 @@ discard block |
||
54 | 54 | |
55 | 55 | // set a log message |
56 | 56 | $message .= 'Call list sucessfully downloaded'; |
57 | -} |
|
58 | -catch (Exception $e) |
|
57 | +} catch (Exception $e) |
|
59 | 58 | { |
60 | 59 | $message .= $e->getMessage(); |
61 | 60 | } |
@@ -64,8 +63,7 @@ discard block |
||
64 | 63 | if ( isset($fritz) && is_object($fritz) && get_class($fritz) == 'fritzbox_api' ) |
65 | 64 | { |
66 | 65 | $fritz->logMessage($message); |
67 | -} |
|
68 | -else |
|
66 | +} else |
|
69 | 67 | { |
70 | 68 | echo($message); |
71 | 69 | } |
@@ -23,11 +23,11 @@ discard block |
||
23 | 23 | // init the output message |
24 | 24 | $message = date('Y-m-d H:i') . ' '; |
25 | 25 | |
26 | - if ( !$fritz->config->getItem('foncallslist_path') ) |
|
26 | + if (!$fritz->config->getItem('foncallslist_path')) |
|
27 | 27 | { |
28 | 28 | throw new Exception('Mandatory config Item foncallslist_path not set.'); |
29 | 29 | } |
30 | - if ( ( file_exists($fritz->config->getItem('foncallslist_path')) && !is_writable($fritz->config->getItem('foncallslist_path')) ) || ( !file_exists($fritz->config->getItem('foncallslist_path')) && !is_writable(dirname($fritz->config->getItem('foncallslist_path'))) ) ) |
|
30 | + if ((file_exists($fritz->config->getItem('foncallslist_path')) && !is_writable($fritz->config->getItem('foncallslist_path'))) || (!file_exists($fritz->config->getItem('foncallslist_path')) && !is_writable(dirname($fritz->config->getItem('foncallslist_path'))))) |
|
31 | 31 | { |
32 | 32 | throw new Exception('Config item foncallslist_path (' . $fritz->config->getItem('foncallslist_path') . ') is not writeable.'); |
33 | 33 | } |
@@ -61,7 +61,7 @@ discard block |
||
61 | 61 | } |
62 | 62 | |
63 | 63 | // log the result |
64 | -if ( isset($fritz) && is_object($fritz) && get_class($fritz) == 'fritzbox_api' ) |
|
64 | +if (isset($fritz) && is_object($fritz) && get_class($fritz) == 'fritzbox_api') |
|
65 | 65 | { |
66 | 66 | $fritz->logMessage($message); |
67 | 67 | } |
@@ -54,8 +54,7 @@ discard block |
||
54 | 54 | |
55 | 55 | // set a log message |
56 | 56 | $message .= 'Call list sucessfully downloaded'; |
57 | -} |
|
58 | -catch (Exception $e) |
|
57 | +} catch (Exception $e) |
|
59 | 58 | { |
60 | 59 | $message .= $e->getMessage(); |
61 | 60 | } |
@@ -64,8 +63,7 @@ discard block |
||
64 | 63 | if ( isset($fritz) && is_object($fritz) && get_class($fritz) == 'fritzbox_api' ) |
65 | 64 | { |
66 | 65 | $fritz->logMessage($message); |
67 | -} |
|
68 | -else |
|
66 | +} else |
|
69 | 67 | { |
70 | 68 | echo($message); |
71 | 69 | } |