aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/sabre/vobject/lib/FreeBusyData.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sabre/vobject/lib/FreeBusyData.php')
-rw-r--r--vendor/sabre/vobject/lib/FreeBusyData.php193
1 files changed, 193 insertions, 0 deletions
diff --git a/vendor/sabre/vobject/lib/FreeBusyData.php b/vendor/sabre/vobject/lib/FreeBusyData.php
new file mode 100644
index 000000000..0a6c72bb2
--- /dev/null
+++ b/vendor/sabre/vobject/lib/FreeBusyData.php
@@ -0,0 +1,193 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * FreeBusyData is a helper class that manages freebusy information.
+ *
+ * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
+ * @author Evert Pot (http://evertpot.com/)
+ * @license http://sabre.io/license/ Modified BSD License
+ */
+class FreeBusyData {
+
+ /**
+ * Start timestamp
+ *
+ * @var int
+ */
+ protected $start;
+
+ /**
+ * End timestamp
+ *
+ * @var int
+ */
+ protected $end;
+
+ /**
+ * A list of free-busy times.
+ *
+ * @var array
+ */
+ protected $data;
+
+ function __construct($start, $end) {
+
+ $this->start = $start;
+ $this->end = $end;
+ $this->data = [];
+
+ $this->data[] = [
+ 'start' => $this->start,
+ 'end' => $this->end,
+ 'type' => 'FREE',
+ ];
+
+ }
+
+ /**
+ * Adds free or busytime to the data.
+ *
+ * @param int $start
+ * @param int $end
+ * @param string $type FREE, BUSY, BUSY-UNAVAILABLE or BUSY-TENTATIVE
+ * @return void
+ */
+ function add($start, $end, $type) {
+
+ if ($start > $this->end || $end < $this->start) {
+
+ // This new data is outside our timerange.
+ return;
+
+ }
+
+ if ($start < $this->start) {
+ // The item starts before our requested time range
+ $start = $this->start;
+ }
+ if ($end > $this->end) {
+ // The item ends after our requested time range
+ $end = $this->end;
+ }
+
+ // Finding out where we need to insert the new item.
+ $currentIndex = 0;
+ while ($start > $this->data[$currentIndex]['end']) {
+ $currentIndex++;
+ }
+
+ // The standard insertion point will be one _after_ the first
+ // overlapping item.
+ $insertStartIndex = $currentIndex + 1;
+
+ $newItem = [
+ 'start' => $start,
+ 'end' => $end,
+ 'type' => $type,
+ ];
+
+ $preceedingItem = $this->data[$insertStartIndex - 1];
+ if ($this->data[$insertStartIndex - 1]['start'] === $start) {
+ // The old item starts at the exact same point as the new item.
+ $insertStartIndex--;
+ }
+
+ // Now we know where to insert the item, we need to know where it
+ // starts overlapping with items on the tail end. We need to start
+ // looking one item before the insertStartIndex, because it's possible
+ // that the new item 'sits inside' the previous old item.
+ if ($insertStartIndex > 0) {
+ $currentIndex = $insertStartIndex - 1;
+ } else {
+ $currentIndex = 0;
+ }
+
+ while ($end > $this->data[$currentIndex]['end']) {
+
+ $currentIndex++;
+
+ }
+
+ // What we are about to insert into the array
+ $newItems = [
+ $newItem
+ ];
+
+ // This is the amount of items that are completely overwritten by the
+ // new item.
+ $itemsToDelete = $currentIndex - $insertStartIndex;
+ if ($this->data[$currentIndex]['end'] <= $end) $itemsToDelete++;
+
+ // If itemsToDelete was -1, it means that the newly inserted item is
+ // actually sitting inside an existing one. This means we need to split
+ // the item at the current position in two and insert the new item in
+ // between.
+ if ($itemsToDelete === -1) {
+ $itemsToDelete = 0;
+ if ($newItem['end'] < $preceedingItem['end']) {
+ $newItems[] = [
+ 'start' => $newItem['end'] + 1,
+ 'end' => $preceedingItem['end'],
+ 'type' => $preceedingItem['type']
+ ];
+ }
+ }
+
+ array_splice(
+ $this->data,
+ $insertStartIndex,
+ $itemsToDelete,
+ $newItems
+ );
+
+ $doMerge = false;
+ $mergeOffset = $insertStartIndex;
+ $mergeItem = $newItem;
+ $mergeDelete = 1;
+
+ if (isset($this->data[$insertStartIndex - 1])) {
+ // Updating the start time of the previous item.
+ $this->data[$insertStartIndex - 1]['end'] = $start;
+
+ // If the previous and the current are of the same type, we can
+ // merge them into one item.
+ if ($this->data[$insertStartIndex - 1]['type'] === $this->data[$insertStartIndex]['type']) {
+ $doMerge = true;
+ $mergeOffset--;
+ $mergeDelete++;
+ $mergeItem['start'] = $this->data[$insertStartIndex - 1]['start'];
+ }
+ }
+ if (isset($this->data[$insertStartIndex + 1])) {
+ // Updating the start time of the next item.
+ $this->data[$insertStartIndex + 1]['start'] = $end;
+
+ // If the next and the current are of the same type, we can
+ // merge them into one item.
+ if ($this->data[$insertStartIndex + 1]['type'] === $this->data[$insertStartIndex]['type']) {
+ $doMerge = true;
+ $mergeDelete++;
+ $mergeItem['end'] = $this->data[$insertStartIndex + 1]['end'];
+ }
+
+ }
+ if ($doMerge) {
+ array_splice(
+ $this->data,
+ $mergeOffset,
+ $mergeDelete,
+ [$mergeItem]
+ );
+ }
+
+ }
+
+ function getData() {
+
+ return $this->data;
+
+ }
+
+}