Ejemplo n.º 1
0
 /**
  * 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 DateTimeInterface $start
  * @param DateTimeInterface $end
  * @param VObject\Component $request
  * @return array
  */
 protected function getFreeBusyForEmail($email, \DateTimeInterface $start, \DateTimeInterface $end, VObject\Component $request)
 {
     $caldavNS = '{' . self::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', $caldavNS . 'schedule-inbox-URL', '{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];
     }
     if (!isset($result[0][200][$caldavNS . 'schedule-inbox-URL'])) {
         return ['request-status' => '3.7;No schedule-inbox-URL property found', 'href' => 'mailto:' . $email];
     }
     $homeSet = $result[0][200][$caldavNS . 'calendar-home-set']->getHref();
     $inboxUrl = $result[0][200][$caldavNS . 'schedule-inbox-URL']->getHref();
     // Grabbing the calendar list
     $objects = [];
     $calendarTimeZone = new DateTimeZone('UTC');
     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();
             // Destroy circular references so PHP can garbage collect the object.
             $vtimezoneObj->destroy();
         }
         // 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);
     }
     $inboxProps = $this->server->getProperties($inboxUrl, $caldavNS . 'calendar-availability');
     $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);
     if ($inboxProps) {
         $generator->setVAvailability(VObject\Reader::read($inboxProps[$caldavNS . 'calendar-availability']));
     }
     $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];
 }