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 } |
