PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.4
Booking for Appointments and Events Calendar – Amelia v2.4.4
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / vendor / sabre / vobject / lib / Property / Text.php
ameliabooking / vendor / sabre / vobject / lib / Property Last commit date
ICalendar 6 months ago VCard 6 months ago Binary.php 6 months ago Boolean.php 6 months ago FlatText.php 6 months ago FloatValue.php 6 months ago IntegerValue.php 6 months ago Text.php 6 months ago Time.php 6 months ago Unknown.php 6 months ago Uri.php 6 months ago UtcOffset.php 6 months ago
Text.php
393 lines
1 <?php
2
3 namespace AmeliaVendor\Sabre\VObject\Property;
4
5 use AmeliaVendor\Sabre\VObject\Component;
6 use AmeliaVendor\Sabre\VObject\Document;
7 use AmeliaVendor\Sabre\VObject\Parser\MimeDir;
8 use AmeliaVendor\Sabre\VObject\Property;
9 use AmeliaVendor\Sabre\Xml;
10
11 /**
12 * Text property.
13 *
14 * This object represents TEXT values.
15 *
16 * @copyright Copyright (C) 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 = [
36 // vCard
37 'N',
38 'ADR',
39 'ORG',
40 'GENDER',
41 'CLIENTPIDMAP',
42
43 // iCalendar
44 'REQUEST-STATUS',
45 ];
46
47 /**
48 * Some text components have a minimum number of components.
49 *
50 * N must for instance be represented as 5 components, separated by ;, even
51 * if the last few components are unused.
52 *
53 * @var array
54 */
55 protected $minimumPropertyValues = [
56 'N' => 5,
57 'ADR' => 7,
58 ];
59
60 /**
61 * Creates the property.
62 *
63 * You can specify the parameters either in key=>value syntax, in which case
64 * parameters will automatically be created, or you can just pass a list of
65 * Parameter objects.
66 *
67 * @param Component $root The root document
68 * @param string $name
69 * @param string|array|null $value
70 * @param array $parameters List of parameters
71 * @param string $group The vcard property group
72 */
73 public function __construct(Component $root, $name, $value = null, array $parameters = [], $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 * Sets a raw value coming from a mimedir (iCalendar/vCard) file.
89 *
90 * This has been 'unfolded', so only 1 line will be passed. Unescaping is
91 * not yet done, but parameters are not included.
92 *
93 * @param string $val
94 */
95 public function setRawMimeDirValue($val)
96 {
97 $this->setValue(MimeDir::unescapeValue($val, $this->delimiter));
98 }
99
100 /**
101 * Sets the value as a quoted-printable encoded string.
102 *
103 * @param string $val
104 */
105 public function setQuotedPrintableValue($val)
106 {
107 $val = quoted_printable_decode($val);
108
109 // Quoted printable only appears in vCard 2.1, and the only character
110 // that may be escaped there is ;. So we are simply splitting on just
111 // that.
112 //
113 // We also don't have to unescape \\, so all we need to look for is a ;
114 // that's not preceded with a \.
115 $regex = '# (?<!\\\\) ; #x';
116 $matches = preg_split($regex, $val);
117 $this->setValue($matches);
118 }
119
120 /**
121 * Returns a raw mime-dir representation of the value.
122 *
123 * @return string
124 */
125 public function getRawMimeDirValue()
126 {
127 $val = $this->getParts();
128
129 if (isset($this->minimumPropertyValues[$this->name])) {
130 $val = array_pad($val, $this->minimumPropertyValues[$this->name], '');
131 }
132
133 foreach ($val as &$item) {
134 if (!is_array($item)) {
135 $item = [$item];
136 }
137
138 foreach ($item as &$subItem) {
139 if (!is_null($subItem)) {
140 $subItem = strtr(
141 $subItem,
142 [
143 '\\' => '\\\\',
144 ';' => '\;',
145 ',' => '\,',
146 "\n" => '\n',
147 "\r" => '',
148 ]
149 );
150 }
151 }
152 $item = implode(',', $item);
153 }
154
155 return implode($this->delimiter, $val);
156 }
157
158 /**
159 * Returns the value, in the format it should be encoded for json.
160 *
161 * This method must always return an array.
162 *
163 * @return array
164 */
165 public function getJsonValue()
166 {
167 // Structured text values should always be returned as a single
168 // array-item. Multi-value text should be returned as multiple items in
169 // the top-array.
170 if (in_array($this->name, $this->structuredValues)) {
171 return [$this->getParts()];
172 }
173
174 return $this->getParts();
175 }
176
177 /**
178 * Returns the type of value.
179 *
180 * This corresponds to the VALUE= parameter. Every property also has a
181 * 'default' valueType.
182 *
183 * @return string
184 */
185 public function getValueType()
186 {
187 return 'TEXT';
188 }
189
190 /**
191 * Turns the object back into a serialized blob.
192 *
193 * @return string
194 */
195 public function serialize()
196 {
197 // We need to kick in a special type of encoding, if it's a 2.1 vcard.
198 if (Document::VCARD21 !== $this->root->getDocumentType()) {
199 return parent::serialize();
200 }
201
202 $val = $this->getParts();
203
204 if (isset($this->minimumPropertyValues[$this->name])) {
205 $val = \array_pad($val, $this->minimumPropertyValues[$this->name], '');
206 }
207
208 // Imploding multiple parts into a single value, and splitting the
209 // values with ;.
210 if (\count($val) > 1) {
211 foreach ($val as $k => $v) {
212 $val[$k] = \str_replace(';', '\;', $v);
213 }
214 $val = \implode(';', $val);
215 } else {
216 $val = $val[0];
217 }
218
219 $str = $this->name;
220 if ($this->group) {
221 $str = $this->group.'.'.$this->name;
222 }
223 foreach ($this->parameters as $param) {
224 if ('QUOTED-PRINTABLE' === $param->getValue()) {
225 continue;
226 }
227 $str .= ';'.$param->serialize();
228 }
229
230 // If the resulting value contains a \n, we must encode it as
231 // quoted-printable.
232 if (false !== \strpos($val, "\n")) {
233 $str .= ';ENCODING=QUOTED-PRINTABLE:';
234 $lastLine = $str;
235 $out = null;
236
237 // The PHP built-in quoted-printable-encode does not correctly
238 // encode newlines for us. Specifically, the \r\n sequence must in
239 // vcards be encoded as =0D=OA and we must insert soft-newlines
240 // every 75 bytes.
241 for ($ii = 0; $ii < \strlen($val); ++$ii) {
242 $ord = \ord($val[$ii]);
243 // These characters are encoded as themselves.
244 if ($ord >= 32 && $ord <= 126) {
245 $lastLine .= $val[$ii];
246 } else {
247 $lastLine .= '='.\strtoupper(\bin2hex($val[$ii]));
248 }
249 if (\strlen($lastLine) >= 75) {
250 // Soft line break
251 $out .= $lastLine."=\r\n ";
252 $lastLine = null;
253 }
254 }
255 if (!\is_null($lastLine)) {
256 $out .= $lastLine."\r\n";
257 }
258
259 return $out;
260 } else {
261 $str .= ':'.$val;
262
263 $str = \preg_replace(
264 '/(
265 (?:^.)? # 1 additional byte in first line because of missing single space (see next line)
266 .{1,74} # max 75 bytes per line (1 byte is used for a single space added after every CRLF)
267 (?![\x80-\xbf]) # prevent splitting multibyte characters
268 )/x',
269 "$1\r\n ",
270 $str
271 );
272
273 // remove single space after last CRLF
274 return \substr($str, 0, -1);
275 }
276 }
277
278 /**
279 * This method serializes only the value of a property. This is used to
280 * create xCard or xCal documents.
281 *
282 * @param Xml\Writer $writer XML writer
283 */
284 protected function xmlSerializeValue(Xml\Writer $writer)
285 {
286 $values = $this->getParts();
287
288 $map = function ($items) use ($values, $writer) {
289 foreach ($items as $i => $item) {
290 $writer->writeElement(
291 $item,
292 !empty($values[$i]) ? $values[$i] : null
293 );
294 }
295 };
296
297 switch ($this->name) {
298 // Special-casing the REQUEST-STATUS property.
299 //
300 // See:
301 // http://tools.ietf.org/html/rfc6321#section-3.4.1.3
302 case 'REQUEST-STATUS':
303 $writer->writeElement('code', $values[0]);
304 $writer->writeElement('description', $values[1]);
305
306 if (isset($values[2])) {
307 $writer->writeElement('data', $values[2]);
308 }
309 break;
310
311 case 'N':
312 $map([
313 'surname',
314 'given',
315 'additional',
316 'prefix',
317 'suffix',
318 ]);
319 break;
320
321 case 'GENDER':
322 $map([
323 'sex',
324 'text',
325 ]);
326 break;
327
328 case 'ADR':
329 $map([
330 'pobox',
331 'ext',
332 'street',
333 'locality',
334 'region',
335 'code',
336 'country',
337 ]);
338 break;
339
340 case 'CLIENTPIDMAP':
341 $map([
342 'sourceid',
343 'uri',
344 ]);
345 break;
346
347 default:
348 parent::xmlSerializeValue($writer);
349 }
350 }
351
352 /**
353 * Validates the node for correctness.
354 *
355 * The following options are supported:
356 * - Node::REPAIR - If something is broken, and automatic repair may
357 * be attempted.
358 *
359 * An array is returned with warnings.
360 *
361 * Every item in the array has the following properties:
362 * * level - (number between 1 and 3 with severity information)
363 * * message - (human readable message)
364 * * node - (reference to the offending node)
365 *
366 * @param int $options
367 *
368 * @return array
369 */
370 public function validate($options = 0)
371 {
372 $warnings = parent::validate($options);
373
374 if (isset($this->minimumPropertyValues[$this->name])) {
375 $minimum = $this->minimumPropertyValues[$this->name];
376 $parts = $this->getParts();
377 if (count($parts) < $minimum) {
378 $warnings[] = [
379 'level' => $options & self::REPAIR ? 1 : 3,
380 'message' => 'The '.$this->name.' property must have at least '.$minimum.' values. It only has '.count($parts),
381 'node' => $this,
382 ];
383 if ($options & self::REPAIR) {
384 $parts = array_pad($parts, $minimum, '');
385 $this->setParts($parts);
386 }
387 }
388 }
389
390 return $warnings;
391 }
392 }
393