/** * Returns free-busy information for a specific address. The returned * data is an array containing the following properties: * * calendar-data : A VFREEBUSY VObject * request-status : an iTip status code. * href: The principal's email address, as requested * * The following request status codes may be returned: * * 2.0;description * * 3.7;description * * @param string $email address * @param \DateTime $start * @param \DateTime $end * @param VObject\Component $request * @return array */ protected function getFreeBusyForEmail($email, \DateTime $start, \DateTime $end, VObject\Component $request) { $caldavNS = '{' . Plugin::NS_CALDAV . '}'; $aclPlugin = $this->server->getPlugin('acl'); if (substr($email, 0, 7) === 'mailto:') { $email = substr($email, 7); } $result = $aclPlugin->principalSearch(['{http://sabredav.org/ns}email-address' => $email], ['{DAV:}principal-URL', $caldavNS . 'calendar-home-set', '{http://sabredav.org/ns}email-address']); if (!count($result)) { return ['request-status' => '3.7;Could not find principal', 'href' => 'mailto:' . $email]; } if (!isset($result[0][200][$caldavNS . 'calendar-home-set'])) { return ['request-status' => '3.7;No calendar-home-set property found', 'href' => 'mailto:' . $email]; } $homeSet = $result[0][200][$caldavNS . 'calendar-home-set']->getHref(); // Grabbing the calendar list $objects = []; foreach ($this->server->tree->getNodeForPath($homeSet)->getChildren() as $node) { if (!$node instanceof ICalendar) { continue; } $sct = $caldavNS . 'schedule-calendar-transp'; $ctz = $caldavNS . 'calendar-timezone'; $props = $node->getProperties([$sct, $ctz]); if (isset($props[$sct]) && $props[$sct]->getValue() == ScheduleCalendarTransp::TRANSPARENT) { // If a calendar is marked as 'transparent', it means we must // ignore it for free-busy purposes. continue; } $aclPlugin->checkPrivileges($homeSet . $node->getName(), $caldavNS . 'read-free-busy'); if (isset($props[$ctz])) { $vtimezoneObj = VObject\Reader::read($props[$ctz]); $calendarTimeZone = $vtimezoneObj->VTIMEZONE->getTimeZone(); } else { $calendarTimeZone = new DateTimeZone('UTC'); } // Getting the list of object uris within the time-range $urls = $node->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]); $calObjects = array_map(function ($url) use($node) { $obj = $node->getChild($url)->get(); return $obj; }, $urls); $objects = array_merge($objects, $calObjects); } $vcalendar = new VObject\Component\VCalendar(); $vcalendar->METHOD = 'REPLY'; $generator = new VObject\FreeBusyGenerator(); $generator->setObjects($objects); $generator->setTimeRange($start, $end); $generator->setBaseObject($vcalendar); $generator->setTimeZone($calendarTimeZone); $result = $generator->getResult(); $vcalendar->VFREEBUSY->ATTENDEE = 'mailto:' . $email; $vcalendar->VFREEBUSY->UID = (string) $request->VFREEBUSY->UID; $vcalendar->VFREEBUSY->ORGANIZER = clone $request->VFREEBUSY->ORGANIZER; return ['calendar-data' => $result, 'request-status' => '2.0;Success', 'href' => 'mailto:' . $email]; }
/** * Returns free-busy information for a specific address. The returned * data is an array containing the following properties: * * calendar-data : A VFREEBUSY VObject * request-status : an iTip status code. * href: The principal's email address, as requested * * The following request status codes may be returned: * * 2.0;description * * 3.7;description * * @param string $email address * @param \DateTime $start * @param \DateTime $end * @param VObject\Component $request * @return array */ protected function getFreeBusyForEmail($email, \DateTime $start, \DateTime $end, VObject\Component $request) { $caldavNS = '{' . Plugin::NS_CALDAV . '}'; $aclPlugin = $this->server->getPlugin('acl'); if (substr($email, 0, 7) === 'mailto:') { $email = substr($email, 7); } $result = $aclPlugin->principalSearch(array('{http://sabredav.org/ns}email-address' => $email), array('{DAV:}principal-URL', $caldavNS . 'calendar-home-set', '{http://sabredav.org/ns}email-address')); if (!count($result)) { return array('request-status' => '3.7;Could not find principal', 'href' => 'mailto:' . $email); } if (!isset($result[0][200][$caldavNS . 'calendar-home-set'])) { return array('request-status' => '3.7;No calendar-home-set property found', 'href' => 'mailto:' . $email); } $homeSet = $result[0][200][$caldavNS . 'calendar-home-set']->getHref(); // Grabbing the calendar list $objects = array(); foreach ($this->server->tree->getNodeForPath($homeSet)->getChildren() as $node) { if (!$node instanceof ICalendar) { continue; } $aclPlugin->checkPrivileges($homeSet . $node->getName(), $caldavNS . 'read-free-busy'); // Getting the list of object uris within the time-range $urls = $node->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)); $calObjects = array_map(function ($url) use($node) { $obj = $node->getChild($url)->get(); return $obj; }, $urls); $objects = array_merge($objects, $calObjects); } $vcalendar = VObject\Component::create('VCALENDAR'); $vcalendar->VERSION = '2.0'; $vcalendar->METHOD = 'REPLY'; $vcalendar->CALSCALE = 'GREGORIAN'; $vcalendar->PRODID = '-//SabreDAV//SabreDAV ' . DAV\Version::VERSION . '//EN'; $generator = new VObject\FreeBusyGenerator(); $generator->setObjects($objects); $generator->setTimeRange($start, $end); $generator->setBaseObject($vcalendar); $result = $generator->getResult(); $vcalendar->VFREEBUSY->ATTENDEE = 'mailto:' . $email; $vcalendar->VFREEBUSY->UID = (string) $request->VFREEBUSY->UID; $vcalendar->VFREEBUSY->ORGANIZER = clone $request->VFREEBUSY->ORGANIZER; return array('calendar-data' => $result, 'request-status' => '2.0;Success', 'href' => 'mailto:' . $email); }