1<?php
2
3namespace Sabre\VObject\Property;
4
5use Sabre\VObject\Parameter;
6use Sabre\VObject\Property;
7
8/**
9 * URI property.
10 *
11 * This object encodes URI values. vCard 2.1 calls these URL.
12 *
13 * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
14 * @author Evert Pot (http://evertpot.com/)
15 * @license http://sabre.io/license/ Modified BSD License
16 */
17class Uri extends Text
18{
19    /**
20     * In case this is a multi-value property. This string will be used as a
21     * delimiter.
22     *
23     * @var string|null
24     */
25    public $delimiter = null;
26
27    /**
28     * Returns the type of value.
29     *
30     * This corresponds to the VALUE= parameter. Every property also has a
31     * 'default' valueType.
32     *
33     * @return string
34     */
35    public function getValueType()
36    {
37        return 'URI';
38    }
39
40    /**
41     * Returns an iterable list of children.
42     *
43     * @return array
44     */
45    public function parameters()
46    {
47        $parameters = parent::parameters();
48        if (!isset($parameters['VALUE']) && in_array($this->name, ['URL', 'PHOTO'])) {
49            // If we are encoding a URI value, and this URI value has no
50            // VALUE=URI parameter, we add it anyway.
51            //
52            // This is not required by any spec, but both Apple iCal and Apple
53            // AddressBook (at least in version 10.8) will trip over this if
54            // this is not set, and so it improves compatibility.
55            //
56            // See Issue #227 and #235
57            $parameters['VALUE'] = new Parameter($this->root, 'VALUE', 'URI');
58        }
59
60        return $parameters;
61    }
62
63    /**
64     * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
65     *
66     * This has been 'unfolded', so only 1 line will be passed. Unescaping is
67     * not yet done, but parameters are not included.
68     *
69     * @param string $val
70     */
71    public function setRawMimeDirValue($val)
72    {
73        // Normally we don't need to do any type of unescaping for these
74        // properties, however.. we've noticed that Google Contacts
75        // specifically escapes the colon (:) with a backslash. While I have
76        // no clue why they thought that was a good idea, I'm unescaping it
77        // anyway.
78        //
79        // Good thing backslashes are not allowed in urls. Makes it easy to
80        // assume that a backslash is always intended as an escape character.
81        if ('URL' === $this->name) {
82            $regex = '#  (?: (\\\\ (?: \\\\ | : ) ) ) #x';
83            $matches = preg_split($regex, $val, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
84            $newVal = '';
85            foreach ($matches as $match) {
86                switch ($match) {
87                    case '\:':
88                        $newVal .= ':';
89                        break;
90                    default:
91                        $newVal .= $match;
92                        break;
93                }
94            }
95            $this->value = $newVal;
96        } else {
97            $this->value = strtr($val, ['\,' => ',']);
98        }
99    }
100
101    /**
102     * Returns a raw mime-dir representation of the value.
103     *
104     * @return string
105     */
106    public function getRawMimeDirValue()
107    {
108        if (is_array($this->value)) {
109            $value = $this->value[0];
110        } else {
111            $value = $this->value;
112        }
113
114        return strtr($value, [',' => '\,']);
115    }
116}
117