本文整理汇总了PHP中Sabre\VObject\DateTimeParser::parseDateTime方法的典型用法代码示例。如果您正苦于以下问题:PHP DateTimeParser::parseDateTime方法的具体用法?PHP DateTimeParser::parseDateTime怎么用?PHP DateTimeParser::parseDateTime使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Sabre\VObject\DateTimeParser
的用法示例。
在下文中一共展示了DateTimeParser::parseDateTime方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: xmlDeserialize
/**
* The deserialize method is called during xml parsing.
*
* This method is called statictly, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
* free to return other data as well.
*
* You are responsible for advancing the reader to the next element. Not
* doing anything will result in a never-ending loop.
*
* If you just want to skip parsing for this element altogether, you can
* just call $reader->next();
*
* $reader->parseInnerTree() will parse the entire sub-tree, and advance to
* the next element.
*
* @param Reader $reader
* @return mixed
*/
static function xmlDeserialize(Reader $reader)
{
$result = ['name' => null, 'is-not-defined' => false, 'comp-filters' => [], 'prop-filters' => [], 'time-range' => false];
$att = $reader->parseAttributes();
$result['name'] = $att['name'];
$elems = $reader->parseInnerTree();
if (is_array($elems)) {
foreach ($elems as $elem) {
switch ($elem['name']) {
case '{' . Plugin::NS_CALDAV . '}comp-filter':
$result['comp-filters'][] = $elem['value'];
break;
case '{' . Plugin::NS_CALDAV . '}prop-filter':
$result['prop-filters'][] = $elem['value'];
break;
case '{' . Plugin::NS_CALDAV . '}is-not-defined':
$result['is-not-defined'] = true;
break;
case '{' . Plugin::NS_CALDAV . '}time-range':
if ($result['name'] === 'VCALENDAR') {
throw new BadRequest('You cannot add time-range filters on the VCALENDAR component');
}
$result['time-range'] = ['start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null, 'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null];
if ($result['time-range']['start'] && $result['time-range']['end'] && $result['time-range']['end'] <= $result['time-range']['start']) {
throw new BadRequest('The end-date must be larger than the start-date');
}
break;
}
}
}
return $result;
}
示例2: xmlDeserialize
/**
* The deserialize method is called during xml parsing.
*
* This method is called statictly, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
* free to return other data as well.
*
* You are responsible for advancing the reader to the next element. Not
* doing anything will result in a never-ending loop.
*
* If you just want to skip parsing for this element altogether, you can
* just call $reader->next();
*
* $reader->parseInnerTree() will parse the entire sub-tree, and advance to
* the next element.
*
* @param Reader $reader
* @return mixed
*/
static function xmlDeserialize(Reader $reader)
{
$result = ['name' => null, 'is-not-defined' => false, 'param-filters' => [], 'text-match' => null, 'time-range' => false];
$att = $reader->parseAttributes();
$result['name'] = $att['name'];
$elems = $reader->parseInnerTree();
if (is_array($elems)) {
foreach ($elems as $elem) {
switch ($elem['name']) {
case '{' . Plugin::NS_CALDAV . '}param-filter':
$result['param-filters'][] = $elem['value'];
break;
case '{' . Plugin::NS_CALDAV . '}is-not-defined':
$result['is-not-defined'] = true;
break;
case '{' . Plugin::NS_CALDAV . '}time-range':
$result['time-range'] = ['start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null, 'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null];
if ($result['time-range']['start'] && $result['time-range']['end'] && $result['time-range']['end'] <= $result['time-range']['start']) {
throw new BadRequest('The end-date must be larger than the start-date');
}
break;
case '{' . Plugin::NS_CALDAV . '}text-match':
$result['text-match'] = ['negate-condition' => isset($elem['attributes']['negate-condition']) && $elem['attributes']['negate-condition'] === 'yes', 'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;ascii-casemap', 'value' => $elem['value']];
break;
}
}
}
return $result;
}
示例3: xmlDeserialize
/**
* The deserialize method is called during xml parsing.
*
* This method is called statictly, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
* free to return other data as well.
*
* You are responsible for advancing the reader to the next element. Not
* doing anything will result in a never-ending loop.
*
* If you just want to skip parsing for this element altogether, you can
* just call $reader->next();
*
* $reader->parseInnerTree() will parse the entire sub-tree, and advance to
* the next element.
*
* @param Reader $reader
* @return mixed
*/
static function xmlDeserialize(Reader $reader)
{
$timeRange = '{' . Plugin::NS_CALDAV . '}time-range';
$start = null;
$end = null;
foreach ((array) $reader->parseInnerTree([]) as $elem) {
if ($elem['name'] !== $timeRange) {
continue;
}
$start = empty($elem['attributes']['start']) ?: $elem['attributes']['start'];
$end = empty($elem['attributes']['end']) ?: $elem['attributes']['end'];
}
if (!$start && !$end) {
throw new BadRequest('The freebusy report must have a time-range element');
}
if ($start) {
$start = DateTimeParser::parseDateTime($start);
}
if ($end) {
$end = DateTimeParser::parseDateTime($end);
}
$result = new self();
$result->start = $start;
$result->end = $end;
return $result;
}
示例4: getJsonValue
/**
* 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 = array();
foreach ($this->getParts() as $item) {
list($start, $end) = explode('/', $item, 2);
$start = DateTimeParser::parseDateTime($start);
// This is a duration value.
if ($end[0] === 'P') {
$return[] = array($start->format('Y-m-d\\TH:i:s'), $end);
} else {
$end = DateTimeParser::parseDateTime($end);
$return[] = array($start->format('Y-m-d\\TH:i:s'), $end->format('Y-m-d\\TH:i:s'));
}
}
return $return;
}
示例5: xmlDeserialize
/**
* The deserialize method is called during xml parsing.
*
* This method is called statictly, this is because in theory this method
* may be used as a type of constructor, or factory method.
*
* Often you want to return an instance of the current class, but you are
* free to return other data as well.
*
* You are responsible for advancing the reader to the next element. Not
* doing anything will result in a never-ending loop.
*
* If you just want to skip parsing for this element altogether, you can
* just call $reader->next();
*
* $reader->parseInnerTree() will parse the entire sub-tree, and advance to
* the next element.
*
* @param Reader $reader
* @return mixed
*/
static function xmlDeserialize(Reader $reader)
{
$result = ['contentType' => $reader->getAttribute('content-type') ?: 'text/calendar', 'version' => $reader->getAttribute('version') ?: '2.0'];
$elems = (array) $reader->parseInnerTree();
foreach ($elems as $elem) {
switch ($elem['name']) {
case '{' . Plugin::NS_CALDAV . '}expand':
$result['expand'] = ['start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null, 'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null];
if (!$result['expand']['start'] || !$result['expand']['end']) {
throw new BadRequest('The "start" and "end" attributes are required when expanding calendar-data');
}
if ($result['expand']['end'] <= $result['expand']['start']) {
throw new BadRequest('The end-date must be larger than the start-date when expanding calendar-data');
}
break;
}
}
return $result;
}
示例6: DateTime
/**
* Check if a datetime with year > 4000 will not throw an exception. iOS seems to use 45001231T235959 in yearly recurring events
*/
function testParseICalendarDateTimeGreaterThan4000()
{
$dateTime = DateTimeParser::parseDateTime('45001231T235959');
$expected = new DateTime('4500-12-31 23:59:59', new DateTimeZone('UTC'));
$this->assertEquals($expected, $dateTime);
$dateTime = DateTimeParser::parse('45001231T235959');
$this->assertEquals($expected, $dateTime);
}
示例7: getResult
/**
* Parses the input data and returns a correct VFREEBUSY object, wrapped in
* a VCALENDAR.
*
* @return Component
*/
function getResult()
{
$busyTimes = [];
foreach ($this->objects as $key => $object) {
foreach ($object->getBaseComponents() as $component) {
switch ($component->name) {
case 'VEVENT':
$FBTYPE = 'BUSY';
if (isset($component->TRANSP) && strtoupper($component->TRANSP) === 'TRANSPARENT') {
break;
}
if (isset($component->STATUS)) {
$status = strtoupper($component->STATUS);
if ($status === 'CANCELLED') {
break;
}
if ($status === 'TENTATIVE') {
$FBTYPE = 'BUSY-TENTATIVE';
}
}
$times = [];
if ($component->RRULE) {
try {
$iterator = new EventIterator($object, (string) $component->uid, $this->timeZone);
} catch (NoInstancesException $e) {
// This event is recurring, but it doesn't have a single
// instance. We are skipping this event from the output
// entirely.
unset($this->objects[$key]);
continue;
}
if ($this->start) {
$iterator->fastForward($this->start);
}
$maxRecurrences = 200;
while ($iterator->valid() && --$maxRecurrences) {
$startTime = $iterator->getDTStart();
if ($this->end && $startTime > $this->end) {
break;
}
$times[] = [$iterator->getDTStart(), $iterator->getDTEnd()];
$iterator->next();
}
} else {
$startTime = $component->DTSTART->getDateTime($this->timeZone);
if ($this->end && $startTime > $this->end) {
break;
}
$endTime = null;
if (isset($component->DTEND)) {
$endTime = $component->DTEND->getDateTime($this->timeZone);
} elseif (isset($component->DURATION)) {
$duration = DateTimeParser::parseDuration((string) $component->DURATION);
$endTime = clone $startTime;
$endTime = $endTime->add($duration);
} elseif (!$component->DTSTART->hasTime()) {
$endTime = clone $startTime;
$endTime = $endTime->modify('+1 day');
} else {
// The event had no duration (0 seconds)
break;
}
$times[] = [$startTime, $endTime];
}
foreach ($times as $time) {
if ($this->end && $time[0] > $this->end) {
break;
}
if ($this->start && $time[1] < $this->start) {
break;
}
$busyTimes[] = [$time[0], $time[1], $FBTYPE];
}
break;
case 'VFREEBUSY':
foreach ($component->FREEBUSY as $freebusy) {
$fbType = isset($freebusy['FBTYPE']) ? strtoupper($freebusy['FBTYPE']) : 'BUSY';
// Skipping intervals marked as 'free'
if ($fbType === 'FREE') {
continue;
}
$values = explode(',', $freebusy);
foreach ($values as $value) {
list($startTime, $endTime) = explode('/', $value);
$startTime = DateTimeParser::parseDateTime($startTime);
if (substr($endTime, 0, 1) === 'P' || substr($endTime, 0, 2) === '-P') {
$duration = DateTimeParser::parseDuration($endTime);
$endTime = clone $startTime;
$endTime = $endTime->add($duration);
} else {
$endTime = DateTimeParser::parseDateTime($endTime);
}
if ($this->start && $this->start > $endTime) {
continue;
//.........这里部分代码省略.........
示例8: parseExpand
/**
* Parses the CALDAV:expand element
*
* @param \DOMElement $parentNode
* @return void
*/
protected function parseExpand(\DOMElement $parentNode)
{
$start = $parentNode->getAttribute('start');
if (!$start) {
throw new \Sabre\DAV\Exception\BadRequest('The "start" attribute is required for the CALDAV:expand element');
}
$start = VObject\DateTimeParser::parseDateTime($start);
$end = $parentNode->getAttribute('end');
if (!$end) {
throw new \Sabre\DAV\Exception\BadRequest('The "end" attribute is required for the CALDAV:expand element');
}
$end = VObject\DateTimeParser::parseDateTime($end);
if ($end <= $start) {
throw new \Sabre\DAV\Exception\BadRequest('The end-date must be larger than the start-date in the expand element.');
}
return array('start' => $start, 'end' => $end);
}
示例9: validate
/**
* 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
*/
function validate($options = 0)
{
$messages = parent::validate($options);
$valueType = $this->getValueType();
$values = $this->getParts();
try {
foreach ($values as $value) {
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];
}
return $messages;
}
示例10: calculateBusy
/**
* This method takes an array of iCalendar objects and applies its busy
* times on fbData.
*
* @param FreeBusyData $fbData
* @param VCalendar[] $objects
*/
protected function calculateBusy(FreeBusyData $fbData, array $objects)
{
foreach ($objects as $key => $object) {
foreach ($object->getBaseComponents() as $component) {
switch ($component->name) {
case 'VEVENT':
$FBTYPE = 'BUSY';
if (isset($component->TRANSP) && strtoupper($component->TRANSP) === 'TRANSPARENT') {
break;
}
if (isset($component->STATUS)) {
$status = strtoupper($component->STATUS);
if ($status === 'CANCELLED') {
break;
}
if ($status === 'TENTATIVE') {
$FBTYPE = 'BUSY-TENTATIVE';
}
}
$times = [];
if ($component->RRULE) {
try {
$iterator = new EventIterator($object, (string) $component->uid, $this->timeZone);
} catch (NoInstancesException $e) {
// This event is recurring, but it doesn't have a single
// instance. We are skipping this event from the output
// entirely.
unset($this->objects[$key]);
continue;
}
if ($this->start) {
$iterator->fastForward($this->start);
}
$maxRecurrences = Settings::$maxRecurrences;
while ($iterator->valid() && --$maxRecurrences) {
$startTime = $iterator->getDTStart();
if ($this->end && $startTime > $this->end) {
break;
}
$times[] = [$iterator->getDTStart(), $iterator->getDTEnd()];
$iterator->next();
}
} else {
$startTime = $component->DTSTART->getDateTime($this->timeZone);
if ($this->end && $startTime > $this->end) {
break;
}
$endTime = null;
if (isset($component->DTEND)) {
$endTime = $component->DTEND->getDateTime($this->timeZone);
} elseif (isset($component->DURATION)) {
$duration = DateTimeParser::parseDuration((string) $component->DURATION);
$endTime = clone $startTime;
$endTime = $endTime->add($duration);
} elseif (!$component->DTSTART->hasTime()) {
$endTime = clone $startTime;
$endTime = $endTime->modify('+1 day');
} else {
// The event had no duration (0 seconds)
break;
}
$times[] = [$startTime, $endTime];
}
foreach ($times as $time) {
if ($this->end && $time[0] > $this->end) {
break;
}
if ($this->start && $time[1] < $this->start) {
break;
}
$fbData->add($time[0]->getTimeStamp(), $time[1]->getTimeStamp(), $FBTYPE);
}
break;
case 'VFREEBUSY':
foreach ($component->FREEBUSY as $freebusy) {
$fbType = isset($freebusy['FBTYPE']) ? strtoupper($freebusy['FBTYPE']) : 'BUSY';
// Skipping intervals marked as 'free'
if ($fbType === 'FREE') {
continue;
}
$values = explode(',', $freebusy);
foreach ($values as $value) {
list($startTime, $endTime) = explode('/', $value);
$startTime = DateTimeParser::parseDateTime($startTime);
if (substr($endTime, 0, 1) === 'P' || substr($endTime, 0, 2) === '-P') {
$duration = DateTimeParser::parseDuration($endTime);
$endTime = clone $startTime;
$endTime = $endTime->add($duration);
} else {
$endTime = DateTimeParser::parseDateTime($endTime);
}
if ($this->start && $this->start > $endTime) {
continue;
//.........这里部分代码省略.........
示例11: freeBusyQueryReport
/**
* This method is responsible for parsing the request and generating the
* response for the CALDAV:free-busy-query REPORT.
*
* @param \DOMNode $dom
* @return void
*/
protected function freeBusyQueryReport(\DOMNode $dom)
{
$start = null;
$end = null;
foreach ($dom->firstChild->childNodes as $childNode) {
$clark = DAV\XMLUtil::toClarkNotation($childNode);
if ($clark == '{' . self::NS_CALDAV . '}time-range') {
$start = $childNode->getAttribute('start');
$end = $childNode->getAttribute('end');
break;
}
}
if ($start) {
$start = VObject\DateTimeParser::parseDateTime($start);
}
if ($end) {
$end = VObject\DateTimeParser::parseDateTime($end);
}
$uri = $this->server->getRequestUri();
if (!$start && !$end) {
throw new DAV\Exception\BadRequest('The freebusy report must have a time-range filter');
}
$acl = $this->server->getPlugin('acl');
if ($acl) {
$acl->checkPrivileges($uri, '{' . self::NS_CALDAV . '}read-free-busy');
}
$calendar = $this->server->tree->getNodeForPath($uri);
if (!$calendar instanceof ICalendar) {
throw new DAV\Exception\NotImplemented('The free-busy-query REPORT is only implemented on calendars');
}
$tzProp = '{' . self::NS_CALDAV . '}calendar-timezone';
// Figuring out the default timezone for the calendar, for floating
// times.
$calendarProps = $this->server->getProperties($uri, [$tzProp]);
if (isset($calendarProps[$tzProp])) {
$vtimezoneObj = VObject\Reader::read($calendarProps[$tzProp]);
$calendarTimeZone = $vtimezoneObj->VTIMEZONE->getTimeZone();
} else {
$calendarTimeZone = new DateTimeZone('UTC');
}
// Doing a calendar-query first, to make sure we get the most
// performance.
$urls = $calendar->calendarQuery(['name' => 'VCALENDAR', 'comp-filters' => [['name' => 'VEVENT', 'comp-filters' => [], 'prop-filters' => [], 'is-not-defined' => false, 'time-range' => ['start' => $start, 'end' => $end]]], 'prop-filters' => [], 'is-not-defined' => false, 'time-range' => null]);
$objects = array_map(function ($url) use($calendar) {
$obj = $calendar->getChild($url)->get();
return $obj;
}, $urls);
$generator = new VObject\FreeBusyGenerator();
$generator->setObjects($objects);
$generator->setTimeRange($start, $end);
$generator->setTimeZone($calendarTimeZone);
$result = $generator->getResult();
$result = $result->serialize();
$this->server->httpResponse->setStatus(200);
$this->server->httpResponse->setHeader('Content-Type', 'text/calendar');
$this->server->httpResponse->setHeader('Content-Length', strlen($result));
$this->server->httpResponse->setBody($result);
}
示例12: freeBusyQueryReport
/**
* This method is responsible for parsing the request and generating the
* response for the CALDAV:free-busy-query REPORT.
*
* @param \DOMNode $dom
* @return void
*/
protected function freeBusyQueryReport(\DOMNode $dom)
{
$start = null;
$end = null;
foreach ($dom->firstChild->childNodes as $childNode) {
$clark = DAV\XMLUtil::toClarkNotation($childNode);
if ($clark == '{' . self::NS_CALDAV . '}time-range') {
$start = $childNode->getAttribute('start');
$end = $childNode->getAttribute('end');
break;
}
}
if ($start) {
$start = VObject\DateTimeParser::parseDateTime($start);
}
if ($end) {
$end = VObject\DateTimeParser::parseDateTime($end);
}
if (!$start && !$end) {
throw new DAV\Exception\BadRequest('The freebusy report must have a time-range filter');
}
$acl = $this->server->getPlugin('acl');
if (!$acl) {
throw new DAV\Exception('The ACL plugin must be loaded for free-busy queries to work');
}
$uri = $this->server->getRequestUri();
$acl->checkPrivileges($uri, '{' . self::NS_CALDAV . '}read-free-busy');
$calendar = $this->server->tree->getNodeForPath($uri);
if (!$calendar instanceof ICalendar) {
throw new DAV\Exception\NotImplemented('The free-busy-query REPORT is only implemented on calendars');
}
// Doing a calendar-query first, to make sure we get the most
// performance.
$urls = $calendar->calendarQuery(array('name' => 'VCALENDAR', 'comp-filters' => array(array('name' => 'VEVENT', 'comp-filters' => array(), 'prop-filters' => array(), 'is-not-defined' => false, 'time-range' => array('start' => $start, 'end' => $end))), 'prop-filters' => array(), 'is-not-defined' => false, 'time-range' => null));
$objects = array_map(function ($url) use($calendar) {
$obj = $calendar->getChild($url)->get();
return $obj;
}, $urls);
$generator = new VObject\FreeBusyGenerator();
$generator->setObjects($objects);
$generator->setTimeRange($start, $end);
$result = $generator->getResult();
$result = $result->serialize();
$this->server->httpResponse->sendStatus(200);
$this->server->httpResponse->setHeader('Content-Type', 'text/calendar');
$this->server->httpResponse->setHeader('Content-Length', strlen($result));
$this->server->httpResponse->sendBody($result);
}
示例13: validate
/**
* 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();
$value = $this->getValue();
try {
switch ($valueType) {
case 'DATE':
$foo = DateTimeParser::parseDate($value);
break;
case 'DATE-TIME':
$foo = DateTimeParser::parseDateTime($value);
break;
}
} catch (\LogicException $e) {
$messages[] = array('level' => 3, 'message' => 'The supplied value (' . $value . ') is not a correct ' . $valueType, 'node' => $this);
}
return $messages;
}
示例14: testParseICalendarDateTimeCustomTimeZone
/**
* @depends testParseICalendarDateTime
*/
function testParseICalendarDateTimeCustomTimeZone()
{
$dateTime = DateTimeParser::parseDateTime('20100316T141405', new DateTimeZone('Europe/Amsterdam'));
$compare = new DateTime('2010-03-16 13:14:05', new DateTimeZone('UTC'));
$this->assertEquals($compare, $dateTime);
}
示例15: parseEventForAttendee
/**
* Parse an event update for an attendee.
*
* This function figures out if we need to send a reply to an organizer.
*
* @param VCalendar $calendar
* @param array $eventInfo
* @param array $oldEventInfo
* @param string $attendee
* @return Message[]
*/
protected function parseEventForAttendee(VCalendar $calendar, array $eventInfo, array $oldEventInfo, $attendee)
{
$instances = array();
foreach ($oldEventInfo['attendees'][$attendee]['instances'] as $instance) {
$instances[$instance['id']] = array('id' => $instance['id'], 'oldstatus' => $instance['partstat'], 'newstatus' => null);
}
foreach ($eventInfo['attendees'][$attendee]['instances'] as $instance) {
if (isset($instances[$instance['id']])) {
$instances[$instance['id']]['newstatus'] = $instance['partstat'];
} else {
$instances[$instance['id']] = array('id' => $instance['id'], 'oldstatus' => null, 'newstatus' => $instance['partstat']);
}
}
// We need to also look for differences in EXDATE. If there are new
// items in EXDATE, it means that an attendee deleted instances of an
// event, which means we need to send DECLINED specifically for those
// instances.
// We only need to do that though, if the master event is not declined.
if ($instances['master']['newstatus'] !== 'DECLINED') {
foreach ($eventInfo['exdate'] as $exDate) {
if (!in_array($exDate, $oldEventInfo['exdate'])) {
$instances[$exDate] = array('id' => $exDate, 'oldstatus' => $instances['master']['oldstatus'], 'newstatus' => 'DECLINED');
}
}
}
$message = new Message();
$message->uid = $eventInfo['uid'];
$message->method = 'REPLY';
$message->component = 'VEVENT';
$message->sequence = $eventInfo['sequence'];
$message->sender = $attendee;
$message->senderName = $eventInfo['attendees'][$attendee]['name'];
$message->recipient = $eventInfo['organizer'];
$message->recipientName = $eventInfo['organizerName'];
$icalMsg = new VCalendar();
$icalMsg->METHOD = 'REPLY';
$hasReply = false;
foreach ($instances as $instance) {
if ($instance['oldstatus'] == $instance['newstatus']) {
// Skip
continue;
}
$event = $icalMsg->add('VEVENT', array('UID' => $message->uid, 'SEQUENCE' => $message->sequence));
if ($instance['id'] !== 'master') {
$event->{'RECURRENCE-ID'} = DateTimeParser::parseDateTime($instance['id'], $eventInfo['timezone']);
}
$organizer = $event->add('ORGANIZER', $message->recipient);
if ($message->recipientName) {
$organizer['CN'] = $message->recipientName;
}
$attendee = $event->add('ATTENDEE', $message->sender, array('PARTSTAT' => $instance['newstatus']));
if ($message->senderName) {
$attendee['CN'] = $message->senderName;
}
$hasReply = true;
}
if ($hasReply) {
$message->message = $icalMsg;
return array($message);
} else {
return array();
}
}