Mercurial > hg > rc1
comparison vendor/sabre/vobject/lib/Property/Text.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\Property; | |
4 | |
5 use | |
6 Sabre\VObject\Property, | |
7 Sabre\VObject\Component, | |
8 Sabre\VObject\Parser\MimeDir, | |
9 Sabre\VObject\Document; | |
10 | |
11 /** | |
12 * Text property | |
13 * | |
14 * This object represents TEXT values. | |
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 Text extends Property { | |
21 | |
22 /** | |
23 * In case this is a multi-value property. This string will be used as a | |
24 * delimiter. | |
25 * | |
26 * @var string | |
27 */ | |
28 public $delimiter = ','; | |
29 | |
30 /** | |
31 * List of properties that are considered 'structured'. | |
32 * | |
33 * @var array | |
34 */ | |
35 protected $structuredValues = array( | |
36 // vCard | |
37 'N', | |
38 'ADR', | |
39 'ORG', | |
40 'GENDER', | |
41 | |
42 // iCalendar | |
43 'REQUEST-STATUS', | |
44 ); | |
45 | |
46 /** | |
47 * Some text components have a minimum number of components. | |
48 * | |
49 * N must for instance be represented as 5 components, separated by ;, even | |
50 * if the last few components are unused. | |
51 * | |
52 * @var array | |
53 */ | |
54 protected $minimumPropertyValues = array( | |
55 'N' => 5, | |
56 'ADR' => 7, | |
57 ); | |
58 | |
59 /** | |
60 * Creates the property. | |
61 * | |
62 * You can specify the parameters either in key=>value syntax, in which case | |
63 * parameters will automatically be created, or you can just pass a list of | |
64 * Parameter objects. | |
65 * | |
66 * @param Component $root The root document | |
67 * @param string $name | |
68 * @param string|array|null $value | |
69 * @param array $parameters List of parameters | |
70 * @param string $group The vcard property group | |
71 * @return void | |
72 */ | |
73 public function __construct(Component $root, $name, $value = null, array $parameters = array(), $group = null) { | |
74 | |
75 // There's two types of multi-valued text properties: | |
76 // 1. multivalue properties. | |
77 // 2. structured value properties | |
78 // | |
79 // The former is always separated by a comma, the latter by semi-colon. | |
80 if (in_array($name, $this->structuredValues)) { | |
81 $this->delimiter = ';'; | |
82 } | |
83 | |
84 parent::__construct($root, $name, $value, $parameters, $group); | |
85 | |
86 } | |
87 | |
88 | |
89 /** | |
90 * Sets a raw value coming from a mimedir (iCalendar/vCard) file. | |
91 * | |
92 * This has been 'unfolded', so only 1 line will be passed. Unescaping is | |
93 * not yet done, but parameters are not included. | |
94 * | |
95 * @param string $val | |
96 * @return void | |
97 */ | |
98 public function setRawMimeDirValue($val) { | |
99 | |
100 $this->setValue(MimeDir::unescapeValue($val, $this->delimiter)); | |
101 | |
102 } | |
103 | |
104 /** | |
105 * Sets the value as a quoted-printable encoded string. | |
106 * | |
107 * @param string $val | |
108 * @return void | |
109 */ | |
110 public function setQuotedPrintableValue($val) { | |
111 | |
112 $val = quoted_printable_decode($val); | |
113 | |
114 // Quoted printable only appears in vCard 2.1, and the only character | |
115 // that may be escaped there is ;. So we are simply splitting on just | |
116 // that. | |
117 // | |
118 // We also don't have to unescape \\, so all we need to look for is a ; | |
119 // that's not preceeded with a \. | |
120 $regex = '# (?<!\\\\) ; #x'; | |
121 $matches = preg_split($regex, $val); | |
122 $this->setValue($matches); | |
123 | |
124 } | |
125 | |
126 /** | |
127 * Returns a raw mime-dir representation of the value. | |
128 * | |
129 * @return string | |
130 */ | |
131 public function getRawMimeDirValue() { | |
132 | |
133 $val = $this->getParts(); | |
134 | |
135 if (isset($this->minimumPropertyValues[$this->name])) { | |
136 $val = array_pad($val, $this->minimumPropertyValues[$this->name], ''); | |
137 } | |
138 | |
139 foreach($val as &$item) { | |
140 | |
141 if (!is_array($item)) { | |
142 $item = array($item); | |
143 } | |
144 | |
145 foreach($item as &$subItem) { | |
146 $subItem = strtr( | |
147 $subItem, | |
148 array( | |
149 '\\' => '\\\\', | |
150 ';' => '\;', | |
151 ',' => '\,', | |
152 "\n" => '\n', | |
153 "\r" => "", | |
154 ) | |
155 ); | |
156 } | |
157 $item = implode(',', $item); | |
158 | |
159 } | |
160 | |
161 return implode($this->delimiter, $val); | |
162 | |
163 } | |
164 | |
165 /** | |
166 * Returns the value, in the format it should be encoded for json. | |
167 * | |
168 * This method must always return an array. | |
169 * | |
170 * @return array | |
171 */ | |
172 public function getJsonValue() { | |
173 | |
174 // Structured text values should always be returned as a single | |
175 // array-item. Multi-value text should be returned as multiple items in | |
176 // the top-array. | |
177 if (in_array($this->name, $this->structuredValues)) { | |
178 return array($this->getParts()); | |
179 } else { | |
180 return $this->getParts(); | |
181 } | |
182 | |
183 } | |
184 | |
185 /** | |
186 * Returns the type of value. | |
187 * | |
188 * This corresponds to the VALUE= parameter. Every property also has a | |
189 * 'default' valueType. | |
190 * | |
191 * @return string | |
192 */ | |
193 public function getValueType() { | |
194 | |
195 return "TEXT"; | |
196 | |
197 } | |
198 | |
199 /** | |
200 * Turns the object back into a serialized blob. | |
201 * | |
202 * @return string | |
203 */ | |
204 public function serialize() { | |
205 | |
206 // We need to kick in a special type of encoding, if it's a 2.1 vcard. | |
207 if ($this->root->getDocumentType() !== Document::VCARD21) { | |
208 return parent::serialize(); | |
209 } | |
210 | |
211 $val = $this->getParts(); | |
212 | |
213 if (isset($this->minimumPropertyValues[$this->name])) { | |
214 $val = array_pad($val, $this->minimumPropertyValues[$this->name], ''); | |
215 } | |
216 | |
217 // Imploding multiple parts into a single value, and splitting the | |
218 // values with ;. | |
219 if (count($val)>1) { | |
220 foreach($val as $k=>$v) { | |
221 $val[$k] = str_replace(';','\;', $v); | |
222 } | |
223 $val = implode(';', $val); | |
224 } else { | |
225 $val = $val[0]; | |
226 } | |
227 | |
228 $str = $this->name; | |
229 if ($this->group) $str = $this->group . '.' . $this->name; | |
230 foreach($this->parameters as $param) { | |
231 | |
232 if ($param->getValue() === 'QUOTED-PRINTABLE') { | |
233 continue; | |
234 } | |
235 $str.=';' . $param->serialize(); | |
236 | |
237 } | |
238 | |
239 | |
240 | |
241 // If the resulting value contains a \n, we must encode it as | |
242 // quoted-printable. | |
243 if (strpos($val,"\n") !== false) { | |
244 | |
245 $str.=';ENCODING=QUOTED-PRINTABLE:'; | |
246 $lastLine=$str; | |
247 $out = null; | |
248 | |
249 // The PHP built-in quoted-printable-encode does not correctly | |
250 // encode newlines for us. Specifically, the \r\n sequence must in | |
251 // vcards be encoded as =0D=OA and we must insert soft-newlines | |
252 // every 75 bytes. | |
253 for($ii=0;$ii<strlen($val);$ii++) { | |
254 $ord = ord($val[$ii]); | |
255 // These characters are encoded as themselves. | |
256 if ($ord >= 32 && $ord <=126) { | |
257 $lastLine.=$val[$ii]; | |
258 } else { | |
259 $lastLine.='=' . strtoupper(bin2hex($val[$ii])); | |
260 } | |
261 if (strlen($lastLine)>=75) { | |
262 // Soft line break | |
263 $out.=$lastLine. "=\r\n "; | |
264 $lastLine = null; | |
265 } | |
266 | |
267 } | |
268 if (!is_null($lastLine)) $out.= $lastLine . "\r\n"; | |
269 return $out; | |
270 | |
271 } else { | |
272 $str.=':' . $val; | |
273 $out = ''; | |
274 while(strlen($str)>0) { | |
275 if (strlen($str)>75) { | |
276 $out.= mb_strcut($str,0,75,'utf-8') . "\r\n"; | |
277 $str = ' ' . mb_strcut($str,75,strlen($str),'utf-8'); | |
278 } else { | |
279 $out.=$str . "\r\n"; | |
280 $str=''; | |
281 break; | |
282 } | |
283 } | |
284 | |
285 return $out; | |
286 | |
287 | |
288 } | |
289 | |
290 } | |
291 | |
292 /** | |
293 * Validates the node for correctness. | |
294 * | |
295 * The following options are supported: | |
296 * - Node::REPAIR - If something is broken, and automatic repair may | |
297 * be attempted. | |
298 * | |
299 * An array is returned with warnings. | |
300 * | |
301 * Every item in the array has the following properties: | |
302 * * level - (number between 1 and 3 with severity information) | |
303 * * message - (human readable message) | |
304 * * node - (reference to the offending node) | |
305 * | |
306 * @param int $options | |
307 * @return array | |
308 */ | |
309 public function validate($options = 0) { | |
310 | |
311 $warnings = parent::validate($options); | |
312 | |
313 if (isset($this->minimumPropertyValues[$this->name])) { | |
314 | |
315 $minimum = $this->minimumPropertyValues[$this->name]; | |
316 $parts = $this->getParts(); | |
317 if (count($parts) < $minimum) { | |
318 $warnings[] = array( | |
319 'level' => 1, | |
320 'message' => 'This property must have at least ' . $minimum . ' components. It only has ' . count($parts), | |
321 'node' => $this, | |
322 ); | |
323 if ($options & self::REPAIR) { | |
324 $parts = array_pad($parts, $minimum, ''); | |
325 $this->setParts($parts); | |
326 } | |
327 } | |
328 | |
329 } | |
330 return $warnings; | |
331 | |
332 } | |
333 } |