ソースを参照

Timeline logic updates

Vijayakrishnan 4 年 前
コミット
a77363dbca
2 ファイル変更79 行追加26 行削除
  1. 78 26
      app/Helpers/TimeLine.php
  2. 1 0
      app/Helpers/TimeSlot.php

+ 78 - 26
app/Helpers/TimeLine.php

@@ -37,13 +37,17 @@ class TimeLine {
 
     public function removeAvailability(DateTime $_start, DateTime $_end) {
 
-        $this->removeStart = $_start->getTimestamp();
-        $this->removeEnd = $_end->getTimestamp();
-
-        $this->cleanRemove();
-
-        $removeStart = null;
-        $removeSnd = null;
+        $removeStart = $_start->getTimestamp();
+        $removeEnd = $_end->getTimestamp();
+
+        $cleaned = $this->removeEmbeddedInAvailSlot($removeStart, $removeEnd);
+        if(!$cleaned) {
+            for ($i=0; $i<count($this->available); $i++) $this->available[$i]->processed = false;
+            $this->removeStart($removeStart, $removeEnd);
+            for ($i=0; $i<count($this->available); $i++) $this->available[$i]->processed = false;
+            $this->removeEnd($removeStart, $removeEnd);
+            $this->removeEmbeddedInRemoveSlot($removeStart, $removeEnd);
+        }
 
         // sort by start
         usort($this->available, function ($item1, $item2) {
@@ -53,45 +57,92 @@ class TimeLine {
         $this->vdump($this->available);
     }
 
-    private function cleanRemove() {
-
-        $allDone = true;
-
+    private function removeEmbeddedInAvailSlot($removeStart, $removeEnd) {
         for ($i=0; $i<count($this->available); $i++) {
 
             // removeStart at or after slot start
             // removeEnd at or before slot end
             // split slot into 2
-            if($this->removeStart >= $this->available[$i]->start &&
-                $this->removeEnd <= $this->available[$i]->end) {
+            if ($removeStart >= $this->available[$i]->start &&
+                $removeEnd <= $this->available[$i]->end) {
                 $newSlot = new TimeSlot(new DateTime(), new DateTime());
-                $newSlot->start = $this->removeEnd;
+                $newSlot->start = $removeEnd;
                 $newSlot->end = $this->available[$i]->end;
 
-                $this->available[$i]->end = $this->removeStart;
-                array_splice($this->available, $i+1, 0, [$newSlot]);
-                $allDone = true;
-                break;
+                $this->available[$i]->end = $removeStart;
+                array_splice($this->available, $i + 1, 0, [$newSlot]);
+                return true; // nothing more to do
             }
+        }
+
+        return false;
+    }
+
+    private function removeEmbeddedInRemoveSlot($removeStart, $removeEnd) {
+
+        $allDone = true;
+
+        for ($i=0; $i<count($this->available); $i++) {
+
+            // removeStart at or before slot start
+            // removeEnd at or after slot end
+            // remove slot
+            if ($removeStart <= $this->available[$i]->start &&
+                $removeEnd >= $this->available[$i]->end) {
+                array_splice($this->available, $i, 1);
+                $allDone = false;
+            }
+        }
+
+        if(!$allDone) {
+            $this->removeEmbeddedInRemoveSlot($removeStart, $removeEnd); // recurse till clean
+        }
+
+        return false;
+    }
+
+    private function removeStart($removeStart, $removeEnd) {
+
+        $allDone = true;
+
+        for ($i=0; $i<count($this->available); $i++) {
+
+            if($this->available[$i]->processed) continue;
 
             // removeStart at or after slot start
             // removeStart at or before slot end
             // update slot to end at removeStart
-            if($this->removeStart >= $this->available[$i]->start &&
-                $this->removeStart <= $this->available[$i]->end) {
-                $this->available[$i]->end = $this->removeStart;
+            if($removeStart >= $this->available[$i]->start &&
+                $removeStart <= $this->available[$i]->end) {
+                $this->available[$i]->end = $removeStart;
+                $this->available[$i]->processed = true;
                 $allDone = false;
                 break;
             }
 
-            // process removeEnd
+        }
+
+        if(!$allDone) {
+            $this->removeStart($removeStart, $removeEnd); // recurse till clean
+        }
+
+    }
+
+    private function removeEnd($removeStart, $removeEnd) {
+
+        $allDone = true;
+
+        for ($i=0; $i<count($this->available); $i++) {
+
+            if($this->available[$i]->processed) continue;
 
             // removeEnd at or after slot start
             // removeEnd at or before slot end
             // update slot to start at removeEnd
-            if($this->removeEnd >= $this->available[$i]->start &&
-                $this->removeEnd <= $this->available[$i]->end) {
-                $this->available[$i]->start = $this->removeEnd;
+            if($removeEnd >= $this->available[$i]->start &&
+                $removeEnd <= $this->available[$i]->end) {
+                $this->available[$i]->start = $removeEnd;
+                $this->available[$i]->processed = true;
                 $allDone = false;
                 break;
             }
@@ -99,8 +150,9 @@ class TimeLine {
         }
 
         if(!$allDone) {
-            $this->normalize(); // recurse till clean
+            $this->removeEnd($removeStart, $removeEnd); // recurse till clean
         }
+
     }
 
     private function normalize() {

+ 1 - 0
app/Helpers/TimeSlot.php

@@ -6,6 +6,7 @@ class TimeSlot {
 
     public $start = null;
     public $end = null;
+    public $processed = false;
 
     public function __construct(\DateTime $_start, \DateTime $_end)
     {