119        $this->baseObject = $vcalendar;
 
  131        $this->vavailability = $vcalendar;
 
  155            if (is_string($object) || is_resource($object)) {
 
  157            } elseif ($object instanceof 
Component) {
 
  158                $this->objects[] = $object;
 
  160                throw new \InvalidArgumentException(
'You can only pass strings or \\Sabre\\VObject\\Component arguments to setObjects');
 
  212            $this->start->getTimeStamp(),
 
  213            $this->end->getTimeStamp()
 
  215        if ($this->vavailability) {
 
  248                $priorityA = isset($a->PRIORITY) ? (int)$a->PRIORITY->getValue() : 0;
 
  249                $priorityB = isset($b->PRIORITY) ? (int)$b->PRIORITY->getValue() : 0;
 
  251                if ($priorityA === 0) $priorityA = 10;
 
  252                if ($priorityB === 0) $priorityB = 10;
 
  254                return $priorityA - $priorityB;
 
  269        foreach ($old as $vavail) {
 
  271            list($compStart, $compEnd) = $vavail->getEffectiveStartEnd();
 
  276            if (is_null($compStart) || $compStart < $this->start) {
 
  279            if (is_null($compEnd) || $compEnd > $this->end) {
 
  284            if ($compStart > $this->end || $compEnd < $this->start) {
 
  290            foreach ($new as $higherVavail) {
 
  292                list($higherStart, $higherEnd) = $higherVavail->getEffectiveStartEnd();
 
  294                    (is_null($higherStart) || $higherStart < $compStart) &&
 
  295                    (is_null($higherEnd) || $higherEnd > $compEnd)
 
  316        foreach (array_reverse($new) as $vavail) {
 
  318            $busyType = isset($vavail->BUSYTYPE) ? strtoupper($vavail->BUSYTYPE) : 
'BUSY-UNAVAILABLE';
 
  319            list($vavailStart, $vavailEnd) = $vavail->getEffectiveStartEnd();
 
  323            if (!$vavailStart || $vavailStart < $this->start) {
 
  326            if (!$vavailEnd || $vavailEnd > $this->end) {
 
  333                $vavailStart->getTimeStamp(),
 
  334                $vavailEnd->getTimeStamp(),
 
  339            if (isset($vavail->AVAILABLE)) 
foreach ($vavail->AVAILABLE as $available) {
 
  341                list($availStart, $availEnd) = $available->getEffectiveStartEnd();
 
  343                    $availStart->getTimeStamp(),
 
  344                    $availEnd->getTimeStamp(),
 
  348                if ($available->RRULE) {
 
  352                        $available->RRULE->getValue(),
 
  355                    $rruleIterator->fastForward($vavailStart);
 
  357                    $startEndDiff = $availStart->diff($availEnd);
 
  359                    while ($rruleIterator->valid()) {
 
  361                        $recurStart = $rruleIterator->current();
 
  362                        $recurEnd = $recurStart->add($startEndDiff);
 
  364                        if ($recurStart > $vavailEnd) {
 
  369                        if ($recurEnd > $vavailEnd) {
 
  372                            $recurEnd = $vavailEnd;
 
  376                            $recurStart->getTimeStamp(),
 
  377                            $recurEnd->getTimeStamp(),
 
  381                        $rruleIterator->next();
 
  403            foreach ($object->getBaseComponents() as $component) {
 
  405                switch ($component->name) {
 
  410                        if (isset($component->TRANSP) && (strtoupper($component->TRANSP) === 
'TRANSPARENT')) {
 
  413                        if (isset($component->STATUS)) {
 
  414                            $status = strtoupper($component->STATUS);
 
  415                            if ($status === 
'CANCELLED') {
 
  418                            if ($status === 
'TENTATIVE') {
 
  419                                $FBTYPE = 
'BUSY-TENTATIVE';
 
  425                        if ($component->RRULE) {
 
  427                                $iterator = 
new EventIterator($object, (
string)$component->UID, $this->timeZone);
 
  432                                unset($this->objects[
$key]);
 
  437                                $iterator->fastForward($this->start);
 
  442                            while ($iterator->valid() && --$maxRecurrences) {
 
  444                                $startTime = $iterator->getDTStart();
 
  445                                if ($this->end && $startTime > $this->end) {
 
  449                                    $iterator->getDTStart(),
 
  450                                    $iterator->getDTEnd(),
 
  459                            $startTime = $component->DTSTART->getDateTime($this->timeZone);
 
  460                            if ($this->end && $startTime > $this->end) {
 
  464                            if (isset($component->DTEND)) {
 
  465                                $endTime = $component->DTEND->getDateTime($this->timeZone);
 
  466                            } elseif (isset($component->DURATION)) {
 
  468                                $endTime = clone $startTime;
 
  469                                $endTime = $endTime->add($duration);
 
  470                            } elseif (!$component->DTSTART->hasTime()) {
 
  471                                $endTime = clone $startTime;
 
  472                                $endTime = $endTime->modify(
'+1 day');
 
  478                            $times[] = [$startTime, $endTime];
 
  482                        foreach ($times as 
$time) {
 
  484                            if ($this->end && 
$time[0] > $this->end) 
break;
 
  485                            if ($this->start && 
$time[1] < $this->start) 
break;
 
  488                                $time[0]->getTimeStamp(),
 
  489                                $time[1]->getTimeStamp(),
 
  496                        foreach ($component->FREEBUSY as $freebusy) {
 
  498                            $fbType = isset($freebusy[
'FBTYPE']) ? strtoupper($freebusy[
'FBTYPE']) : 
'BUSY';
 
  501                            if ($fbType === 
'FREE')
 
  504                            $values = explode(
',', $freebusy);
 
  506                                list($startTime, $endTime) = explode(
'/', $value);
 
  509                                if (substr($endTime, 0, 1) === 
'P' || substr($endTime, 0, 2) === 
'-P') {
 
  511                                    $endTime = clone $startTime;
 
  512                                    $endTime = $endTime->add($duration);
 
  517                                if ($this->start && $this->start > $endTime) 
continue;
 
  518                                if ($this->end && $this->end < $startTime) 
continue;
 
  520                                    $startTime->getTimeStamp(),
 
  521                                    $endTime->getTimeStamp(),
 
  548        if ($this->baseObject) {
 
  554        $vfreebusy = 
$calendar->createComponent(
'VFREEBUSY');
 
  558            $dtstart = 
$calendar->createProperty(
'DTSTART');
 
  559            $dtstart->setDateTime($this->start);
 
  560            $vfreebusy->add($dtstart);
 
  563            $dtend = 
$calendar->createProperty(
'DTEND');
 
  564            $dtend->setDateTime($this->end);
 
  565            $vfreebusy->add($dtend);
 
  568        $tz = new \DateTimeZone(
'UTC');
 
  569        $dtstamp = 
$calendar->createProperty(
'DTSTAMP');
 
  570        $dtstamp->setDateTime(
new DateTimeImmutable(
'now', 
$tz));
 
  571        $vfreebusy->add($dtstamp);
 
  573        foreach ($fbData->
getData() as $busyTime) {
 
  575            $busyType = strtoupper($busyTime[
'type']);
 
  578            if ($busyType === 
'FREE') {
 
  582            $busyTime[0] = new \DateTimeImmutable(
'@' . $busyTime[
'start'], 
$tz);
 
  583            $busyTime[1] = new \DateTimeImmutable(
'@' . $busyTime[
'end'], 
$tz);
 
  587                $busyTime[0]->format(
'Ymd\\THis\\Z') . 
'/' . $busyTime[1]->format(
'Ymd\\THis\\Z')
 
  592            if ($busyType !== 
'BUSY') {
 
  593                $prop[
'FBTYPE'] = $busyType;
 
  595            $vfreebusy->add($prop);
 
An exception for terminatinating execution or to throw for unit testing.
static parseDuration($duration, $asString=false)
Parses an iCalendar (RFC5545) formatted duration value.
static parseDateTime($dt, DateTimeZone $tz=null)
Parses an iCalendar (rfc5545) formatted datetime and returns a DateTimeImmutable object.
FreeBusyData is a helper class that manages freebusy information.
add($start, $end, $type)
Adds free or busytime to the data.
This class helps with generating FREEBUSY reports based on existing sets of objects.
setVAvailability(Document $vcalendar)
Sets a VAVAILABILITY document.
setBaseObject(Document $vcalendar)
Sets the VCALENDAR object.
generateFreeBusyCalendar(FreeBusyData $fbData)
This method takes a FreeBusyData object and generates the VCALENDAR object associated with it.
setObjects($objects)
Sets the input objects.
calculateBusy(FreeBusyData $fbData, array $objects)
This method takes an array of iCalendar objects and applies its busy times on fbData.
setTimeZone(DateTimeZone $timeZone)
Sets the reference timezone for floating times.
__construct(DateTimeInterface $start=null, DateTimeInterface $end=null, $objects=null, DateTimeZone $timeZone=null)
Creates the generator.
setTimeRange(DateTimeInterface $start=null, DateTimeInterface $end=null)
Sets the time range.
calculateAvailability(FreeBusyData $fbData, VCalendar $vavailability)
This method takes a VAVAILABILITY component and figures out all the available times.
getResult()
Parses the input data and returns a correct VFREEBUSY object, wrapped in a VCALENDAR.
static read($data, $options=0, $charset='UTF-8')
Parses a vCard or iCalendar object, and returns the top component.
This class is used to determine new for a recurring event, when the next events occur.
This exception gets thrown when a recurrence iterator produces 0 instances.
static $maxDate
The maximum date we accept for various calculations with dates, such as recurrences.
static $maxRecurrences
The maximum number of recurrences that will be generated.
static $minDate
The minimum date we accept for various calculations with dates, such as recurrences.