1<?php 2 3namespace Sabre\VObject\Property; 4 5use Sabre\VObject; 6 7/** 8 * Compound property. 9 * 10 * This class adds (de)serialization of compound properties to/from arrays. 11 * 12 * Currently the following properties from RFC 6350 are mapped to use this 13 * class: 14 * 15 * N: Section 6.2.2 16 * ADR: Section 6.3.1 17 * ORG: Section 6.6.4 18 * CATEGORIES: Section 6.7.1 19 * 20 * In order to use this correctly, you must call setParts and getParts to 21 * retrieve and modify dates respectively. 22 * 23 * @author Thomas Tanghus (http://tanghus.net/) 24 * @author Lars Kneschke 25 * @author Evert Pot (http://evertpot.com/) 26 * @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/). 27 * @license http://sabre.io/license/ Modified BSD License 28 */ 29class Compound extends VObject\Property { 30 31 /** 32 * If property names are added to this map, they will be (de)serialised as arrays 33 * using the getParts() and setParts() methods. 34 * The keys are the property names, values are delimiter chars. 35 * 36 * @var array 37 */ 38 public static $delimiterMap = array( 39 'N' => ';', 40 'ADR' => ';', 41 'ORG' => ';', 42 'CATEGORIES' => ',', 43 ); 44 45 /** 46 * The currently used delimiter. 47 * 48 * @var string 49 */ 50 protected $delimiter = null; 51 52 /** 53 * Get a compound value as an array. 54 * 55 * @param $name string 56 * @return array 57 */ 58 public function getParts() { 59 60 if (is_null($this->value)) { 61 return array(); 62 } 63 64 $delimiter = $this->getDelimiter(); 65 66 // split by any $delimiter which is NOT prefixed by a slash. 67 // Note that this is not a a perfect solution. If a value is prefixed 68 // by two slashes, it should actually be split anyway. 69 // 70 // Hopefully we can fix this better in a future version, where we can 71 // break compatibility a bit. 72 $compoundValues = preg_split("/(?<!\\\)$delimiter/", $this->value); 73 74 // remove slashes from any semicolon and comma left escaped in the single values 75 $compoundValues = array_map( 76 function($val) { 77 return strtr($val, array('\,' => ',', '\;' => ';')); 78 }, $compoundValues); 79 80 return $compoundValues; 81 82 } 83 84 /** 85 * Returns the delimiter for this property. 86 * 87 * @return string 88 */ 89 public function getDelimiter() { 90 91 if (!$this->delimiter) { 92 if (isset(self::$delimiterMap[$this->name])) { 93 $this->delimiter = self::$delimiterMap[$this->name]; 94 } else { 95 // To be a bit future proof, we are going to default the 96 // delimiter to ; 97 $this->delimiter = ';'; 98 } 99 } 100 return $this->delimiter; 101 102 } 103 104 /** 105 * Set a compound value as an array. 106 * 107 * 108 * @param $name string 109 * @return array 110 */ 111 public function setParts(array $values) { 112 113 // add slashes to all semicolons and commas in the single values 114 $values = array_map( 115 function($val) { 116 return strtr($val, array(',' => '\,', ';' => '\;')); 117 }, $values); 118 119 $this->setValue( 120 implode($this->getDelimiter(), $values) 121 ); 122 123 } 124 125} 126