public function parseEvent($calendar = null, $userHref, $oldCalendar = null)
    {
        if ($oldCalendar) {
            if (is_string($oldCalendar)) {
                $oldCalendar = Reader::read($oldCalendar);
            }
            if (!isset($oldCalendar->VEVENT)) {
                // We only support events at the moment
                return [];
            }

            $oldEventInfo = $this->parseEventInfo($oldCalendar);
        } else {
            $oldEventInfo = [
                'organizer' => null,
                'significantChangeHash' => '',
                'attendees' => [],
            ];
        }

        $userHref = (array) $userHref;

        if (!is_null($calendar)) {
            if (is_string($calendar)) {
                $calendar = Reader::read($calendar);
            }
            if (!isset($calendar->VEVENT)) {
                // We only support events at the moment
                return [];
            }
            $eventInfo = $this->parseEventInfo($calendar);
            if (!$eventInfo['attendees'] && !$oldEventInfo['attendees']) {
                // If there were no attendees on either side of the equation,
                // we don't need to do anything.
                return [];
            }
            if (!$eventInfo['organizer'] && !$oldEventInfo['organizer']) {
                // There was no organizer before or after the change.
                return [];
            }

            $baseCalendar = $calendar;

            // If the new object didn't have an organizer, the organizer
            // changed the object from a scheduling object to a non-scheduling
            // object. We just copy the info from the old object.
            if (!$eventInfo['organizer'] && $oldEventInfo['organizer']) {
                $eventInfo['organizer'] = $oldEventInfo['organizer'];
                $eventInfo['organizerName'] = $oldEventInfo['organizerName'];
            }
        } else {
            // The calendar object got deleted, we need to process this as a
            // cancellation / decline.
            if (!$oldCalendar) {
                // No old and no new calendar, there's no thing to do.
                return [];
            }

            $eventInfo = $oldEventInfo;

            if (in_array($eventInfo['organizer'], $userHref)) {
                // This is an organizer deleting the event.
                $eventInfo['attendees'] = [];
                // Increasing the sequence, but only if the organizer deleted
                // the event.
                ++$eventInfo['sequence'];
            } else {
                // This is an attendee deleting the event.
                foreach ($eventInfo['attendees'] as $key => $attendee) {
                    if (in_array($attendee['href'], $userHref)) {
                        $eventInfo['attendees'][$key]['instances'] = ['master' => ['id' => 'master', 'partstat' => 'DECLINED'],
                        ];
                    }
                }
            }
            $baseCalendar = $oldCalendar;
        }

        if (in_array($eventInfo['organizer'], $userHref)) {
            return $this->parseEventForOrganizer($baseCalendar, $eventInfo, $oldEventInfo);
        } elseif ($oldCalendar) {
            // We need to figure out if the user is an attendee, but we're only
            // doing so if there's an oldCalendar, because we only want to
            // process updates, not creation of new events.
            foreach ($eventInfo['attendees'] as $attendee) {
                if (in_array($attendee['href'], $userHref)) {
                    return $this->parseEventForAttendee($baseCalendar, $eventInfo, $oldEventInfo, $attendee['href']);
                }
            }
        }

        return [];
    }
public function parseEvent($calendar = null, $userHref, $oldCalendar = null)
    {
        if ($oldCalendar) {
            if (is_string($oldCalendar)) {
                $oldCalendar = Reader::read($oldCalendar);
            }
            if (!isset($oldCalendar->VEVENT)) {
                // We only support events at the moment
                return [];
            }

            $oldEventInfo = $this->parseEventInfo($oldCalendar);
        } else {
            $oldEventInfo = [
                'organizer' => null,
                'significantChangeHash' => '',
                'attendees' => [],
            ];
        }

        $userHref = (array) $userHref;

        if (!is_null($calendar)) {
            if (is_string($calendar)) {
                $calendar = Reader::read($calendar);
            }
            if (!isset($calendar->VEVENT)) {
                // We only support events at the moment
                return [];
            }
            $eventInfo = $this->parseEventInfo($calendar);
            if (!$eventInfo['attendees'] && !$oldEventInfo['attendees']) {
                // If there were no attendees on either side of the equation,
                // we don't need to do anything.
                return [];
            }
            if (!$eventInfo['organizer'] && !$oldEventInfo['organizer']) {
                // There was no organizer before or after the change.
                return [];
            }

            $baseCalendar = $calendar;

            // If the new object didn't have an organizer, the organizer
            // changed the object from a scheduling object to a non-scheduling
            // object. We just copy the info from the old object.
            if (!$eventInfo['organizer'] && $oldEventInfo['organizer']) {
                $eventInfo['organizer'] = $oldEventInfo['organizer'];
                $eventInfo['organizerName'] = $oldEventInfo['organizerName'];
            }
        } else {
            // The calendar object got deleted, we need to process this as a
            // cancellation / decline.
            if (!$oldCalendar) {
                // No old and no new calendar, there's no thing to do.
                return [];
            }

            $eventInfo = $oldEventInfo;

            if (in_array($eventInfo['organizer'], $userHref)) {
                // This is an organizer deleting the event.
                $eventInfo['attendees'] = [];
                // Increasing the sequence, but only if the organizer deleted
                // the event.
                ++$eventInfo['sequence'];
            } else {
                // This is an attendee deleting the event.
                foreach ($eventInfo['attendees'] as $key => $attendee) {
                    if (in_array($attendee['href'], $userHref)) {
                        $eventInfo['attendees'][$key]['instances'] = ['master' => ['id' => 'master', 'partstat' => 'DECLINED'],
                        ];
                    }
                }
            }
            $baseCalendar = $oldCalendar;
        }

        if (in_array($eventInfo['organizer'], $userHref)) {
            return $this->parseEventForOrganizer($baseCalendar, $eventInfo, $oldEventInfo);
        } elseif ($oldCalendar) {
            // We need to figure out if the user is an attendee, but we're only
            // doing so if there's an oldCalendar, because we only want to
            // process updates, not creation of new events.
            foreach ($eventInfo['attendees'] as $attendee) {
                if (in_array($attendee['href'], $userHref)) {
                    return $this->parseEventForAttendee($baseCalendar, $eventInfo, $oldEventInfo, $attendee['href']);
                }
            }
        }

        return [];
    }
