commit vendor
This commit is contained in:
60
vendor/sabre/vobject/lib/Property/ICalendar/CalAddress.php
vendored
Normal file
60
vendor/sabre/vobject/lib/Property/ICalendar/CalAddress.php
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Sabre\VObject\Property\ICalendar;
|
||||
|
||||
use
|
||||
Sabre\VObject\Property\Text;
|
||||
|
||||
/**
|
||||
* CalAddress property.
|
||||
*
|
||||
* This object encodes CAL-ADDRESS values, as defined in rfc5545
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class CalAddress extends Text
|
||||
{
|
||||
/**
|
||||
* In case this is a multi-value property. This string will be used as a
|
||||
* delimiter.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $delimiter = null;
|
||||
|
||||
/**
|
||||
* Returns the type of value.
|
||||
*
|
||||
* This corresponds to the VALUE= parameter. Every property also has a
|
||||
* 'default' valueType.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValueType()
|
||||
{
|
||||
return 'CAL-ADDRESS';
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns a normalized form of the value.
|
||||
*
|
||||
* This is primarily used right now to turn mixed-cased schemes in user
|
||||
* uris to lower-case.
|
||||
*
|
||||
* Evolution in particular tends to encode mailto: as MAILTO:.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNormalizedValue()
|
||||
{
|
||||
$input = $this->getValue();
|
||||
if (!strpos($input, ':')) {
|
||||
return $input;
|
||||
}
|
||||
list($schema, $everythingElse) = explode(':', $input, 2);
|
||||
|
||||
return strtolower($schema).':'.$everythingElse;
|
||||
}
|
||||
}
|
||||
18
vendor/sabre/vobject/lib/Property/ICalendar/Date.php
vendored
Normal file
18
vendor/sabre/vobject/lib/Property/ICalendar/Date.php
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Sabre\VObject\Property\ICalendar;
|
||||
|
||||
/**
|
||||
* DateTime property.
|
||||
*
|
||||
* This object represents DATE values, as defined here:
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc5545#section-3.3.5
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Date extends DateTime
|
||||
{
|
||||
}
|
||||
363
vendor/sabre/vobject/lib/Property/ICalendar/DateTime.php
vendored
Normal file
363
vendor/sabre/vobject/lib/Property/ICalendar/DateTime.php
vendored
Normal file
@ -0,0 +1,363 @@
|
||||
<?php
|
||||
|
||||
namespace Sabre\VObject\Property\ICalendar;
|
||||
|
||||
use DateTimeInterface;
|
||||
use DateTimeZone;
|
||||
use Sabre\VObject\DateTimeParser;
|
||||
use Sabre\VObject\InvalidDataException;
|
||||
use Sabre\VObject\Property;
|
||||
use Sabre\VObject\TimeZoneUtil;
|
||||
|
||||
/**
|
||||
* DateTime property.
|
||||
*
|
||||
* This object represents DATE-TIME values, as defined here:
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc5545#section-3.3.4
|
||||
*
|
||||
* This particular object has a bit of hackish magic that it may also in some
|
||||
* cases represent a DATE value. This is because it's a common usecase to be
|
||||
* able to change a DATE-TIME into a DATE.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class DateTime extends Property
|
||||
{
|
||||
/**
|
||||
* In case this is a multi-value property. This string will be used as a
|
||||
* delimiter.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $delimiter = ',';
|
||||
|
||||
/**
|
||||
* Sets a multi-valued property.
|
||||
*
|
||||
* You may also specify DateTime objects here.
|
||||
*/
|
||||
public function setParts(array $parts)
|
||||
{
|
||||
if (isset($parts[0]) && $parts[0] instanceof DateTimeInterface) {
|
||||
$this->setDateTimes($parts);
|
||||
} else {
|
||||
parent::setParts($parts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the current value.
|
||||
*
|
||||
* This may be either a single, or multiple strings in an array.
|
||||
*
|
||||
* Instead of strings, you may also use DateTime here.
|
||||
*
|
||||
* @param string|array|DateTimeInterface $value
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
if (is_array($value) && isset($value[0]) && $value[0] instanceof DateTimeInterface) {
|
||||
$this->setDateTimes($value);
|
||||
} elseif ($value instanceof DateTimeInterface) {
|
||||
$this->setDateTimes([$value]);
|
||||
} else {
|
||||
parent::setValue($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a raw value coming from a mimedir (iCalendar/vCard) file.
|
||||
*
|
||||
* This has been 'unfolded', so only 1 line will be passed. Unescaping is
|
||||
* not yet done, but parameters are not included.
|
||||
*
|
||||
* @param string $val
|
||||
*/
|
||||
public function setRawMimeDirValue($val)
|
||||
{
|
||||
$this->setValue(explode($this->delimiter, $val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a raw mime-dir representation of the value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRawMimeDirValue()
|
||||
{
|
||||
return implode($this->delimiter, $this->getParts());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a DATE-TIME value, false if it's a DATE.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasTime()
|
||||
{
|
||||
return 'DATE' !== strtoupper((string) $this['VALUE']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a floating DATE or DATE-TIME.
|
||||
*
|
||||
* Note that DATE is always floating.
|
||||
*/
|
||||
public function isFloating()
|
||||
{
|
||||
return
|
||||
!$this->hasTime() ||
|
||||
(
|
||||
!isset($this['TZID']) &&
|
||||
false === strpos($this->getValue(), 'Z')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a date-time value.
|
||||
*
|
||||
* Note that if this property contained more than 1 date-time, only the
|
||||
* first will be returned. To get an array with multiple values, call
|
||||
* getDateTimes.
|
||||
*
|
||||
* If no timezone information is known, because it's either an all-day
|
||||
* property or floating time, we will use the DateTimeZone argument to
|
||||
* figure out the exact date.
|
||||
*
|
||||
* @param DateTimeZone $timeZone
|
||||
*
|
||||
* @return \DateTimeImmutable
|
||||
*/
|
||||
public function getDateTime(DateTimeZone $timeZone = null)
|
||||
{
|
||||
$dt = $this->getDateTimes($timeZone);
|
||||
if (!$dt) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $dt[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns multiple date-time values.
|
||||
*
|
||||
* If no timezone information is known, because it's either an all-day
|
||||
* property or floating time, we will use the DateTimeZone argument to
|
||||
* figure out the exact date.
|
||||
*
|
||||
* @param DateTimeZone $timeZone
|
||||
*
|
||||
* @return \DateTimeImmutable[]
|
||||
* @return \DateTime[]
|
||||
*/
|
||||
public function getDateTimes(DateTimeZone $timeZone = null)
|
||||
{
|
||||
// Does the property have a TZID?
|
||||
$tzid = $this['TZID'];
|
||||
|
||||
if ($tzid) {
|
||||
$timeZone = TimeZoneUtil::getTimeZone((string) $tzid, $this->root);
|
||||
}
|
||||
|
||||
$dts = [];
|
||||
foreach ($this->getParts() as $part) {
|
||||
$dts[] = DateTimeParser::parse($part, $timeZone);
|
||||
}
|
||||
|
||||
return $dts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the property as a DateTime object.
|
||||
*
|
||||
* @param bool isFloating If set to true, timezones will be ignored
|
||||
*/
|
||||
public function setDateTime(DateTimeInterface $dt, $isFloating = false)
|
||||
{
|
||||
$this->setDateTimes([$dt], $isFloating);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the property as multiple date-time objects.
|
||||
*
|
||||
* The first value will be used as a reference for the timezones, and all
|
||||
* the otehr values will be adjusted for that timezone
|
||||
*
|
||||
* @param DateTimeInterface[] $dt
|
||||
* @param bool isFloating If set to true, timezones will be ignored
|
||||
*/
|
||||
public function setDateTimes(array $dt, $isFloating = false)
|
||||
{
|
||||
$values = [];
|
||||
|
||||
if ($this->hasTime()) {
|
||||
$tz = null;
|
||||
$isUtc = false;
|
||||
|
||||
foreach ($dt as $d) {
|
||||
if ($isFloating) {
|
||||
$values[] = $d->format('Ymd\\THis');
|
||||
continue;
|
||||
}
|
||||
if (is_null($tz)) {
|
||||
$tz = $d->getTimeZone();
|
||||
$isUtc = in_array($tz->getName(), ['UTC', 'GMT', 'Z', '+00:00']);
|
||||
if (!$isUtc) {
|
||||
$this->offsetSet('TZID', $tz->getName());
|
||||
}
|
||||
} else {
|
||||
$d = $d->setTimeZone($tz);
|
||||
}
|
||||
|
||||
if ($isUtc) {
|
||||
$values[] = $d->format('Ymd\\THis\\Z');
|
||||
} else {
|
||||
$values[] = $d->format('Ymd\\THis');
|
||||
}
|
||||
}
|
||||
if ($isUtc || $isFloating) {
|
||||
$this->offsetUnset('TZID');
|
||||
}
|
||||
} else {
|
||||
foreach ($dt as $d) {
|
||||
$values[] = $d->format('Ymd');
|
||||
}
|
||||
$this->offsetUnset('TZID');
|
||||
}
|
||||
|
||||
$this->value = $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of value.
|
||||
*
|
||||
* This corresponds to the VALUE= parameter. Every property also has a
|
||||
* 'default' valueType.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValueType()
|
||||
{
|
||||
return $this->hasTime() ? 'DATE-TIME' : 'DATE';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value, in the format it should be encoded for JSON.
|
||||
*
|
||||
* This method must always return an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getJsonValue()
|
||||
{
|
||||
$dts = $this->getDateTimes();
|
||||
$hasTime = $this->hasTime();
|
||||
$isFloating = $this->isFloating();
|
||||
|
||||
$tz = $dts[0]->getTimeZone();
|
||||
$isUtc = $isFloating ? false : in_array($tz->getName(), ['UTC', 'GMT', 'Z']);
|
||||
|
||||
return array_map(
|
||||
function (DateTimeInterface $dt) use ($hasTime, $isUtc) {
|
||||
if ($hasTime) {
|
||||
return $dt->format('Y-m-d\\TH:i:s').($isUtc ? 'Z' : '');
|
||||
} else {
|
||||
return $dt->format('Y-m-d');
|
||||
}
|
||||
},
|
||||
$dts
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the json value, as it would appear in a jCard or jCal object.
|
||||
*
|
||||
* The value must always be an array.
|
||||
*/
|
||||
public function setJsonValue(array $value)
|
||||
{
|
||||
// dates and times in jCal have one difference to dates and times in
|
||||
// iCalendar. In jCal date-parts are separated by dashes, and
|
||||
// time-parts are separated by colons. It makes sense to just remove
|
||||
// those.
|
||||
$this->setValue(
|
||||
array_map(
|
||||
function ($item) {
|
||||
return strtr($item, [':' => '', '-' => '']);
|
||||
},
|
||||
$value
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to intercept offsetSet, because it may be used to alter the
|
||||
* VALUE from DATE-TIME to DATE or vice-versa.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function offsetSet($name, $value)
|
||||
{
|
||||
parent::offsetSet($name, $value);
|
||||
if ('VALUE' !== strtoupper($name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This will ensure that dates are correctly encoded.
|
||||
$this->setDateTimes($this->getDateTimes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the node for correctness.
|
||||
*
|
||||
* The following options are supported:
|
||||
* Node::REPAIR - May attempt to automatically repair the problem.
|
||||
*
|
||||
* This method returns an array with detected problems.
|
||||
* Every element has the following properties:
|
||||
*
|
||||
* * level - problem level.
|
||||
* * message - A human-readable string describing the issue.
|
||||
* * node - A reference to the problematic node.
|
||||
*
|
||||
* The level means:
|
||||
* 1 - The issue was repaired (only happens if REPAIR was turned on)
|
||||
* 2 - An inconsequential issue
|
||||
* 3 - A severe issue.
|
||||
*
|
||||
* @param int $options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function validate($options = 0)
|
||||
{
|
||||
$messages = parent::validate($options);
|
||||
$valueType = $this->getValueType();
|
||||
$values = $this->getParts();
|
||||
foreach ($values as $value) {
|
||||
try {
|
||||
switch ($valueType) {
|
||||
case 'DATE':
|
||||
DateTimeParser::parseDate($value);
|
||||
break;
|
||||
case 'DATE-TIME':
|
||||
DateTimeParser::parseDateTime($value);
|
||||
break;
|
||||
}
|
||||
} catch (InvalidDataException $e) {
|
||||
$messages[] = [
|
||||
'level' => 3,
|
||||
'message' => 'The supplied value ('.$value.') is not a correct '.$valueType,
|
||||
'node' => $this,
|
||||
];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
}
|
||||
79
vendor/sabre/vobject/lib/Property/ICalendar/Duration.php
vendored
Normal file
79
vendor/sabre/vobject/lib/Property/ICalendar/Duration.php
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Sabre\VObject\Property\ICalendar;
|
||||
|
||||
use Sabre\VObject\DateTimeParser;
|
||||
use Sabre\VObject\Property;
|
||||
|
||||
/**
|
||||
* Duration property.
|
||||
*
|
||||
* This object represents DURATION values, as defined here:
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc5545#section-3.3.6
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Duration extends Property
|
||||
{
|
||||
/**
|
||||
* In case this is a multi-value property. This string will be used as a
|
||||
* delimiter.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $delimiter = ',';
|
||||
|
||||
/**
|
||||
* Sets a raw value coming from a mimedir (iCalendar/vCard) file.
|
||||
*
|
||||
* This has been 'unfolded', so only 1 line will be passed. Unescaping is
|
||||
* not yet done, but parameters are not included.
|
||||
*
|
||||
* @param string $val
|
||||
*/
|
||||
public function setRawMimeDirValue($val)
|
||||
{
|
||||
$this->setValue(explode($this->delimiter, $val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a raw mime-dir representation of the value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRawMimeDirValue()
|
||||
{
|
||||
return implode($this->delimiter, $this->getParts());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of value.
|
||||
*
|
||||
* This corresponds to the VALUE= parameter. Every property also has a
|
||||
* 'default' valueType.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValueType()
|
||||
{
|
||||
return 'DURATION';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DateInterval representation of the Duration property.
|
||||
*
|
||||
* If the property has more than one value, only the first is returned.
|
||||
*
|
||||
* @return \DateInterval
|
||||
*/
|
||||
public function getDateInterval()
|
||||
{
|
||||
$parts = $this->getParts();
|
||||
$value = $parts[0];
|
||||
|
||||
return DateTimeParser::parseDuration($value);
|
||||
}
|
||||
}
|
||||
135
vendor/sabre/vobject/lib/Property/ICalendar/Period.php
vendored
Normal file
135
vendor/sabre/vobject/lib/Property/ICalendar/Period.php
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
namespace Sabre\VObject\Property\ICalendar;
|
||||
|
||||
use Sabre\VObject\DateTimeParser;
|
||||
use Sabre\VObject\Property;
|
||||
use Sabre\Xml;
|
||||
|
||||
/**
|
||||
* Period property.
|
||||
*
|
||||
* This object represents PERIOD values, as defined here:
|
||||
*
|
||||
* http://tools.ietf.org/html/rfc5545#section-3.8.2.6
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Period extends Property
|
||||
{
|
||||
/**
|
||||
* In case this is a multi-value property. This string will be used as a
|
||||
* delimiter.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $delimiter = ',';
|
||||
|
||||
/**
|
||||
* Sets a raw value coming from a mimedir (iCalendar/vCard) file.
|
||||
*
|
||||
* This has been 'unfolded', so only 1 line will be passed. Unescaping is
|
||||
* not yet done, but parameters are not included.
|
||||
*
|
||||
* @param string $val
|
||||
*/
|
||||
public function setRawMimeDirValue($val)
|
||||
{
|
||||
$this->setValue(explode($this->delimiter, $val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a raw mime-dir representation of the value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRawMimeDirValue()
|
||||
{
|
||||
return implode($this->delimiter, $this->getParts());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of value.
|
||||
*
|
||||
* This corresponds to the VALUE= parameter. Every property also has a
|
||||
* 'default' valueType.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValueType()
|
||||
{
|
||||
return 'PERIOD';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the json value, as it would appear in a jCard or jCal object.
|
||||
*
|
||||
* The value must always be an array.
|
||||
*/
|
||||
public function setJsonValue(array $value)
|
||||
{
|
||||
$value = array_map(
|
||||
function ($item) {
|
||||
return strtr(implode('/', $item), [':' => '', '-' => '']);
|
||||
},
|
||||
$value
|
||||
);
|
||||
parent::setJsonValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value, in the format it should be encoded for json.
|
||||
*
|
||||
* This method must always return an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getJsonValue()
|
||||
{
|
||||
$return = [];
|
||||
foreach ($this->getParts() as $item) {
|
||||
list($start, $end) = explode('/', $item, 2);
|
||||
|
||||
$start = DateTimeParser::parseDateTime($start);
|
||||
|
||||
// This is a duration value.
|
||||
if ('P' === $end[0]) {
|
||||
$return[] = [
|
||||
$start->format('Y-m-d\\TH:i:s'),
|
||||
$end,
|
||||
];
|
||||
} else {
|
||||
$end = DateTimeParser::parseDateTime($end);
|
||||
$return[] = [
|
||||
$start->format('Y-m-d\\TH:i:s'),
|
||||
$end->format('Y-m-d\\TH:i:s'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method serializes only the value of a property. This is used to
|
||||
* create xCard or xCal documents.
|
||||
*
|
||||
* @param Xml\Writer $writer XML writer
|
||||
*/
|
||||
protected function xmlSerializeValue(Xml\Writer $writer)
|
||||
{
|
||||
$writer->startElement(strtolower($this->getValueType()));
|
||||
$value = $this->getJsonValue();
|
||||
$writer->writeElement('start', $value[0][0]);
|
||||
|
||||
if ('P' === $value[0][1][0]) {
|
||||
$writer->writeElement('duration', $value[0][1]);
|
||||
} else {
|
||||
$writer->writeElement('end', $value[0][1]);
|
||||
}
|
||||
|
||||
$writer->endElement();
|
||||
}
|
||||
}
|
||||
336
vendor/sabre/vobject/lib/Property/ICalendar/Recur.php
vendored
Normal file
336
vendor/sabre/vobject/lib/Property/ICalendar/Recur.php
vendored
Normal file
@ -0,0 +1,336 @@
|
||||
<?php
|
||||
|
||||
namespace Sabre\VObject\Property\ICalendar;
|
||||
|
||||
use Sabre\VObject\Property;
|
||||
use Sabre\Xml;
|
||||
|
||||
/**
|
||||
* Recur property.
|
||||
*
|
||||
* This object represents RECUR properties.
|
||||
* These values are just used for RRULE and the now deprecated EXRULE.
|
||||
*
|
||||
* The RRULE property may look something like this:
|
||||
*
|
||||
* RRULE:FREQ=MONTHLY;BYDAY=1,2,3;BYHOUR=5.
|
||||
*
|
||||
* This property exposes this as a key=>value array that is accessible using
|
||||
* getParts, and may be set using setParts.
|
||||
*
|
||||
* @copyright Copyright (C) fruux GmbH (https://fruux.com/)
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://sabre.io/license/ Modified BSD License
|
||||
*/
|
||||
class Recur extends Property
|
||||
{
|
||||
/**
|
||||
* Updates the current value.
|
||||
*
|
||||
* This may be either a single, or multiple strings in an array.
|
||||
*
|
||||
* @param string|array $value
|
||||
*/
|
||||
public function setValue($value)
|
||||
{
|
||||
// If we're getting the data from json, we'll be receiving an object
|
||||
if ($value instanceof \StdClass) {
|
||||
$value = (array) $value;
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
$newVal = [];
|
||||
foreach ($value as $k => $v) {
|
||||
if (is_string($v)) {
|
||||
$v = strtoupper($v);
|
||||
|
||||
// The value had multiple sub-values
|
||||
if (false !== strpos($v, ',')) {
|
||||
$v = explode(',', $v);
|
||||
}
|
||||
if (0 === strcmp($k, 'until')) {
|
||||
$v = strtr($v, [':' => '', '-' => '']);
|
||||
}
|
||||
} elseif (is_array($v)) {
|
||||
$v = array_map('strtoupper', $v);
|
||||
}
|
||||
|
||||
$newVal[strtoupper($k)] = $v;
|
||||
}
|
||||
$this->value = $newVal;
|
||||
} elseif (is_string($value)) {
|
||||
$this->value = self::stringToArray($value);
|
||||
} else {
|
||||
throw new \InvalidArgumentException('You must either pass a string, or a key=>value array');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current value.
|
||||
*
|
||||
* This method will always return a singular value. If this was a
|
||||
* multi-value object, some decision will be made first on how to represent
|
||||
* it as a string.
|
||||
*
|
||||
* To get the correct multi-value version, use getParts.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
$out = [];
|
||||
foreach ($this->value as $key => $value) {
|
||||
$out[] = $key.'='.(is_array($value) ? implode(',', $value) : $value);
|
||||
}
|
||||
|
||||
return strtoupper(implode(';', $out));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a multi-valued property.
|
||||
*/
|
||||
public function setParts(array $parts)
|
||||
{
|
||||
$this->setValue($parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a multi-valued property.
|
||||
*
|
||||
* This method always returns an array, if there was only a single value,
|
||||
* it will still be wrapped in an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getParts()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a raw value coming from a mimedir (iCalendar/vCard) file.
|
||||
*
|
||||
* This has been 'unfolded', so only 1 line will be passed. Unescaping is
|
||||
* not yet done, but parameters are not included.
|
||||
*
|
||||
* @param string $val
|
||||
*/
|
||||
public function setRawMimeDirValue($val)
|
||||
{
|
||||
$this->setValue($val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a raw mime-dir representation of the value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRawMimeDirValue()
|
||||
{
|
||||
return $this->getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of value.
|
||||
*
|
||||
* This corresponds to the VALUE= parameter. Every property also has a
|
||||
* 'default' valueType.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getValueType()
|
||||
{
|
||||
return 'RECUR';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value, in the format it should be encoded for json.
|
||||
*
|
||||
* This method must always return an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getJsonValue()
|
||||
{
|
||||
$values = [];
|
||||
foreach ($this->getParts() as $k => $v) {
|
||||
if (0 === strcmp($k, 'UNTIL')) {
|
||||
$date = new DateTime($this->root, null, $v);
|
||||
$values[strtolower($k)] = $date->getJsonValue()[0];
|
||||
} elseif (0 === strcmp($k, 'COUNT')) {
|
||||
$values[strtolower($k)] = intval($v);
|
||||
} else {
|
||||
$values[strtolower($k)] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return [$values];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method serializes only the value of a property. This is used to
|
||||
* create xCard or xCal documents.
|
||||
*
|
||||
* @param Xml\Writer $writer XML writer
|
||||
*/
|
||||
protected function xmlSerializeValue(Xml\Writer $writer)
|
||||
{
|
||||
$valueType = strtolower($this->getValueType());
|
||||
|
||||
foreach ($this->getJsonValue() as $value) {
|
||||
$writer->writeElement($valueType, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an RRULE value string, and turns it into a struct-ish array.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function stringToArray($value)
|
||||
{
|
||||
$value = strtoupper($value);
|
||||
$newValue = [];
|
||||
foreach (explode(';', $value) as $part) {
|
||||
// Skipping empty parts.
|
||||
if (empty($part)) {
|
||||
continue;
|
||||
}
|
||||
list($partName, $partValue) = explode('=', $part);
|
||||
|
||||
// The value itself had multiple values..
|
||||
if (false !== strpos($partValue, ',')) {
|
||||
$partValue = explode(',', $partValue);
|
||||
}
|
||||
$newValue[$partName] = $partValue;
|
||||
}
|
||||
|
||||
return $newValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the node for correctness.
|
||||
*
|
||||
* The following options are supported:
|
||||
* Node::REPAIR - May attempt to automatically repair the problem.
|
||||
*
|
||||
* This method returns an array with detected problems.
|
||||
* Every element has the following properties:
|
||||
*
|
||||
* * level - problem level.
|
||||
* * message - A human-readable string describing the issue.
|
||||
* * node - A reference to the problematic node.
|
||||
*
|
||||
* The level means:
|
||||
* 1 - The issue was repaired (only happens if REPAIR was turned on)
|
||||
* 2 - An inconsequential issue
|
||||
* 3 - A severe issue.
|
||||
*
|
||||
* @param int $options
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function validate($options = 0)
|
||||
{
|
||||
$repair = ($options & self::REPAIR);
|
||||
|
||||
$warnings = parent::validate($options);
|
||||
$values = $this->getParts();
|
||||
|
||||
foreach ($values as $key => $value) {
|
||||
if ('' === $value) {
|
||||
$warnings[] = [
|
||||
'level' => $repair ? 1 : 3,
|
||||
'message' => 'Invalid value for '.$key.' in '.$this->name,
|
||||
'node' => $this,
|
||||
];
|
||||
if ($repair) {
|
||||
unset($values[$key]);
|
||||
}
|
||||
} elseif ('BYMONTH' == $key) {
|
||||
$byMonth = (array) $value;
|
||||
foreach ($byMonth as $i => $v) {
|
||||
if (!is_numeric($v) || (int) $v < 1 || (int) $v > 12) {
|
||||
$warnings[] = [
|
||||
'level' => $repair ? 1 : 3,
|
||||
'message' => 'BYMONTH in RRULE must have value(s) between 1 and 12!',
|
||||
'node' => $this,
|
||||
];
|
||||
if ($repair) {
|
||||
if (is_array($value)) {
|
||||
unset($values[$key][$i]);
|
||||
} else {
|
||||
unset($values[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if there is no valid entry left, remove the whole value
|
||||
if (is_array($value) && empty($values[$key])) {
|
||||
unset($values[$key]);
|
||||
}
|
||||
} elseif ('BYWEEKNO' == $key) {
|
||||
$byWeekNo = (array) $value;
|
||||
foreach ($byWeekNo as $i => $v) {
|
||||
if (!is_numeric($v) || (int) $v < -53 || 0 == (int) $v || (int) $v > 53) {
|
||||
$warnings[] = [
|
||||
'level' => $repair ? 1 : 3,
|
||||
'message' => 'BYWEEKNO in RRULE must have value(s) from -53 to -1, or 1 to 53!',
|
||||
'node' => $this,
|
||||
];
|
||||
if ($repair) {
|
||||
if (is_array($value)) {
|
||||
unset($values[$key][$i]);
|
||||
} else {
|
||||
unset($values[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if there is no valid entry left, remove the whole value
|
||||
if (is_array($value) && empty($values[$key])) {
|
||||
unset($values[$key]);
|
||||
}
|
||||
} elseif ('BYYEARDAY' == $key) {
|
||||
$byYearDay = (array) $value;
|
||||
foreach ($byYearDay as $i => $v) {
|
||||
if (!is_numeric($v) || (int) $v < -366 || 0 == (int) $v || (int) $v > 366) {
|
||||
$warnings[] = [
|
||||
'level' => $repair ? 1 : 3,
|
||||
'message' => 'BYYEARDAY in RRULE must have value(s) from -366 to -1, or 1 to 366!',
|
||||
'node' => $this,
|
||||
];
|
||||
if ($repair) {
|
||||
if (is_array($value)) {
|
||||
unset($values[$key][$i]);
|
||||
} else {
|
||||
unset($values[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if there is no valid entry left, remove the whole value
|
||||
if (is_array($value) && empty($values[$key])) {
|
||||
unset($values[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isset($values['FREQ'])) {
|
||||
$warnings[] = [
|
||||
'level' => $repair ? 1 : 3,
|
||||
'message' => 'FREQ is required in '.$this->name,
|
||||
'node' => $this,
|
||||
];
|
||||
if ($repair) {
|
||||
$this->parent->remove($this);
|
||||
}
|
||||
}
|
||||
if ($repair) {
|
||||
$this->setValue($values);
|
||||
}
|
||||
|
||||
return $warnings;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user