update sabre/vobject

This commit is contained in:
Mario Vavti
2019-04-25 11:47:18 +02:00
parent f1c0797780
commit a60c2f38c6
91 changed files with 2828 additions and 3749 deletions

View File

@@ -14,8 +14,8 @@ use Sabre\VObject;
* @author Ivan Enderlin
* @license http://sabre.io/license/ Modified BSD License
*/
class Available extends VObject\Component {
class Available extends VObject\Component
{
/**
* Returns the 'effective start' and 'effective end' of this VAVAILABILITY
* component.
@@ -28,8 +28,8 @@ class Available extends VObject\Component {
*
* @return array
*/
function getEffectiveStartEnd() {
public function getEffectiveStartEnd()
{
$effectiveStart = $this->DTSTART->getDateTime();
if (isset($this->DTEND)) {
$effectiveEnd = $this->DTEND->getDateTime();
@@ -38,7 +38,6 @@ class Available extends VObject\Component {
}
return [$effectiveStart, $effectiveEnd];
}
/**
@@ -56,32 +55,31 @@ class Available extends VObject\Component {
*
* @var array
*/
function getValidationRules() {
public function getValidationRules()
{
return [
'UID' => 1,
'UID' => 1,
'DTSTART' => 1,
'DTSTAMP' => 1,
'DTEND' => '?',
'DTEND' => '?',
'DURATION' => '?',
'CREATED' => '?',
'DESCRIPTION' => '?',
'CREATED' => '?',
'DESCRIPTION' => '?',
'LAST-MODIFIED' => '?',
'RECURRENCE-ID' => '?',
'RRULE' => '?',
'SUMMARY' => '?',
'RRULE' => '?',
'SUMMARY' => '?',
'CATEGORIES' => '*',
'COMMENT' => '*',
'CONTACT' => '*',
'EXDATE' => '*',
'RDATE' => '*',
'COMMENT' => '*',
'CONTACT' => '*',
'EXDATE' => '*',
'RDATE' => '*',
'AVAILABLE' => '*',
];
}
/**
@@ -108,19 +106,18 @@ class Available extends VObject\Component {
*
* @return array
*/
function validate($options = 0) {
public function validate($options = 0)
{
$result = parent::validate($options);
if (isset($this->DTEND) && isset($this->DURATION)) {
$result[] = [
'level' => 3,
'level' => 3,
'message' => 'DTEND and DURATION cannot both be present',
'node' => $this
'node' => $this,
];
}
return $result;
}
}

View File

@@ -16,8 +16,8 @@ use Sabre\VObject\InvalidDataException;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class VAlarm extends VObject\Component {
class VAlarm extends VObject\Component
{
/**
* Returns a DateTime object when this alarm is going to trigger.
*
@@ -25,17 +25,16 @@ class VAlarm extends VObject\Component {
*
* @return DateTimeImmutable
*/
function getEffectiveTriggerTime() {
public function getEffectiveTriggerTime()
{
$trigger = $this->TRIGGER;
if (!isset($trigger['VALUE']) || strtoupper($trigger['VALUE']) === 'DURATION') {
if (!isset($trigger['VALUE']) || 'DURATION' === strtoupper($trigger['VALUE'])) {
$triggerDuration = VObject\DateTimeParser::parseDuration($this->TRIGGER);
$related = (isset($trigger['RELATED']) && strtoupper($trigger['RELATED']) == 'END') ? 'END' : 'START';
$related = (isset($trigger['RELATED']) && 'END' == strtoupper($trigger['RELATED'])) ? 'END' : 'START';
$parentComponent = $this->parent;
if ($related === 'START') {
if ($parentComponent->name === 'VTODO') {
if ('START' === $related) {
if ('VTODO' === $parentComponent->name) {
$propName = 'DUE';
} else {
$propName = 'DTSTART';
@@ -44,9 +43,9 @@ class VAlarm extends VObject\Component {
$effectiveTrigger = $parentComponent->$propName->getDateTime();
$effectiveTrigger = $effectiveTrigger->add($triggerDuration);
} else {
if ($parentComponent->name === 'VTODO') {
if ('VTODO' === $parentComponent->name) {
$endProp = 'DUE';
} elseif ($parentComponent->name === 'VEVENT') {
} elseif ('VEVENT' === $parentComponent->name) {
$endProp = 'DTEND';
} else {
throw new InvalidDataException('time-range filters on VALARM components are only supported when they are a child of VTODO or VEVENT');
@@ -68,8 +67,8 @@ class VAlarm extends VObject\Component {
} else {
$effectiveTrigger = $trigger->getDateTime();
}
return $effectiveTrigger;
return $effectiveTrigger;
}
/**
@@ -84,30 +83,29 @@ class VAlarm extends VObject\Component {
*
* @return bool
*/
function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) {
public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
{
$effectiveTrigger = $this->getEffectiveTriggerTime();
if (isset($this->DURATION)) {
$duration = VObject\DateTimeParser::parseDuration($this->DURATION);
$repeat = (string)$this->REPEAT;
$repeat = (string) $this->REPEAT;
if (!$repeat) {
$repeat = 1;
}
$period = new \DatePeriod($effectiveTrigger, $duration, (int)$repeat);
$period = new \DatePeriod($effectiveTrigger, $duration, (int) $repeat);
foreach ($period as $occurrence) {
if ($start <= $occurrence && $end > $occurrence) {
return true;
}
}
return false;
} else {
return ($start <= $effectiveTrigger && $end > $effectiveTrigger);
return $start <= $effectiveTrigger && $end > $effectiveTrigger;
}
}
/**
@@ -125,18 +123,16 @@ class VAlarm extends VObject\Component {
*
* @var array
*/
function getValidationRules() {
public function getValidationRules()
{
return [
'ACTION' => 1,
'ACTION' => 1,
'TRIGGER' => 1,
'DURATION' => '?',
'REPEAT' => '?',
'REPEAT' => '?',
'ATTACH' => '?',
];
}
}

View File

@@ -15,8 +15,8 @@ use Sabre\VObject;
* @author Ivan Enderlin
* @license http://sabre.io/license/ Modified BSD License
*/
class VAvailability extends VObject\Component {
class VAvailability extends VObject\Component
{
/**
* Returns true or false depending on if the event falls in the specified
* time-range. This is used for filtering purposes.
@@ -31,14 +31,14 @@ class VAvailability extends VObject\Component {
*
* @return bool
*/
function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) {
public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
{
list($effectiveStart, $effectiveEnd) = $this->getEffectiveStartEnd();
return (
return
(is_null($effectiveStart) || $start < $effectiveEnd) &&
(is_null($effectiveEnd) || $end > $effectiveStart)
);
;
}
/**
@@ -53,8 +53,8 @@ class VAvailability extends VObject\Component {
*
* @return array
*/
function getEffectiveStartEnd() {
public function getEffectiveStartEnd()
{
$effectiveStart = null;
$effectiveEnd = null;
@@ -68,10 +68,8 @@ class VAvailability extends VObject\Component {
}
return [$effectiveStart, $effectiveEnd];
}
/**
* A simple list of validation rules.
*
@@ -87,31 +85,30 @@ class VAvailability extends VObject\Component {
*
* @var array
*/
function getValidationRules() {
public function getValidationRules()
{
return [
'UID' => 1,
'UID' => 1,
'DTSTAMP' => 1,
'BUSYTYPE' => '?',
'CLASS' => '?',
'CREATED' => '?',
'DESCRIPTION' => '?',
'DTSTART' => '?',
'BUSYTYPE' => '?',
'CLASS' => '?',
'CREATED' => '?',
'DESCRIPTION' => '?',
'DTSTART' => '?',
'LAST-MODIFIED' => '?',
'ORGANIZER' => '?',
'PRIORITY' => '?',
'SEQUENCE' => '?',
'SUMMARY' => '?',
'URL' => '?',
'DTEND' => '?',
'DURATION' => '?',
'ORGANIZER' => '?',
'PRIORITY' => '?',
'SEQUENCE' => '?',
'SUMMARY' => '?',
'URL' => '?',
'DTEND' => '?',
'DURATION' => '?',
'CATEGORIES' => '*',
'COMMENT' => '*',
'CONTACT' => '*',
'COMMENT' => '*',
'CONTACT' => '*',
];
}
/**
@@ -138,19 +135,18 @@ class VAvailability extends VObject\Component {
*
* @return array
*/
function validate($options = 0) {
public function validate($options = 0)
{
$result = parent::validate($options);
if (isset($this->DTEND) && isset($this->DURATION)) {
$result[] = [
'level' => 3,
'level' => 3,
'message' => 'DTEND and DURATION cannot both be present',
'node' => $this
'node' => $this,
];
}
return $result;
}
}

View File

@@ -20,8 +20,8 @@ use Sabre\VObject\Recur\NoInstancesException;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class VCalendar extends VObject\Document {
class VCalendar extends VObject\Document
{
/**
* The default name for this component.
*
@@ -29,23 +29,23 @@ class VCalendar extends VObject\Document {
*
* @var string
*/
static $defaultName = 'VCALENDAR';
public static $defaultName = 'VCALENDAR';
/**
* This is a list of components, and which classes they should map to.
*
* @var array
*/
static $componentMap = [
'VCALENDAR' => 'Sabre\\VObject\\Component\\VCalendar',
'VALARM' => 'Sabre\\VObject\\Component\\VAlarm',
'VEVENT' => 'Sabre\\VObject\\Component\\VEvent',
'VFREEBUSY' => 'Sabre\\VObject\\Component\\VFreeBusy',
public static $componentMap = [
'VCALENDAR' => 'Sabre\\VObject\\Component\\VCalendar',
'VALARM' => 'Sabre\\VObject\\Component\\VAlarm',
'VEVENT' => 'Sabre\\VObject\\Component\\VEvent',
'VFREEBUSY' => 'Sabre\\VObject\\Component\\VFreeBusy',
'VAVAILABILITY' => 'Sabre\\VObject\\Component\\VAvailability',
'AVAILABLE' => 'Sabre\\VObject\\Component\\Available',
'VJOURNAL' => 'Sabre\\VObject\\Component\\VJournal',
'VTIMEZONE' => 'Sabre\\VObject\\Component\\VTimeZone',
'VTODO' => 'Sabre\\VObject\\Component\\VTodo',
'AVAILABLE' => 'Sabre\\VObject\\Component\\Available',
'VJOURNAL' => 'Sabre\\VObject\\Component\\VJournal',
'VTIMEZONE' => 'Sabre\\VObject\\Component\\VTimeZone',
'VTODO' => 'Sabre\\VObject\\Component\\VTodo',
];
/**
@@ -53,22 +53,22 @@ class VCalendar extends VObject\Document {
*
* @var array
*/
static $valueMap = [
'BINARY' => 'Sabre\\VObject\\Property\\Binary',
'BOOLEAN' => 'Sabre\\VObject\\Property\\Boolean',
public static $valueMap = [
'BINARY' => 'Sabre\\VObject\\Property\\Binary',
'BOOLEAN' => 'Sabre\\VObject\\Property\\Boolean',
'CAL-ADDRESS' => 'Sabre\\VObject\\Property\\ICalendar\\CalAddress',
'DATE' => 'Sabre\\VObject\\Property\\ICalendar\\Date',
'DATE-TIME' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'DURATION' => 'Sabre\\VObject\\Property\\ICalendar\\Duration',
'FLOAT' => 'Sabre\\VObject\\Property\\FloatValue',
'INTEGER' => 'Sabre\\VObject\\Property\\IntegerValue',
'PERIOD' => 'Sabre\\VObject\\Property\\ICalendar\\Period',
'RECUR' => 'Sabre\\VObject\\Property\\ICalendar\\Recur',
'TEXT' => 'Sabre\\VObject\\Property\\Text',
'TIME' => 'Sabre\\VObject\\Property\\Time',
'UNKNOWN' => 'Sabre\\VObject\\Property\\Unknown', // jCard / jCal-only.
'URI' => 'Sabre\\VObject\\Property\\Uri',
'UTC-OFFSET' => 'Sabre\\VObject\\Property\\UtcOffset',
'DATE' => 'Sabre\\VObject\\Property\\ICalendar\\Date',
'DATE-TIME' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'DURATION' => 'Sabre\\VObject\\Property\\ICalendar\\Duration',
'FLOAT' => 'Sabre\\VObject\\Property\\FloatValue',
'INTEGER' => 'Sabre\\VObject\\Property\\IntegerValue',
'PERIOD' => 'Sabre\\VObject\\Property\\ICalendar\\Period',
'RECUR' => 'Sabre\\VObject\\Property\\ICalendar\\Recur',
'TEXT' => 'Sabre\\VObject\\Property\\Text',
'TIME' => 'Sabre\\VObject\\Property\\Time',
'UNKNOWN' => 'Sabre\\VObject\\Property\\Unknown', // jCard / jCal-only.
'URI' => 'Sabre\\VObject\\Property\\Uri',
'UTC-OFFSET' => 'Sabre\\VObject\\Property\\UtcOffset',
];
/**
@@ -76,81 +76,80 @@ class VCalendar extends VObject\Document {
*
* @var array
*/
static $propertyMap = [
public static $propertyMap = [
// Calendar properties
'CALSCALE' => 'Sabre\\VObject\\Property\\FlatText',
'METHOD' => 'Sabre\\VObject\\Property\\FlatText',
'PRODID' => 'Sabre\\VObject\\Property\\FlatText',
'VERSION' => 'Sabre\\VObject\\Property\\FlatText',
'METHOD' => 'Sabre\\VObject\\Property\\FlatText',
'PRODID' => 'Sabre\\VObject\\Property\\FlatText',
'VERSION' => 'Sabre\\VObject\\Property\\FlatText',
// Component properties
'ATTACH' => 'Sabre\\VObject\\Property\\Uri',
'CATEGORIES' => 'Sabre\\VObject\\Property\\Text',
'CLASS' => 'Sabre\\VObject\\Property\\FlatText',
'COMMENT' => 'Sabre\\VObject\\Property\\FlatText',
'DESCRIPTION' => 'Sabre\\VObject\\Property\\FlatText',
'GEO' => 'Sabre\\VObject\\Property\\FloatValue',
'LOCATION' => 'Sabre\\VObject\\Property\\FlatText',
'ATTACH' => 'Sabre\\VObject\\Property\\Uri',
'CATEGORIES' => 'Sabre\\VObject\\Property\\Text',
'CLASS' => 'Sabre\\VObject\\Property\\FlatText',
'COMMENT' => 'Sabre\\VObject\\Property\\FlatText',
'DESCRIPTION' => 'Sabre\\VObject\\Property\\FlatText',
'GEO' => 'Sabre\\VObject\\Property\\FloatValue',
'LOCATION' => 'Sabre\\VObject\\Property\\FlatText',
'PERCENT-COMPLETE' => 'Sabre\\VObject\\Property\\IntegerValue',
'PRIORITY' => 'Sabre\\VObject\\Property\\IntegerValue',
'RESOURCES' => 'Sabre\\VObject\\Property\\Text',
'STATUS' => 'Sabre\\VObject\\Property\\FlatText',
'SUMMARY' => 'Sabre\\VObject\\Property\\FlatText',
'PRIORITY' => 'Sabre\\VObject\\Property\\IntegerValue',
'RESOURCES' => 'Sabre\\VObject\\Property\\Text',
'STATUS' => 'Sabre\\VObject\\Property\\FlatText',
'SUMMARY' => 'Sabre\\VObject\\Property\\FlatText',
// Date and Time Component Properties
'COMPLETED' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'DTEND' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'DUE' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'DTSTART' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'DURATION' => 'Sabre\\VObject\\Property\\ICalendar\\Duration',
'FREEBUSY' => 'Sabre\\VObject\\Property\\ICalendar\\Period',
'TRANSP' => 'Sabre\\VObject\\Property\\FlatText',
'DTEND' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'DUE' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'DTSTART' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'DURATION' => 'Sabre\\VObject\\Property\\ICalendar\\Duration',
'FREEBUSY' => 'Sabre\\VObject\\Property\\ICalendar\\Period',
'TRANSP' => 'Sabre\\VObject\\Property\\FlatText',
// Time Zone Component Properties
'TZID' => 'Sabre\\VObject\\Property\\FlatText',
'TZNAME' => 'Sabre\\VObject\\Property\\FlatText',
'TZID' => 'Sabre\\VObject\\Property\\FlatText',
'TZNAME' => 'Sabre\\VObject\\Property\\FlatText',
'TZOFFSETFROM' => 'Sabre\\VObject\\Property\\UtcOffset',
'TZOFFSETTO' => 'Sabre\\VObject\\Property\\UtcOffset',
'TZURL' => 'Sabre\\VObject\\Property\\Uri',
'TZOFFSETTO' => 'Sabre\\VObject\\Property\\UtcOffset',
'TZURL' => 'Sabre\\VObject\\Property\\Uri',
// Relationship Component Properties
'ATTENDEE' => 'Sabre\\VObject\\Property\\ICalendar\\CalAddress',
'CONTACT' => 'Sabre\\VObject\\Property\\FlatText',
'ORGANIZER' => 'Sabre\\VObject\\Property\\ICalendar\\CalAddress',
'ATTENDEE' => 'Sabre\\VObject\\Property\\ICalendar\\CalAddress',
'CONTACT' => 'Sabre\\VObject\\Property\\FlatText',
'ORGANIZER' => 'Sabre\\VObject\\Property\\ICalendar\\CalAddress',
'RECURRENCE-ID' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'RELATED-TO' => 'Sabre\\VObject\\Property\\FlatText',
'URL' => 'Sabre\\VObject\\Property\\Uri',
'UID' => 'Sabre\\VObject\\Property\\FlatText',
'RELATED-TO' => 'Sabre\\VObject\\Property\\FlatText',
'URL' => 'Sabre\\VObject\\Property\\Uri',
'UID' => 'Sabre\\VObject\\Property\\FlatText',
// Recurrence Component Properties
'EXDATE' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'RDATE' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'RRULE' => 'Sabre\\VObject\\Property\\ICalendar\\Recur',
'RDATE' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'RRULE' => 'Sabre\\VObject\\Property\\ICalendar\\Recur',
'EXRULE' => 'Sabre\\VObject\\Property\\ICalendar\\Recur', // Deprecated since rfc5545
// Alarm Component Properties
'ACTION' => 'Sabre\\VObject\\Property\\FlatText',
'REPEAT' => 'Sabre\\VObject\\Property\\IntegerValue',
'ACTION' => 'Sabre\\VObject\\Property\\FlatText',
'REPEAT' => 'Sabre\\VObject\\Property\\IntegerValue',
'TRIGGER' => 'Sabre\\VObject\\Property\\ICalendar\\Duration',
// Change Management Component Properties
'CREATED' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'DTSTAMP' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'CREATED' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'DTSTAMP' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'LAST-MODIFIED' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'SEQUENCE' => 'Sabre\\VObject\\Property\\IntegerValue',
'SEQUENCE' => 'Sabre\\VObject\\Property\\IntegerValue',
// Request Status
'REQUEST-STATUS' => 'Sabre\\VObject\\Property\\Text',
// Additions from draft-daboo-valarm-extensions-04
'ALARM-AGENT' => 'Sabre\\VObject\\Property\\Text',
'ACKNOWLEDGED' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'PROXIMITY' => 'Sabre\\VObject\\Property\\Text',
'ALARM-AGENT' => 'Sabre\\VObject\\Property\\Text',
'ACKNOWLEDGED' => 'Sabre\\VObject\\Property\\ICalendar\\DateTime',
'PROXIMITY' => 'Sabre\\VObject\\Property\\Text',
'DEFAULT-ALARM' => 'Sabre\\VObject\\Property\\Boolean',
// Additions from draft-daboo-calendar-availability-05
'BUSYTYPE' => 'Sabre\\VObject\\Property\\Text',
];
/**
@@ -158,10 +157,9 @@ class VCalendar extends VObject\Document {
*
* @return int
*/
function getDocumentType() {
public function getDocumentType()
{
return self::ICALENDAR20;
}
/**
@@ -175,21 +173,20 @@ class VCalendar extends VObject\Document {
*
* @return VObject\Component[]
*/
function getBaseComponents($componentName = null) {
$isBaseComponent = function($component) {
public function getBaseComponents($componentName = null)
{
$isBaseComponent = function ($component) {
if (!$component instanceof VObject\Component) {
return false;
}
if ($component->name === 'VTIMEZONE') {
if ('VTIMEZONE' === $component->name) {
return false;
}
if (isset($component->{'RECURRENCE-ID'})) {
return false;
}
return true;
return true;
};
if ($componentName) {
@@ -202,9 +199,7 @@ class VCalendar extends VObject\Document {
$components = [];
foreach ($this->children as $childGroup) {
foreach ($childGroup as $child) {
if (!$child instanceof Component) {
// If one child is not a component, they all are so we skip
// the entire group.
@@ -213,12 +208,10 @@ class VCalendar extends VObject\Document {
if ($isBaseComponent($child)) {
$components[] = $child;
}
}
}
return $components;
return $components;
}
/**
@@ -231,21 +224,20 @@ class VCalendar extends VObject\Document {
*
* @return VObject\Component|null
*/
function getBaseComponent($componentName = null) {
$isBaseComponent = function($component) {
public function getBaseComponent($componentName = null)
{
$isBaseComponent = function ($component) {
if (!$component instanceof VObject\Component) {
return false;
}
if ($component->name === 'VTIMEZONE') {
if ('VTIMEZONE' === $component->name) {
return false;
}
if (isset($component->{'RECURRENCE-ID'})) {
return false;
}
return true;
return true;
};
if ($componentName) {
@@ -254,6 +246,7 @@ class VCalendar extends VObject\Document {
return $child;
}
}
return null;
}
@@ -264,10 +257,9 @@ class VCalendar extends VObject\Document {
return $child;
}
}
}
return null;
return null;
}
/**
@@ -277,7 +269,7 @@ class VCalendar extends VObject\Document {
* If this calendar object, has events with recurrence rules, this method
* can be used to expand the event into multiple sub-events.
*
* Each event will be stripped from it's recurrence information, and only
* Each event will be stripped from its recurrence information, and only
* the instances of the event in the specified timerange will be left
* alone.
*
@@ -286,12 +278,13 @@ class VCalendar extends VObject\Document {
*
* @param DateTimeInterface $start
* @param DateTimeInterface $end
* @param DateTimeZone $timeZone reference timezone for floating dates and
* times.
* @param DateTimeZone $timeZone reference timezone for floating dates and
* times
*
* @return VCalendar
*/
function expand(DateTimeInterface $start, DateTimeInterface $end, DateTimeZone $timeZone = null) {
public function expand(DateTimeInterface $start, DateTimeInterface $end, DateTimeZone $timeZone = null)
{
$newChildren = [];
$recurringEvents = [];
@@ -299,11 +292,9 @@ class VCalendar extends VObject\Document {
$timeZone = new DateTimeZone('UTC');
}
$stripTimezones = function(Component $component) use ($timeZone, &$stripTimezones) {
$stripTimezones = function (Component $component) use ($timeZone, &$stripTimezones) {
foreach ($component->children() as $componentChild) {
if ($componentChild instanceof Property\ICalendar\DateTime && $componentChild->hasTime()) {
$dt = $componentChild->getDateTimes($timeZone);
// We only need to update the first timezone, because
// setDateTimes will match all other timezones to the
@@ -313,25 +304,22 @@ class VCalendar extends VObject\Document {
} elseif ($componentChild instanceof Component) {
$stripTimezones($componentChild);
}
}
return $component;
return $component;
};
foreach ($this->children() as $child) {
if ($child instanceof Property && $child->name !== 'PRODID') {
if ($child instanceof Property && 'PRODID' !== $child->name) {
// We explictly want to ignore PRODID, because we want to
// overwrite it with our own.
$newChildren[] = clone $child;
} elseif ($child instanceof Component && $child->name !== 'VTIMEZONE') {
} elseif ($child instanceof Component && 'VTIMEZONE' !== $child->name) {
// We're also stripping all VTIMEZONE objects because we're
// converting everything to UTC.
if ($child->name === 'VEVENT' && (isset($child->{'RECURRENCE-ID'}) || isset($child->RRULE) || isset($child->RDATE))) {
if ('VEVENT' === $child->name && (isset($child->{'RECURRENCE-ID'}) || isset($child->RRULE) || isset($child->RDATE))) {
// Handle these a bit later.
$uid = (string)$child->UID;
$uid = (string) $child->UID;
if (!$uid) {
throw new InvalidDataException('Every VEVENT object must have a UID property');
}
@@ -340,19 +328,15 @@ class VCalendar extends VObject\Document {
} else {
$recurringEvents[$uid] = [clone $child];
}
} elseif ($child->name === 'VEVENT' && $child->isInTimeRange($start, $end)) {
} elseif ('VEVENT' === $child->name && $child->isInTimeRange($start, $end)) {
$newChildren[] = $stripTimezones(clone $child);
}
}
}
foreach ($recurringEvents as $events) {
try {
$it = new EventIterator($events, $timeZone);
} catch (NoInstancesException $e) {
// This event is recurring, but it doesn't have a single
// instance. We are skipping this event from the output
@@ -362,20 +346,14 @@ class VCalendar extends VObject\Document {
$it->fastForward($start);
while ($it->valid() && $it->getDTStart() < $end) {
if ($it->getDTEnd() > $start) {
$newChildren[] = $stripTimezones($it->getEventObject());
}
$it->next();
}
}
return new self($newChildren);
}
/**
@@ -383,14 +361,13 @@ class VCalendar extends VObject\Document {
*
* @return array
*/
protected function getDefaults() {
protected function getDefaults()
{
return [
'VERSION' => '2.0',
'PRODID' => '-//Sabre//Sabre VObject ' . VObject\Version::VERSION . '//EN',
'VERSION' => '2.0',
'PRODID' => '-//Sabre//Sabre VObject '.VObject\Version::VERSION.'//EN',
'CALSCALE' => 'GREGORIAN',
];
}
/**
@@ -408,16 +385,15 @@ class VCalendar extends VObject\Document {
*
* @var array
*/
function getValidationRules() {
public function getValidationRules()
{
return [
'PRODID' => 1,
'PRODID' => 1,
'VERSION' => 1,
'CALSCALE' => '?',
'METHOD' => '?',
'METHOD' => '?',
];
}
/**
@@ -444,19 +420,18 @@ class VCalendar extends VObject\Document {
*
* @return array
*/
function validate($options = 0) {
public function validate($options = 0)
{
$warnings = parent::validate($options);
if ($ver = $this->VERSION) {
if ((string)$ver !== '2.0') {
if ('2.0' !== (string) $ver) {
$warnings[] = [
'level' => 3,
'level' => 3,
'message' => 'Only iCalendar version 2.0 as defined in rfc5545 is supported.',
'node' => $this,
'node' => $this,
];
}
}
$uidList = [];
@@ -465,77 +440,75 @@ class VCalendar extends VObject\Document {
foreach ($this->children() as $child) {
if ($child instanceof Component) {
$componentsFound++;
++$componentsFound;
if (!in_array($child->name, ['VEVENT', 'VTODO', 'VJOURNAL'])) {
continue;
}
$componentTypes[] = $child->name;
$uid = (string)$child->UID;
$uid = (string) $child->UID;
$isMaster = isset($child->{'RECURRENCE-ID'}) ? 0 : 1;
if (isset($uidList[$uid])) {
$uidList[$uid]['count']++;
++$uidList[$uid]['count'];
if ($isMaster && $uidList[$uid]['hasMaster']) {
$warnings[] = [
'level' => 3,
'message' => 'More than one master object was found for the object with UID ' . $uid,
'node' => $this,
'level' => 3,
'message' => 'More than one master object was found for the object with UID '.$uid,
'node' => $this,
];
}
$uidList[$uid]['hasMaster'] += $isMaster;
} else {
$uidList[$uid] = [
'count' => 1,
'count' => 1,
'hasMaster' => $isMaster,
];
}
}
}
if ($componentsFound === 0) {
if (0 === $componentsFound) {
$warnings[] = [
'level' => 3,
'level' => 3,
'message' => 'An iCalendar object must have at least 1 component.',
'node' => $this,
'node' => $this,
];
}
if ($options & self::PROFILE_CALDAV) {
if (count($uidList) > 1) {
$warnings[] = [
'level' => 3,
'level' => 3,
'message' => 'A calendar object on a CalDAV server may only have components with the same UID.',
'node' => $this,
'node' => $this,
];
}
if (count($componentTypes) === 0) {
if (0 === count($componentTypes)) {
$warnings[] = [
'level' => 3,
'level' => 3,
'message' => 'A calendar object on a CalDAV server must have at least 1 component (VTODO, VEVENT, VJOURNAL).',
'node' => $this,
'node' => $this,
];
}
if (count(array_unique($componentTypes)) > 1) {
$warnings[] = [
'level' => 3,
'level' => 3,
'message' => 'A calendar object on a CalDAV server may only have 1 type of component (VEVENT, VTODO or VJOURNAL).',
'node' => $this,
'node' => $this,
];
}
if (isset($this->METHOD)) {
$warnings[] = [
'level' => 3,
'level' => 3,
'message' => 'A calendar object on a CalDAV server MUST NOT have a METHOD property.',
'node' => $this,
'node' => $this,
];
}
}
return $warnings;
}
/**
@@ -543,19 +516,15 @@ class VCalendar extends VObject\Document {
*
* @return array
*/
function getByUID($uid) {
return array_filter($this->getComponents(), function($item) use ($uid) {
public function getByUID($uid)
{
return array_filter($this->getComponents(), function ($item) use ($uid) {
if (!$itemUid = $item->select('UID')) {
return false;
}
$itemUid = current($itemUid)->getValue();
return $uid === $itemUid;
});
}
}

View File

@@ -15,8 +15,8 @@ use Sabre\Xml;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class VCard extends VObject\Document {
class VCard extends VObject\Document
{
/**
* The default name for this component.
*
@@ -24,7 +24,7 @@ class VCard extends VObject\Document {
*
* @var string
*/
static $defaultName = 'VCARD';
public static $defaultName = 'VCARD';
/**
* Caching the version number.
@@ -38,7 +38,7 @@ class VCard extends VObject\Document {
*
* @var array
*/
static $componentMap = [
public static $componentMap = [
'VCARD' => 'Sabre\\VObject\\Component\\VCard',
];
@@ -47,23 +47,23 @@ class VCard extends VObject\Document {
*
* @var array
*/
static $valueMap = [
'BINARY' => 'Sabre\\VObject\\Property\\Binary',
'BOOLEAN' => 'Sabre\\VObject\\Property\\Boolean',
'CONTENT-ID' => 'Sabre\\VObject\\Property\\FlatText', // vCard 2.1 only
'DATE' => 'Sabre\\VObject\\Property\\VCard\\Date',
'DATE-TIME' => 'Sabre\\VObject\\Property\\VCard\\DateTime',
public static $valueMap = [
'BINARY' => 'Sabre\\VObject\\Property\\Binary',
'BOOLEAN' => 'Sabre\\VObject\\Property\\Boolean',
'CONTENT-ID' => 'Sabre\\VObject\\Property\\FlatText', // vCard 2.1 only
'DATE' => 'Sabre\\VObject\\Property\\VCard\\Date',
'DATE-TIME' => 'Sabre\\VObject\\Property\\VCard\\DateTime',
'DATE-AND-OR-TIME' => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime', // vCard only
'FLOAT' => 'Sabre\\VObject\\Property\\FloatValue',
'INTEGER' => 'Sabre\\VObject\\Property\\IntegerValue',
'LANGUAGE-TAG' => 'Sabre\\VObject\\Property\\VCard\\LanguageTag',
'TIMESTAMP' => 'Sabre\\VObject\\Property\\VCard\\TimeStamp',
'TEXT' => 'Sabre\\VObject\\Property\\Text',
'TIME' => 'Sabre\\VObject\\Property\\Time',
'UNKNOWN' => 'Sabre\\VObject\\Property\\Unknown', // jCard / jCal-only.
'URI' => 'Sabre\\VObject\\Property\\Uri',
'URL' => 'Sabre\\VObject\\Property\\Uri', // vCard 2.1 only
'UTC-OFFSET' => 'Sabre\\VObject\\Property\\UtcOffset',
'FLOAT' => 'Sabre\\VObject\\Property\\FloatValue',
'INTEGER' => 'Sabre\\VObject\\Property\\IntegerValue',
'LANGUAGE-TAG' => 'Sabre\\VObject\\Property\\VCard\\LanguageTag',
'TIMESTAMP' => 'Sabre\\VObject\\Property\\VCard\\TimeStamp',
'TEXT' => 'Sabre\\VObject\\Property\\Text',
'TIME' => 'Sabre\\VObject\\Property\\Time',
'UNKNOWN' => 'Sabre\\VObject\\Property\\Unknown', // jCard / jCal-only.
'URI' => 'Sabre\\VObject\\Property\\Uri',
'URL' => 'Sabre\\VObject\\Property\\Uri', // vCard 2.1 only
'UTC-OFFSET' => 'Sabre\\VObject\\Property\\UtcOffset',
];
/**
@@ -71,72 +71,70 @@ class VCard extends VObject\Document {
*
* @var array
*/
static $propertyMap = [
public static $propertyMap = [
// vCard 2.1 properties and up
'N' => 'Sabre\\VObject\\Property\\Text',
'FN' => 'Sabre\\VObject\\Property\\FlatText',
'PHOTO' => 'Sabre\\VObject\\Property\\Binary',
'BDAY' => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime',
'ADR' => 'Sabre\\VObject\\Property\\Text',
'LABEL' => 'Sabre\\VObject\\Property\\FlatText', // Removed in vCard 4.0
'TEL' => 'Sabre\\VObject\\Property\\FlatText',
'EMAIL' => 'Sabre\\VObject\\Property\\FlatText',
'N' => 'Sabre\\VObject\\Property\\Text',
'FN' => 'Sabre\\VObject\\Property\\FlatText',
'PHOTO' => 'Sabre\\VObject\\Property\\Binary',
'BDAY' => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime',
'ADR' => 'Sabre\\VObject\\Property\\Text',
'LABEL' => 'Sabre\\VObject\\Property\\FlatText', // Removed in vCard 4.0
'TEL' => 'Sabre\\VObject\\Property\\FlatText',
'EMAIL' => 'Sabre\\VObject\\Property\\FlatText',
'MAILER' => 'Sabre\\VObject\\Property\\FlatText', // Removed in vCard 4.0
'GEO' => 'Sabre\\VObject\\Property\\FlatText',
'TITLE' => 'Sabre\\VObject\\Property\\FlatText',
'ROLE' => 'Sabre\\VObject\\Property\\FlatText',
'LOGO' => 'Sabre\\VObject\\Property\\Binary',
'GEO' => 'Sabre\\VObject\\Property\\FlatText',
'TITLE' => 'Sabre\\VObject\\Property\\FlatText',
'ROLE' => 'Sabre\\VObject\\Property\\FlatText',
'LOGO' => 'Sabre\\VObject\\Property\\Binary',
// 'AGENT' => 'Sabre\\VObject\\Property\\', // Todo: is an embedded vCard. Probably rare, so
// not supported at the moment
'ORG' => 'Sabre\\VObject\\Property\\Text',
'NOTE' => 'Sabre\\VObject\\Property\\FlatText',
'REV' => 'Sabre\\VObject\\Property\\VCard\\TimeStamp',
'SOUND' => 'Sabre\\VObject\\Property\\FlatText',
'URL' => 'Sabre\\VObject\\Property\\Uri',
'UID' => 'Sabre\\VObject\\Property\\FlatText',
'ORG' => 'Sabre\\VObject\\Property\\Text',
'NOTE' => 'Sabre\\VObject\\Property\\FlatText',
'REV' => 'Sabre\\VObject\\Property\\VCard\\TimeStamp',
'SOUND' => 'Sabre\\VObject\\Property\\FlatText',
'URL' => 'Sabre\\VObject\\Property\\Uri',
'UID' => 'Sabre\\VObject\\Property\\FlatText',
'VERSION' => 'Sabre\\VObject\\Property\\FlatText',
'KEY' => 'Sabre\\VObject\\Property\\FlatText',
'TZ' => 'Sabre\\VObject\\Property\\Text',
'KEY' => 'Sabre\\VObject\\Property\\FlatText',
'TZ' => 'Sabre\\VObject\\Property\\Text',
// vCard 3.0 properties
'CATEGORIES' => 'Sabre\\VObject\\Property\\Text',
'CATEGORIES' => 'Sabre\\VObject\\Property\\Text',
'SORT-STRING' => 'Sabre\\VObject\\Property\\FlatText',
'PRODID' => 'Sabre\\VObject\\Property\\FlatText',
'NICKNAME' => 'Sabre\\VObject\\Property\\Text',
'CLASS' => 'Sabre\\VObject\\Property\\FlatText', // Removed in vCard 4.0
'PRODID' => 'Sabre\\VObject\\Property\\FlatText',
'NICKNAME' => 'Sabre\\VObject\\Property\\Text',
'CLASS' => 'Sabre\\VObject\\Property\\FlatText', // Removed in vCard 4.0
// rfc2739 properties
'FBURL' => 'Sabre\\VObject\\Property\\Uri',
'CAPURI' => 'Sabre\\VObject\\Property\\Uri',
'CALURI' => 'Sabre\\VObject\\Property\\Uri',
'FBURL' => 'Sabre\\VObject\\Property\\Uri',
'CAPURI' => 'Sabre\\VObject\\Property\\Uri',
'CALURI' => 'Sabre\\VObject\\Property\\Uri',
'CALADRURI' => 'Sabre\\VObject\\Property\\Uri',
// rfc4770 properties
'IMPP' => 'Sabre\\VObject\\Property\\Uri',
// vCard 4.0 properties
'SOURCE' => 'Sabre\\VObject\\Property\\Uri',
'XML' => 'Sabre\\VObject\\Property\\FlatText',
'ANNIVERSARY' => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime',
'SOURCE' => 'Sabre\\VObject\\Property\\Uri',
'XML' => 'Sabre\\VObject\\Property\\FlatText',
'ANNIVERSARY' => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime',
'CLIENTPIDMAP' => 'Sabre\\VObject\\Property\\Text',
'LANG' => 'Sabre\\VObject\\Property\\VCard\\LanguageTag',
'GENDER' => 'Sabre\\VObject\\Property\\Text',
'KIND' => 'Sabre\\VObject\\Property\\FlatText',
'MEMBER' => 'Sabre\\VObject\\Property\\Uri',
'RELATED' => 'Sabre\\VObject\\Property\\Uri',
'LANG' => 'Sabre\\VObject\\Property\\VCard\\LanguageTag',
'GENDER' => 'Sabre\\VObject\\Property\\Text',
'KIND' => 'Sabre\\VObject\\Property\\FlatText',
'MEMBER' => 'Sabre\\VObject\\Property\\Uri',
'RELATED' => 'Sabre\\VObject\\Property\\Uri',
// rfc6474 properties
'BIRTHPLACE' => 'Sabre\\VObject\\Property\\FlatText',
'DEATHPLACE' => 'Sabre\\VObject\\Property\\FlatText',
'DEATHDATE' => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime',
'DEATHDATE' => 'Sabre\\VObject\\Property\\VCard\\DateAndOrTime',
// rfc6715 properties
'EXPERTISE' => 'Sabre\\VObject\\Property\\FlatText',
'HOBBY' => 'Sabre\\VObject\\Property\\FlatText',
'INTEREST' => 'Sabre\\VObject\\Property\\FlatText',
'EXPERTISE' => 'Sabre\\VObject\\Property\\FlatText',
'HOBBY' => 'Sabre\\VObject\\Property\\FlatText',
'INTEREST' => 'Sabre\\VObject\\Property\\FlatText',
'ORG-DIRECTORY' => 'Sabre\\VObject\\Property\\FlatText',
];
/**
@@ -144,23 +142,22 @@ class VCard extends VObject\Document {
*
* @return int
*/
function getDocumentType() {
public function getDocumentType()
{
if (!$this->version) {
$version = (string)$this->VERSION;
$version = (string) $this->VERSION;
switch ($version) {
case '2.1' :
case '2.1':
$this->version = self::VCARD21;
break;
case '3.0' :
case '3.0':
$this->version = self::VCARD30;
break;
case '4.0' :
case '4.0':
$this->version = self::VCARD40;
break;
default :
default:
// We don't want to cache the version if it's unknown,
// because we might get a version property in a bit.
return self::UNKNOWN;
@@ -168,7 +165,6 @@ class VCard extends VObject\Document {
}
return $this->version;
}
/**
@@ -185,11 +181,11 @@ class VCard extends VObject\Document {
*
* @return VCard
*/
function convert($target) {
public function convert($target)
{
$converter = new VObject\VCardConverter();
return $converter->convert($this, $target);
return $converter->convert($this, $target);
}
/**
@@ -221,8 +217,8 @@ class VCard extends VObject\Document {
*
* @return array
*/
function validate($options = 0) {
public function validate($options = 0)
{
$warnings = [];
$versionMap = [
@@ -232,29 +228,28 @@ class VCard extends VObject\Document {
];
$version = $this->select('VERSION');
if (count($version) === 1) {
$version = (string)$this->VERSION;
if ($version !== '2.1' && $version !== '3.0' && $version !== '4.0') {
if (1 === count($version)) {
$version = (string) $this->VERSION;
if ('2.1' !== $version && '3.0' !== $version && '4.0' !== $version) {
$warnings[] = [
'level' => 3,
'level' => 3,
'message' => 'Only vcard version 4.0 (RFC6350), version 3.0 (RFC2426) or version 2.1 (icm-vcard-2.1) are supported.',
'node' => $this,
'node' => $this,
];
if ($options & self::REPAIR) {
$this->VERSION = $versionMap[self::DEFAULT_VERSION];
}
}
if ($version === '2.1' && ($options & self::PROFILE_CARDDAV)) {
if ('2.1' === $version && ($options & self::PROFILE_CARDDAV)) {
$warnings[] = [
'level' => 3,
'level' => 3,
'message' => 'CardDAV servers are not allowed to accept vCard 2.1.',
'node' => $this,
'node' => $this,
];
}
}
$uid = $this->select('UID');
if (count($uid) === 0) {
if (0 === count($uid)) {
if ($options & self::PROFILE_CARDDAV) {
// Required for CardDAV
$warningLevel = 3;
@@ -269,23 +264,22 @@ class VCard extends VObject\Document {
$warningLevel = 1;
}
$warnings[] = [
'level' => $warningLevel,
'level' => $warningLevel,
'message' => $message,
'node' => $this,
'node' => $this,
];
}
$fn = $this->select('FN');
if (count($fn) !== 1) {
if (1 !== count($fn)) {
$repaired = false;
if (($options & self::REPAIR) && count($fn) === 0) {
if (($options & self::REPAIR) && 0 === count($fn)) {
// We're going to try to see if we can use the contents of the
// N property.
if (isset($this->N)) {
$value = explode(';', (string)$this->N);
$value = explode(';', (string) $this->N);
if (isset($value[1]) && $value[1]) {
$this->FN = $value[1] . ' ' . $value[0];
$this->FN = $value[1].' '.$value[0];
} else {
$this->FN = $value[0];
}
@@ -293,20 +287,19 @@ class VCard extends VObject\Document {
// Otherwise, the ORG property may work
} elseif (isset($this->ORG)) {
$this->FN = (string)$this->ORG;
$this->FN = (string) $this->ORG;
$repaired = true;
// Otherwise, the EMAIL property may work
} elseif (isset($this->EMAIL)) {
$this->FN = (string)$this->EMAIL;
$this->FN = (string) $this->EMAIL;
$repaired = true;
}
}
$warnings[] = [
'level' => $repaired ? 1 : 3,
'level' => $repaired ? 1 : 3,
'message' => 'The FN property must appear in the VCARD component exactly 1 time',
'node' => $this,
'node' => $this,
];
}
@@ -314,7 +307,6 @@ class VCard extends VObject\Document {
parent::validate($options),
$warnings
);
}
/**
@@ -332,50 +324,49 @@ class VCard extends VObject\Document {
*
* @var array
*/
function getValidationRules() {
public function getValidationRules()
{
return [
'ADR' => '*',
'ANNIVERSARY' => '?',
'BDAY' => '?',
'CALADRURI' => '*',
'CALURI' => '*',
'CATEGORIES' => '*',
'ADR' => '*',
'ANNIVERSARY' => '?',
'BDAY' => '?',
'CALADRURI' => '*',
'CALURI' => '*',
'CATEGORIES' => '*',
'CLIENTPIDMAP' => '*',
'EMAIL' => '*',
'FBURL' => '*',
'IMPP' => '*',
'GENDER' => '?',
'GEO' => '*',
'KEY' => '*',
'KIND' => '?',
'LANG' => '*',
'LOGO' => '*',
'MEMBER' => '*',
'N' => '?',
'NICKNAME' => '*',
'NOTE' => '*',
'ORG' => '*',
'PHOTO' => '*',
'PRODID' => '?',
'RELATED' => '*',
'REV' => '?',
'ROLE' => '*',
'SOUND' => '*',
'SOURCE' => '*',
'TEL' => '*',
'TITLE' => '*',
'TZ' => '*',
'URL' => '*',
'VERSION' => '1',
'XML' => '*',
'EMAIL' => '*',
'FBURL' => '*',
'IMPP' => '*',
'GENDER' => '?',
'GEO' => '*',
'KEY' => '*',
'KIND' => '?',
'LANG' => '*',
'LOGO' => '*',
'MEMBER' => '*',
'N' => '?',
'NICKNAME' => '*',
'NOTE' => '*',
'ORG' => '*',
'PHOTO' => '*',
'PRODID' => '?',
'RELATED' => '*',
'REV' => '?',
'ROLE' => '*',
'SOUND' => '*',
'SOURCE' => '*',
'TEL' => '*',
'TITLE' => '*',
'TZ' => '*',
'URL' => '*',
'VERSION' => '1',
'XML' => '*',
// FN is commented out, because it's already handled by the
// validate function, which may also try to repair it.
// 'FN' => '+',
'UID' => '?',
];
}
/**
@@ -392,12 +383,11 @@ class VCard extends VObject\Document {
*
* @return VObject\Property|null
*/
function preferred($propertyName) {
public function preferred($propertyName)
{
$preferred = null;
$lastPref = 101;
foreach ($this->select($propertyName) as $field) {
$pref = 101;
if (isset($field['TYPE']) && $field['TYPE']->has('PREF')) {
$pref = 1;
@@ -409,10 +399,9 @@ class VCard extends VObject\Document {
$preferred = $field;
$lastPref = $pref;
}
}
return $preferred;
return $preferred;
}
/**
@@ -426,7 +415,8 @@ class VCard extends VObject\Document {
*
* @return VObject\Property|null
*/
function getByType($propertyName, $type) {
public function getByType($propertyName, $type)
{
foreach ($this->select($propertyName) as $field) {
if (isset($field['TYPE']) && $field['TYPE']->has($type)) {
return $field;
@@ -439,14 +429,13 @@ class VCard extends VObject\Document {
*
* @return array
*/
protected function getDefaults() {
protected function getDefaults()
{
return [
'VERSION' => '4.0',
'PRODID' => '-//Sabre//Sabre VObject ' . VObject\Version::VERSION . '//EN',
'UID' => 'sabre-vobject-' . VObject\UUIDUtil::getUUID(),
'PRODID' => '-//Sabre//Sabre VObject '.VObject\Version::VERSION.'//EN',
'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(),
];
}
/**
@@ -455,8 +444,8 @@ class VCard extends VObject\Document {
*
* @return array
*/
function jsonSerialize() {
public function jsonSerialize()
{
// A vcard does not have sub-components, so we're overriding this
// method to remove that array element.
$properties = [];
@@ -469,23 +458,19 @@ class VCard extends VObject\Document {
strtolower($this->name),
$properties,
];
}
/**
* This method serializes the data into XML. This is used to create xCard or
* xCal documents.
*
* @param Xml\Writer $writer XML writer.
*
* @return void
* @param Xml\Writer $writer XML writer
*/
function xmlSerialize(Xml\Writer $writer) {
public function xmlSerialize(Xml\Writer $writer)
{
$propertiesByGroup = [];
foreach ($this->children() as $property) {
$group = $property->group;
if (!isset($propertiesByGroup[$group])) {
@@ -493,25 +478,20 @@ class VCard extends VObject\Document {
}
$propertiesByGroup[$group][] = $property;
}
$writer->startElement(strtolower($this->name));
foreach ($propertiesByGroup as $group => $properties) {
if (!empty($group)) {
$writer->startElement('group');
$writer->writeAttribute('name', strtolower($group));
}
foreach ($properties as $property) {
switch ($property->name) {
case 'VERSION':
continue;
break;
case 'XML':
$value = $property->getParts();
@@ -522,18 +502,15 @@ class VCard extends VObject\Document {
default:
$property->xmlSerialize($writer);
break;
}
}
if (!empty($group)) {
$writer->endElement();
}
}
$writer->endElement();
}
/**
@@ -543,16 +520,15 @@ class VCard extends VObject\Document {
*
* @return string
*/
function getClassNameForPropertyName($propertyName) {
public function getClassNameForPropertyName($propertyName)
{
$className = parent::getClassNameForPropertyName($propertyName);
// In vCard 4, BINARY no longer exists, and we need URI instead.
if ($className == 'Sabre\\VObject\\Property\\Binary' && $this->getDocumentType() === self::VCARD40) {
if ('Sabre\\VObject\\Property\\Binary' == $className && self::VCARD40 === $this->getDocumentType()) {
return 'Sabre\\VObject\\Property\\Uri';
}
return $className;
}
}

View File

@@ -16,8 +16,8 @@ use Sabre\VObject\Recur\NoInstancesException;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class VEvent extends VObject\Component {
class VEvent extends VObject\Component
{
/**
* Returns true or false depending on if the event falls in the specified
* time-range. This is used for filtering purposes.
@@ -30,20 +30,15 @@ class VEvent extends VObject\Component {
*
* @return bool
*/
function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) {
public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
{
if ($this->RRULE) {
try {
$it = new EventIterator($this, null, $start->getTimezone());
} catch (NoInstancesException $e) {
// If we've catched this exception, there are no instances
// for the event that fall into the specified time-range.
return false;
}
$it->fastForward($start);
@@ -54,13 +49,11 @@ class VEvent extends VObject\Component {
//
// If the starttime of the recurrence did not exceed the
// end of the time range as well, we have a match.
return ($it->getDTStart() < $end && $it->getDTEnd() > $start);
return $it->getDTStart() < $end && $it->getDTEnd() > $start;
}
$effectiveStart = $this->DTSTART->getDateTime($start->getTimezone());
if (isset($this->DTEND)) {
// The DTEND property is considered non inclusive. So for a 3 day
// event in july, dtstart and dtend would have to be July 1st and
// July 4th respectively.
@@ -68,7 +61,6 @@ class VEvent extends VObject\Component {
// See:
// http://tools.ietf.org/html/rfc5545#page-54
$effectiveEnd = $this->DTEND->getDateTime($end->getTimezone());
} elseif (isset($this->DURATION)) {
$effectiveEnd = $effectiveStart->add(VObject\DateTimeParser::parseDuration($this->DURATION));
} elseif (!$this->DTSTART->hasTime()) {
@@ -76,10 +68,10 @@ class VEvent extends VObject\Component {
} else {
$effectiveEnd = $effectiveStart;
}
return (
($start < $effectiveEnd) && ($end > $effectiveStart)
);
return
($start < $effectiveEnd) && ($end > $effectiveStart)
;
}
/**
@@ -87,13 +79,12 @@ class VEvent extends VObject\Component {
*
* @return array
*/
protected function getDefaults() {
protected function getDefaults()
{
return [
'UID' => 'sabre-vobject-' . VObject\UUIDUtil::getUUID(),
'DTSTAMP' => date('Ymd\\THis\\Z'),
'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(),
'DTSTAMP' => gmdate('Ymd\\THis\\Z'),
];
}
/**
@@ -111,43 +102,42 @@ class VEvent extends VObject\Component {
*
* @var array
*/
function getValidationRules() {
public function getValidationRules()
{
$hasMethod = isset($this->parent->METHOD);
return [
'UID' => 1,
'DTSTAMP' => 1,
'DTSTART' => $hasMethod ? '?' : '1',
'CLASS' => '?',
'CREATED' => '?',
'DESCRIPTION' => '?',
'GEO' => '?',
'UID' => 1,
'DTSTAMP' => 1,
'DTSTART' => $hasMethod ? '?' : '1',
'CLASS' => '?',
'CREATED' => '?',
'DESCRIPTION' => '?',
'GEO' => '?',
'LAST-MODIFIED' => '?',
'LOCATION' => '?',
'ORGANIZER' => '?',
'PRIORITY' => '?',
'SEQUENCE' => '?',
'STATUS' => '?',
'SUMMARY' => '?',
'TRANSP' => '?',
'URL' => '?',
'LOCATION' => '?',
'ORGANIZER' => '?',
'PRIORITY' => '?',
'SEQUENCE' => '?',
'STATUS' => '?',
'SUMMARY' => '?',
'TRANSP' => '?',
'URL' => '?',
'RECURRENCE-ID' => '?',
'RRULE' => '?',
'DTEND' => '?',
'DURATION' => '?',
'RRULE' => '?',
'DTEND' => '?',
'DURATION' => '?',
'ATTACH' => '*',
'ATTENDEE' => '*',
'CATEGORIES' => '*',
'COMMENT' => '*',
'CONTACT' => '*',
'EXDATE' => '*',
'ATTACH' => '*',
'ATTENDEE' => '*',
'CATEGORIES' => '*',
'COMMENT' => '*',
'CONTACT' => '*',
'EXDATE' => '*',
'REQUEST-STATUS' => '*',
'RELATED-TO' => '*',
'RESOURCES' => '*',
'RDATE' => '*',
'RELATED-TO' => '*',
'RESOURCES' => '*',
'RDATE' => '*',
];
}
}

View File

@@ -15,8 +15,8 @@ use Sabre\VObject;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class VFreeBusy extends VObject\Component {
class VFreeBusy extends VObject\Component
{
/**
* Checks based on the contained FREEBUSY information, if a timeslot is
* available.
@@ -26,19 +26,18 @@ class VFreeBusy extends VObject\Component {
*
* @return bool
*/
function isFree(DateTimeInterface $start, DatetimeInterface $end) {
public function isFree(DateTimeInterface $start, DatetimeInterface $end)
{
foreach ($this->select('FREEBUSY') as $freebusy) {
// We are only interested in FBTYPE=BUSY (the default),
// FBTYPE=BUSY-TENTATIVE or FBTYPE=BUSY-UNAVAILABLE.
if (isset($freebusy['FBTYPE']) && strtoupper(substr((string)$freebusy['FBTYPE'], 0, 4)) !== 'BUSY') {
if (isset($freebusy['FBTYPE']) && 'BUSY' !== strtoupper(substr((string) $freebusy['FBTYPE'], 0, 4))) {
continue;
}
// The freebusy component can hold more than 1 value, separated by
// commas.
$periods = explode(',', (string)$freebusy);
$periods = explode(',', (string) $freebusy);
foreach ($periods as $period) {
// Every period is formatted as [start]/[end]. The start is an
@@ -55,13 +54,10 @@ class VFreeBusy extends VObject\Component {
if ($start < $busyEnd && $end > $busyStart) {
return false;
}
}
}
return true;
}
/**
@@ -79,24 +75,22 @@ class VFreeBusy extends VObject\Component {
*
* @var array
*/
function getValidationRules() {
public function getValidationRules()
{
return [
'UID' => 1,
'UID' => 1,
'DTSTAMP' => 1,
'CONTACT' => '?',
'DTSTART' => '?',
'DTEND' => '?',
'CONTACT' => '?',
'DTSTART' => '?',
'DTEND' => '?',
'ORGANIZER' => '?',
'URL' => '?',
'URL' => '?',
'ATTENDEE' => '*',
'COMMENT' => '*',
'FREEBUSY' => '*',
'ATTENDEE' => '*',
'COMMENT' => '*',
'FREEBUSY' => '*',
'REQUEST-STATUS' => '*',
];
}
}

View File

@@ -14,8 +14,8 @@ use Sabre\VObject;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class VJournal extends VObject\Component {
class VJournal extends VObject\Component
{
/**
* Returns true or false depending on if the event falls in the specified
* time-range. This is used for filtering purposes.
@@ -28,8 +28,8 @@ class VJournal extends VObject\Component {
*
* @return bool
*/
function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) {
public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
{
$dtstart = isset($this->DTSTART) ? $this->DTSTART->getDateTime() : null;
if ($dtstart) {
$effectiveEnd = $dtstart;
@@ -37,11 +37,10 @@ class VJournal extends VObject\Component {
$effectiveEnd = $effectiveEnd->modify('+1 day');
}
return ($start <= $effectiveEnd && $end > $dtstart);
return $start <= $effectiveEnd && $end > $dtstart;
}
return false;
return false;
}
/**
@@ -59,36 +58,35 @@ class VJournal extends VObject\Component {
*
* @var array
*/
function getValidationRules() {
public function getValidationRules()
{
return [
'UID' => 1,
'UID' => 1,
'DTSTAMP' => 1,
'CLASS' => '?',
'CREATED' => '?',
'DTSTART' => '?',
'CLASS' => '?',
'CREATED' => '?',
'DTSTART' => '?',
'LAST-MODIFIED' => '?',
'ORGANIZER' => '?',
'ORGANIZER' => '?',
'RECURRENCE-ID' => '?',
'SEQUENCE' => '?',
'STATUS' => '?',
'SUMMARY' => '?',
'URL' => '?',
'SEQUENCE' => '?',
'STATUS' => '?',
'SUMMARY' => '?',
'URL' => '?',
'RRULE' => '?',
'ATTACH' => '*',
'ATTENDEE' => '*',
'CATEGORIES' => '*',
'COMMENT' => '*',
'CONTACT' => '*',
'ATTACH' => '*',
'ATTENDEE' => '*',
'CATEGORIES' => '*',
'COMMENT' => '*',
'CONTACT' => '*',
'DESCRIPTION' => '*',
'EXDATE' => '*',
'RELATED-TO' => '*',
'RDATE' => '*',
'EXDATE' => '*',
'RELATED-TO' => '*',
'RDATE' => '*',
];
}
/**
@@ -96,12 +94,11 @@ class VJournal extends VObject\Component {
*
* @return array
*/
protected function getDefaults() {
protected function getDefaults()
{
return [
'UID' => 'sabre-vobject-' . VObject\UUIDUtil::getUUID(),
'DTSTAMP' => date('Ymd\\THis\\Z'),
'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(),
'DTSTAMP' => gmdate('Ymd\\THis\\Z'),
];
}
}

View File

@@ -14,8 +14,8 @@ use Sabre\VObject;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class VTimeZone extends VObject\Component {
class VTimeZone extends VObject\Component
{
/**
* Returns the PHP DateTimeZone for this VTIMEZONE component.
*
@@ -24,10 +24,9 @@ class VTimeZone extends VObject\Component {
*
* @return \DateTimeZone
*/
function getTimeZone() {
return VObject\TimeZoneUtil::getTimeZone((string)$this->TZID, $this->root);
public function getTimeZone()
{
return VObject\TimeZoneUtil::getTimeZone((string) $this->TZID, $this->root);
}
/**
@@ -45,13 +44,13 @@ class VTimeZone extends VObject\Component {
*
* @var array
*/
function getValidationRules() {
public function getValidationRules()
{
return [
'TZID' => 1,
'LAST-MODIFIED' => '?',
'TZURL' => '?',
'TZURL' => '?',
// At least 1 STANDARD or DAYLIGHT must appear.
//
@@ -60,7 +59,5 @@ class VTimeZone extends VObject\Component {
'STANDARD' => '*',
'DAYLIGHT' => '*',
];
}
}

View File

@@ -14,8 +14,8 @@ use Sabre\VObject;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
class VTodo extends VObject\Component {
class VTodo extends VObject\Component
{
/**
* Returns true or false depending on if the event falls in the specified
* time-range. This is used for filtering purposes.
@@ -28,8 +28,8 @@ class VTodo extends VObject\Component {
*
* @return bool
*/
function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end) {
public function isInTimeRange(DateTimeInterface $start, DateTimeInterface $end)
{
$dtstart = isset($this->DTSTART) ? $this->DTSTART->getDateTime() : null;
$duration = isset($this->DURATION) ? VObject\DateTimeParser::parseDuration($this->DURATION) : null;
$due = isset($this->DUE) ? $this->DUE->getDateTime() : null;
@@ -39,6 +39,7 @@ class VTodo extends VObject\Component {
if ($dtstart) {
if ($duration) {
$effectiveEnd = $dtstart->add($duration);
return $start <= $effectiveEnd && $end > $dtstart;
} elseif ($due) {
return
@@ -49,7 +50,7 @@ class VTodo extends VObject\Component {
}
}
if ($due) {
return ($start < $due && $end >= $due);
return $start < $due && $end >= $due;
}
if ($completed && $created) {
return
@@ -57,13 +58,13 @@ class VTodo extends VObject\Component {
($end >= $created || $end >= $completed);
}
if ($completed) {
return ($start <= $completed && $end >= $completed);
return $start <= $completed && $end >= $completed;
}
if ($created) {
return ($end > $created);
return $end > $created;
}
return true;
return true;
}
/**
@@ -81,45 +82,44 @@ class VTodo extends VObject\Component {
*
* @var array
*/
function getValidationRules() {
public function getValidationRules()
{
return [
'UID' => 1,
'UID' => 1,
'DTSTAMP' => 1,
'CLASS' => '?',
'COMPLETED' => '?',
'CREATED' => '?',
'DESCRIPTION' => '?',
'DTSTART' => '?',
'GEO' => '?',
'CLASS' => '?',
'COMPLETED' => '?',
'CREATED' => '?',
'DESCRIPTION' => '?',
'DTSTART' => '?',
'GEO' => '?',
'LAST-MODIFIED' => '?',
'LOCATION' => '?',
'ORGANIZER' => '?',
'PERCENT' => '?',
'PRIORITY' => '?',
'LOCATION' => '?',
'ORGANIZER' => '?',
'PERCENT' => '?',
'PRIORITY' => '?',
'RECURRENCE-ID' => '?',
'SEQUENCE' => '?',
'STATUS' => '?',
'SUMMARY' => '?',
'URL' => '?',
'SEQUENCE' => '?',
'STATUS' => '?',
'SUMMARY' => '?',
'URL' => '?',
'RRULE' => '?',
'DUE' => '?',
'RRULE' => '?',
'DUE' => '?',
'DURATION' => '?',
'ATTACH' => '*',
'ATTENDEE' => '*',
'CATEGORIES' => '*',
'COMMENT' => '*',
'CONTACT' => '*',
'EXDATE' => '*',
'ATTACH' => '*',
'ATTENDEE' => '*',
'CATEGORIES' => '*',
'COMMENT' => '*',
'CONTACT' => '*',
'EXDATE' => '*',
'REQUEST-STATUS' => '*',
'RELATED-TO' => '*',
'RESOURCES' => '*',
'RDATE' => '*',
'RELATED-TO' => '*',
'RESOURCES' => '*',
'RDATE' => '*',
];
}
/**
@@ -144,36 +144,29 @@ class VTodo extends VObject\Component {
*
* @return array
*/
function validate($options = 0) {
public function validate($options = 0)
{
$result = parent::validate($options);
if (isset($this->DUE) && isset($this->DTSTART)) {
$due = $this->DUE;
$dtStart = $this->DTSTART;
if ($due->getValueType() !== $dtStart->getValueType()) {
$result[] = [
'level' => 3,
'level' => 3,
'message' => 'The value type (DATE or DATE-TIME) must be identical for DUE and DTSTART',
'node' => $due,
'node' => $due,
];
} elseif ($due->getDateTime() < $dtStart->getDateTime()) {
$result[] = [
'level' => 3,
'level' => 3,
'message' => 'DUE must occur after DTSTART',
'node' => $due,
'node' => $due,
];
}
}
return $result;
}
/**
@@ -181,13 +174,11 @@ class VTodo extends VObject\Component {
*
* @return array
*/
protected function getDefaults() {
protected function getDefaults()
{
return [
'UID' => 'sabre-vobject-' . VObject\UUIDUtil::getUUID(),
'UID' => 'sabre-vobject-'.VObject\UUIDUtil::getUUID(),
'DTSTAMP' => date('Ymd\\THis\\Z'),
];
}
}