public function parseEvent ( $ calendar = null , $ userHref , $ oldCalendar = null ) { if ( $ oldCalendar ) { if ( is_string ( $ oldCalendar ) ) { $ oldCalendar = Reader :: read ( $ oldCalendar ) ; } if ( ! isset ( $ oldCalendar -> VEVENT ) ) { // We only support events at the moment return [ ] ; } $ oldEventInfo = $ this -> parseEventInfo ( $ oldCalendar ) ; } else { $ oldEventInfo = [ 'organizer' => null , 'significantChangeHash' => '' , 'attendees' => [ ] , ] ; } $ userHref = ( array ) $ userHref ; if ( ! is_null ( $ calendar ) ) { if ( is_string ( $ calendar ) ) { $ calendar = Reader :: read ( $ calendar ) ; } if ( ! isset ( $ calendar -> VEVENT ) ) { // We only support events at the moment return [ ] ; } $ eventInfo = $ this -> parseEventInfo ( $ calendar ) ; if ( ! $ eventInfo [ 'attendees' ] && ! $ oldEventInfo [ 'attendees' ] ) { // If there were no attendees on either side of the equation, // we don't need to do anything. return [ ] ; } if ( ! $ eventInfo [ 'organizer' ] && ! $ oldEventInfo [ 'organizer' ] ) { // There was no organizer before or after the change. return [ ] ; } $ baseCalendar = $ calendar ; // If the new object didn't have an organizer, the organizer // changed the object from a scheduling object to a non-scheduling // object. We just copy the info from the old object. if ( ! $ eventInfo [ 'organizer' ] && $ oldEventInfo [ 'organizer' ] ) { $ eventInfo [ 'organizer' ] = $ oldEventInfo [ 'organizer' ] ; $ eventInfo [ 'organizerName' ] = $ oldEventInfo [ 'organizerName' ] ; } } else { // The calendar object got deleted, we need to process this as a // cancellation / decline. if ( ! $ oldCalendar ) { // No old and no new calendar, there's no thing to do. return [ ] ; } $ eventInfo = $ oldEventInfo ; if ( in_array ( $ eventInfo [ 'organizer' ] , $ userHref ) ) { // This is an organizer deleting the event. $ eventInfo [ 'attendees' ] = [ ] ; // Increasing the sequence, but only if the organizer deleted // the event. ++ $ eventInfo [ 'sequence' ] ; } else { // This is an attendee deleting the event. foreach ( $ eventInfo [ 'attendees' ] as $ key => $ attendee ) { if ( in_array ( $ attendee [ 'href' ] , $ userHref ) ) { $ eventInfo [ 'attendees' ] [ $ key ] [ 'instances' ] = [ 'master' => [ 'id' => 'master' , 'partstat' => 'DECLINED' ] , ] ; } } } $ baseCalendar = $ oldCalendar ; } if ( in_array ( $ eventInfo [ 'organizer' ] , $ userHref ) ) { return $ this -> parseEventForOrganizer ( $ baseCalendar , $ eventInfo , $ oldEventInfo ) ; } elseif ( $ oldCalendar ) { // We need to figure out if the user is an attendee, but we're only // doing so if there's an oldCalendar, because we only want to // process updates, not creation of new events. foreach ( $ eventInfo [ 'attendees' ] as $ attendee ) { if ( in_array ( $ attendee [ 'href' ] , $ userHref ) ) { return $ this -> parseEventForAttendee ( $ baseCalendar , $ eventInfo , $ oldEventInfo , $ attendee [ 'href' ] ) ; } } } return [ ] ; }
This function parses a VCALENDAR object and figure out if any messages
need to be sent.

A VCALENDAR object will be created from the perspective of either an
attendee, or an organizer. You must pass a string identifying the
current user, so we can figure out who in the list of attendees or the
organizer we are sending this message on behalf of.

It's possible to specify the current user as an array, in case the user
has more than one identifying href (such as multiple emails).

It $oldCalendar is specified, it is assumed that the operation is
updating an existing event, which means that we need to look at the
differences between events, and potentially send old attendees
cancellations, and current attendees updates.

If $calendar is null, but $oldCalendar is specified, we treat the
operation as if the user has deleted an event. If the user was an
organizer, this means that we need to send cancellation notices to
people. If the user was an attendee, we need to make sure that the
organizer gets the 'declined' message.

@param VCalendar|string $calendar
@param string|array     $userHref
@param VCalendar|string $oldCalendar

@return array
This function parses a VCALENDAR object and figure out if any messages need to be sent .