Mercurial > hg > rc1
comparison vendor/sabre/vobject/lib/Property/VCard/DateAndOrTime.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\VCard; | |
| 4 | |
| 5 use | |
| 6 Sabre\VObject\DateTimeParser, | |
| 7 Sabre\VObject\Property\Text, | |
| 8 Sabre\VObject\Property, | |
| 9 DateTime; | |
| 10 | |
| 11 /** | |
| 12 * DateAndOrTime property | |
| 13 * | |
| 14 * This object encodes DATE-AND-OR-TIME 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 DateAndOrTime extends Property { | |
| 21 | |
| 22 /** | |
| 23 * Field separator | |
| 24 * | |
| 25 * @var null|string | |
| 26 */ | |
| 27 public $delimiter = null; | |
| 28 | |
| 29 /** | |
| 30 * Returns the type of value. | |
| 31 * | |
| 32 * This corresponds to the VALUE= parameter. Every property also has a | |
| 33 * 'default' valueType. | |
| 34 * | |
| 35 * @return string | |
| 36 */ | |
| 37 public function getValueType() { | |
| 38 | |
| 39 return "DATE-AND-OR-TIME"; | |
| 40 | |
| 41 } | |
| 42 | |
| 43 /** | |
| 44 * Sets a multi-valued property. | |
| 45 * | |
| 46 * You may also specify DateTime objects here. | |
| 47 * | |
| 48 * @param array $parts | |
| 49 * @return void | |
| 50 */ | |
| 51 public function setParts(array $parts) { | |
| 52 | |
| 53 if (count($parts)>1) { | |
| 54 throw new \InvalidArgumentException('Only one value allowed'); | |
| 55 } | |
| 56 if (isset($parts[0]) && $parts[0] instanceof \DateTime) { | |
| 57 $this->setDateTime($parts[0]); | |
| 58 } else { | |
| 59 parent::setParts($parts); | |
| 60 } | |
| 61 | |
| 62 } | |
| 63 | |
| 64 /** | |
| 65 * Updates the current value. | |
| 66 * | |
| 67 * This may be either a single, or multiple strings in an array. | |
| 68 * | |
| 69 * Instead of strings, you may also use DateTime here. | |
| 70 * | |
| 71 * @param string|array|\DateTime $value | |
| 72 * @return void | |
| 73 */ | |
| 74 public function setValue($value) { | |
| 75 | |
| 76 if ($value instanceof \DateTime) { | |
| 77 $this->setDateTime($value); | |
| 78 } else { | |
| 79 parent::setValue($value); | |
| 80 } | |
| 81 | |
| 82 } | |
| 83 | |
| 84 /** | |
| 85 * Sets the property as a DateTime object. | |
| 86 * | |
| 87 * @param \DateTime $dt | |
| 88 * @return void | |
| 89 */ | |
| 90 public function setDateTime(\DateTime $dt) { | |
| 91 | |
| 92 $values = array(); | |
| 93 | |
| 94 $tz = null; | |
| 95 $isUtc = false; | |
| 96 | |
| 97 $tz = $dt->getTimeZone(); | |
| 98 $isUtc = in_array($tz->getName() , array('UTC', 'GMT', 'Z')); | |
| 99 | |
| 100 if ($isUtc) { | |
| 101 $value = $dt->format('Ymd\\THis\\Z'); | |
| 102 } else { | |
| 103 // Calculating the offset. | |
| 104 $value = $dt->format('Ymd\\THisO'); | |
| 105 } | |
| 106 | |
| 107 $this->value = $value; | |
| 108 | |
| 109 } | |
| 110 | |
| 111 /** | |
| 112 * Returns a date-time value. | |
| 113 * | |
| 114 * Note that if this property contained more than 1 date-time, only the | |
| 115 * first will be returned. To get an array with multiple values, call | |
| 116 * getDateTimes. | |
| 117 * | |
| 118 * If no time was specified, we will always use midnight (in the default | |
| 119 * timezone) as the time. | |
| 120 * | |
| 121 * If parts of the date were omitted, such as the year, we will grab the | |
| 122 * current values for those. So at the time of writing, if the year was | |
| 123 * omitted, we would have filled in 2014. | |
| 124 * | |
| 125 * @return \DateTime | |
| 126 */ | |
| 127 public function getDateTime() { | |
| 128 | |
| 129 $dts = array(); | |
| 130 $now = new DateTime(); | |
| 131 | |
| 132 $tzFormat = $now->getTimezone()->getOffset($now)===0?'\\Z':'O'; | |
| 133 $nowParts = DateTimeParser::parseVCardDateTime($now->format('Ymd\\This' . $tzFormat)); | |
| 134 | |
| 135 $value = $this->getValue(); | |
| 136 | |
| 137 $dateParts = DateTimeParser::parseVCardDateTime($this->getValue()); | |
| 138 | |
| 139 // This sets all the missing parts to the current date/time. | |
| 140 // So if the year was missing for a birthday, we're making it 'this | |
| 141 // year'. | |
| 142 foreach($dateParts as $k=>$v) { | |
| 143 if (is_null($v)) { | |
| 144 $dateParts[$k] = $nowParts[$k]; | |
| 145 } | |
| 146 } | |
| 147 return new DateTime("$dateParts[year]-$dateParts[month]-$dateParts[date] $dateParts[hour]:$dateParts[minute]:$dateParts[second] $dateParts[timezone]"); | |
| 148 | |
| 149 } | |
| 150 | |
| 151 /** | |
| 152 * Returns the value, in the format it should be encoded for json. | |
| 153 * | |
| 154 * This method must always return an array. | |
| 155 * | |
| 156 * @return array | |
| 157 */ | |
| 158 public function getJsonValue() { | |
| 159 | |
| 160 $parts = DateTimeParser::parseVCardDateTime($this->getValue()); | |
| 161 | |
| 162 $dateStr = ''; | |
| 163 | |
| 164 // Year | |
| 165 if (!is_null($parts['year'])) { | |
| 166 $dateStr.=$parts['year']; | |
| 167 | |
| 168 if (!is_null($parts['month'])) { | |
| 169 // If a year and a month is set, we need to insert a separator | |
| 170 // dash. | |
| 171 $dateStr.='-'; | |
| 172 } | |
| 173 | |
| 174 } else { | |
| 175 | |
| 176 if (!is_null($parts['month']) || !is_null($parts['date'])) { | |
| 177 // Inserting two dashes | |
| 178 $dateStr.='--'; | |
| 179 } | |
| 180 | |
| 181 } | |
| 182 | |
| 183 // Month | |
| 184 | |
| 185 if (!is_null($parts['month'])) { | |
| 186 $dateStr.=$parts['month']; | |
| 187 | |
| 188 if (isset($parts['date'])) { | |
| 189 // If month and date are set, we need the separator dash. | |
| 190 $dateStr.='-'; | |
| 191 } | |
| 192 } else { | |
| 193 if (isset($parts['date'])) { | |
| 194 // If the month is empty, and a date is set, we need a 'empty | |
| 195 // dash' | |
| 196 $dateStr.='-'; | |
| 197 } | |
| 198 } | |
| 199 | |
| 200 // Date | |
| 201 if (!is_null($parts['date'])) { | |
| 202 $dateStr.=$parts['date']; | |
| 203 } | |
| 204 | |
| 205 | |
| 206 // Early exit if we don't have a time string. | |
| 207 if (is_null($parts['hour']) && is_null($parts['minute']) && is_null($parts['second'])) { | |
| 208 return array($dateStr); | |
| 209 } | |
| 210 | |
| 211 $dateStr.='T'; | |
| 212 | |
| 213 // Hour | |
| 214 if (!is_null($parts['hour'])) { | |
| 215 $dateStr.=$parts['hour']; | |
| 216 | |
| 217 if (!is_null($parts['minute'])) { | |
| 218 $dateStr.=':'; | |
| 219 } | |
| 220 } else { | |
| 221 // We know either minute or second _must_ be set, so we insert a | |
| 222 // dash for an empty value. | |
| 223 $dateStr.='-'; | |
| 224 } | |
| 225 | |
| 226 // Minute | |
| 227 if (!is_null($parts['minute'])) { | |
| 228 $dateStr.=$parts['minute']; | |
| 229 | |
| 230 if (!is_null($parts['second'])) { | |
| 231 $dateStr.=':'; | |
| 232 } | |
| 233 } else { | |
| 234 if (isset($parts['second'])) { | |
| 235 // Dash for empty minute | |
| 236 $dateStr.='-'; | |
| 237 } | |
| 238 } | |
| 239 | |
| 240 // Second | |
| 241 if (!is_null($parts['second'])) { | |
| 242 $dateStr.=$parts['second']; | |
| 243 } | |
| 244 | |
| 245 // Timezone | |
| 246 if (!is_null($parts['timezone'])) { | |
| 247 $dateStr.=$parts['timezone']; | |
| 248 } | |
| 249 | |
| 250 return array($dateStr); | |
| 251 | |
| 252 } | |
| 253 | |
| 254 /** | |
| 255 * Sets a raw value coming from a mimedir (iCalendar/vCard) file. | |
| 256 * | |
| 257 * This has been 'unfolded', so only 1 line will be passed. Unescaping is | |
| 258 * not yet done, but parameters are not included. | |
| 259 * | |
| 260 * @param string $val | |
| 261 * @return void | |
| 262 */ | |
| 263 public function setRawMimeDirValue($val) { | |
| 264 | |
| 265 $this->setValue($val); | |
| 266 | |
| 267 } | |
| 268 | |
| 269 /** | |
| 270 * Returns a raw mime-dir representation of the value. | |
| 271 * | |
| 272 * @return string | |
| 273 */ | |
| 274 public function getRawMimeDirValue() { | |
| 275 | |
| 276 return implode($this->delimiter, $this->getParts()); | |
| 277 | |
| 278 } | |
| 279 | |
| 280 /** | |
| 281 * Validates the node for correctness. | |
| 282 * | |
| 283 * The following options are supported: | |
| 284 * Node::REPAIR - May attempt to automatically repair the problem. | |
| 285 * | |
| 286 * This method returns an array with detected problems. | |
| 287 * Every element has the following properties: | |
| 288 * | |
| 289 * * level - problem level. | |
| 290 * * message - A human-readable string describing the issue. | |
| 291 * * node - A reference to the problematic node. | |
| 292 * | |
| 293 * The level means: | |
| 294 * 1 - The issue was repaired (only happens if REPAIR was turned on) | |
| 295 * 2 - An inconsequential issue | |
| 296 * 3 - A severe issue. | |
| 297 * | |
| 298 * @param int $options | |
| 299 * @return array | |
| 300 */ | |
| 301 public function validate($options = 0) { | |
| 302 | |
| 303 $messages = parent::validate($options); | |
| 304 $value = $this->getValue(); | |
| 305 try { | |
| 306 DateTimeParser::parseVCardDateTime($value); | |
| 307 } catch (\InvalidArgumentException $e) { | |
| 308 $messages[] = array( | |
| 309 'level' => 3, | |
| 310 'message' => 'The supplied value (' . $value . ') is not a correct DATE-AND-OR-TIME property', | |
| 311 'node' => $this, | |
| 312 ); | |
| 313 } | |
| 314 return $messages; | |
| 315 | |
| 316 } | |
| 317 } |
