Skip to content

Commit c045737

Browse files
committed
[FIX] AvailabilityGrammar.php: validate Time Ranges (start time must not be greater than or equal to the end time)
1 parent 2fda9e7 commit c045737

File tree

2 files changed

+49
-23
lines changed

2 files changed

+49
-23
lines changed

php-nlgen

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit f1783dab105d4d7d94e5b4df32d939b66ad460a1

src/Grammars/Availability/AvailabilityGrammar.php

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
class AvailabilityGrammar extends Generator
3333
{
3434

35-
// coarseness
35+
// coarseness
3636
public const SUCCINCT = 0;
3737
public const BASE = 1;
3838
public const SPECIFIC = 2;
@@ -47,7 +47,32 @@ class AvailabilityGrammar extends Generator
4747
// coarseness is one of the above constant.
4848
public function generateAvailability($busyList, $ranges, $coarseness=self::BASE, $context)
4949
{
50-
return $this->generate([ 'busyList' => $busyList, 'ranges' => $ranges, 'coarseness' => $coarseness ], $context);
50+
$invalidRanges = [];
51+
foreach ($busyList as $rangeIndex => $range) {
52+
list($day, $startTime, $endTime) = $range;
53+
54+
// Convert start and end times to minutes for easier comparison
55+
$startMinutes = $startTime[0] * 60 + $startTime[1];
56+
$endMinutes = $endTime[0] * 60 + $endTime[1];
57+
58+
// Check if the start time is greater than or equal to the end time
59+
if ($startMinutes >= $endMinutes) {
60+
$invalidRanges[] = $rangeIndex;
61+
}
62+
}
63+
64+
if (!empty($invalidRanges)) {
65+
$invalidRangeIndices = "";
66+
foreach ($invalidRanges as $rangeIndex) {
67+
$rangeIndex = $rangeIndex + 1;
68+
$invalidRangeIndices .= "$rangeIndex, ";
69+
}
70+
71+
throw new Exception("Invalid time range found in range(s): $invalidRangeIndices");
72+
}
73+
else {
74+
return $this->generate([ 'busyList' => $busyList, 'ranges' => $ranges, 'coarseness' => $coarseness ], $context);
75+
}
5176
}
5277

5378
function top($data)
@@ -59,7 +84,7 @@ function top($data)
5984
$this->context['coarseness'] = $coarseness;
6085

6186
$busyList = $this->cleanBusyList($busyList, $ranges);
62-
87+
6388
$table = $this->buildTable($busyList, $ranges);
6489
//print_r($table);
6590
$textSems = [];
@@ -76,7 +101,7 @@ function top($data)
76101
$focused = $l[0];
77102
$thisText = $this->focusedMessage($focused, false);
78103
$textSems[] = [ $focused->dows, $thisText, $focused->semantics() ];
79-
104+
80105
$table = $this->removeFocused($focused, $table);
81106
$extra = [];
82107
foreach($focused->dows as $dow) {
@@ -95,7 +120,7 @@ function top($data)
95120
}
96121
}
97122
if($found){
98-
unset($ranges[$dow]);
123+
unset($ranges[$dow]);
99124
unset($table[$dow]);
100125
}
101126
}
@@ -169,7 +194,7 @@ function top($data)
169194
}else{
170195
if($ranges[$dow][0][0] <= 12) {
171196
if($ranges[$dow][1][0] <= 12) {
172-
unset($ranges[$dow]); // drop
197+
unset($ranges[$dow]); // drop
173198
unset($table[$dow]);
174199
}else{
175200
$ranges[$dow][0] = [ 12, 0 ]; // chop
@@ -226,7 +251,7 @@ function top($data)
226251
$sem=[];
227252
foreach($fullRanges as $dow=>$x){
228253
$found = null;
229-
254+
230255
foreach($textSems as $idx=>$e){
231256
[ $dows, $thisText, $sems ] = $e;
232257
foreach($dows as $odow){
@@ -279,8 +304,8 @@ protected function focusedMessage($focused, $inSegment)
279304
$this->blocks($focused->blocks, true, false)
280305
);
281306
break;
282-
283-
case FocusedSegmentMessage::DAYS:
307+
308+
case FocusedSegmentMessage::DAYS:
284309
$this->addWS(
285310
$text,
286311
$this->dows($focused->dows),
@@ -369,7 +394,7 @@ protected function blocks($blocks, $isSegment, $inSegment)
369394

370395
protected function purity($purity)
371396
{
372-
$purityStr = "{".sprintf("%1.2f",$purity)."}";
397+
$purityStr = "{".sprintf("%1.2f",$purity)."}";
373398
if($purity > 0.99){
374399
return [ 'text'=>"", 'sem'=> [ 'level' => 'full', 'value'=>$purity ] ];
375400
}elseif($purity > 0.95){
@@ -400,7 +425,7 @@ protected function block($block, $prevPurity, $prevBusy)
400425
);
401426
return [ 'text'=>$text, 'sem' => [ 'block' => $block->semantics() ] ];
402427
}
403-
428+
404429
protected function dows($dows)
405430
{
406431
sort($dows);
@@ -492,13 +517,13 @@ function cleanBusyList($busyList, $ranges) : array
492517
}
493518
if($end[0] < $start[0] or // looped, set to end
494519
$end[0] > $ranges[$dow][1][0] or
495-
($end[0] == $ranges[$dow][1][0] and $end[1] > $ranges[$dow][1][1])) {
520+
($end[0] == $ranges[$dow][1][0] and $end[1] > $ranges[$dow][1][1])) {
496521
$end = $ranges[$dow][1];
497522
}
498523
if($start[0] < $ranges[$dow][0][0]){
499524
$start = $ranges[$dow][0];
500525
}
501-
526+
502527
$perDay[$dow][] = [ $dow, $start, $end ];
503528
}
504529
$result = [];
@@ -512,9 +537,9 @@ function cleanBusyList($busyList, $ranges) : array
512537
while($j < count($dayBusyList)) {
513538
$otherS = $dayBusyList[$j][1];
514539
$otherE = $dayBusyList[$j][2];
515-
540+
516541
if(overlaps($currentS, $currentE, $otherS, $otherE)) {
517-
[ $currentS, $currentE ] = [ minTime( $currentS, $otherS ), maxTime( $currentE, $otherE ) ];
542+
[ $currentS, $currentE ] = [ minTime( $currentS, $otherS ), maxTime( $currentE, $otherE ) ];
518543
$dayBusyList[$i] = [ $dow, $currentS, $currentE ];
519544
$l = count($dayBusyList) - 1;
520545
$dayBusyList[$j] = $dayBusyList[$l];
@@ -528,7 +553,7 @@ function cleanBusyList($busyList, $ranges) : array
528553
$i++;
529554
}
530555
}
531-
array_push($result, ...$dayBusyList);
556+
array_push($result, ...$dayBusyList);
532557
}
533558
return $result;
534559
}
@@ -592,7 +617,7 @@ function analyzeDays($table, $ranges, $coarseness, $isFree)
592617
$groupFocused = array_shift($distilled);
593618
//echo "pop ".$this->dows($groupFocused->dows)."\n";
594619
$cluster = [ $groupFocused ];
595-
620+
596621
foreach($distilled as $focused){
597622
//echo "Comparing with " . $this->dows($focused->dows)."\n";
598623
[ $compatible, $newGroupFocused ] = $this->compatible($groupFocused, $focused, $cluster, $coarseness);
@@ -628,7 +653,7 @@ function analyzeWeek($table, $ranges, $coarseness, $isFree)
628653
$allWeek[] = $dow;
629654
}
630655
}
631-
656+
632657
$allWeekCompat = true;
633658
$groupFocused = null;
634659
$cluster = [ ];
@@ -709,7 +734,7 @@ function analyzeSegments($table, $ranges, $coarseness, $isFree)
709734
}
710735
}
711736
}
712-
737+
713738
$distilled[$dow] = $this->distillDay($dow, [ $start, 0 ], [ $end, 0 ], $truncatedEntries, $coarseness, $isFree);
714739
if(! $distilled[$dow]->blocks){
715740
$allCompat = false;
@@ -722,7 +747,7 @@ function analyzeSegments($table, $ranges, $coarseness, $isFree)
722747
// check all distilled are compatible
723748
$groupFocused = array_shift($distilled);
724749
$cluster = [ $groupFocused ];
725-
750+
726751
foreach($distilled as $focused){
727752
//echo "Comparing with " . $this->dows($focused->dows)."\n";
728753
[ $compatible, $newGroupFocused ] = $this->compatible($groupFocused, $focused, $cluster, $coarseness);
@@ -808,7 +833,7 @@ function compatible(FocusedSegmentMessage $current, FocusedSegmentMessage $other
808833
// build new message
809834
$newBlocks = [];
810835
$allOtherBlocksAsSet = $this->blocksToSet($other->blocks);
811-
836+
812837
foreach($current->blocks as $block) {
813838
// adjust purity based on $other blocks
814839
$thisBlockAsSet = $this->blocksToSet([ $block ]);
@@ -818,7 +843,7 @@ function compatible(FocusedSegmentMessage $current, FocusedSegmentMessage $other
818843
$newPurity = min($purity, $block->purity);
819844
$newBlocks[] = new MeetingBlockMessage($block->startTime, $block->endTime, array_merge($block->dows, [ $other->dows[0] ]),
820845
$block->isFree, $newPurity, $block->fullRange);
821-
}
846+
}
822847
return [ true, new FocusedSegmentMessage($current->focus,
823848
$current->startTime, $current->endTime, array_merge($current->dows, $other->dows),
824849
$current->fullRange, $newBlocks) ];
@@ -874,7 +899,7 @@ function removeFocused(FocusedSegmentMessage $focused, array $table) : array
874899
$block = new MeetingBlockMessage($focused->startTime, $focused->endTime, $focused->dows, false, 1.0, $focused->fullRange);
875900

876901
//echo "Removing: " . strval($block)."\n"; echo "Before:\n".tableToString($table);
877-
902+
878903
foreach($focused->dows as $dow) {
879904
$current = $table[$dow];
880905
$new = [];

0 commit comments

Comments
 (0)