Improved logic in tasks and unfinished scripts plus some bug fixes
[SonOfLokstallBot.git] / src / common.php
index 173bd32..bc627f4 100644 (file)
@@ -43,11 +43,11 @@ function canChatWith(TelegramUpdate $update) : bool {
 function partition(int $numPartitions, array $array) : array {
     $partitionSize = (int)ceil(count($array) / $numPartitions);
 
-    return array_values(filter(notEmpty)(
+    return array_values(
         map(function($p) use ($array, $partitionSize) {
             return array_slice($array, $p*$partitionSize, $partitionSize);
         })(range(0, $numPartitions-1))
-    ));
+    );
 }
 
 function getInbox(string $inbox) {
@@ -260,7 +260,7 @@ function getTasksForTheSeason($season, $taskMatrix) {
                 return array_merge(
                     $c,
                     array_reduce($v, function($c, $v) {
-                        return array_merge($c, is_array($v) ? $v : [$v]);
+                        return array_merge($c, is_array($v) ? [] : [$v]);
                     }, [])
                 );
             },
@@ -283,11 +283,11 @@ function getTasksForTheMonth($monthNum, $taskMatrix) {
     );
 }
 
-function getTasksForTheWeek(int $weekNum, int $monthNum, array $taskMatrix) {
+function getTasksForTheWeek(int $year, int $monthNum, int $weekNum, array $taskMatrix) {
     return  array_merge(
         $weekNum % 2 == 0 ? $taskMatrix['bimonthly'] : [],
         $taskMatrix['annualy'][getSeason($monthNum)][getMonthName($monthNum)]['weekly'] ?? [],
-        partition(4, getTasksForTheMonth($monthNum, $taskMatrix))[$weekNum-1]
+        partition(count(getMondaysForMonth($year, $monthNum)), getTasksForTheMonth($monthNum, $taskMatrix))[$weekNum-1]
     );
 }
 
@@ -304,10 +304,77 @@ function getFilePathForWeek(int $year, int $monthNum, int $weekNum) {
     );
 }
 
+function getMondaysForMonth(int $year, int $monthNum) {
+    $dt = DateTimeImmutable::createFromFormat('Y n', "$year $monthNum");
+    $m = $dt->format('F');
+    $y = $dt->format('Y');
+    $fifthMonday = (int)(new DateTimeImmutable("fifth monday of $m $y"))->format('d');
+    $mondays = [
+        (int)(new DateTimeImmutable("first monday of $m $y"))->format('d'),
+        (int)(new DateTimeImmutable("second monday of $m $y"))->format('d'),
+        (int)(new DateTimeImmutable("third monday of $m $y"))->format('d'),
+        (int)(new DateTimeImmutable("fourth monday of $m $y"))->format('d'),
+    ];
+
+    return array_merge(
+        $mondays,
+        $fifthMonday > $mondays[3] ? [$fifthMonday] : []
+    );
+}
+
+function getDayNumber(int $year, int $month, int $day) {
+    $potentialMondays = array_filter(
+        getMondaysForMonth($year, $month),
+        function($monday) use ($day) {
+            return $monday <= $day;
+        }
+    );
+
+    return $potentialMondays
+        ? closest($day, $potentialMondays)
+        : array_values(
+            array_slice(
+                getMondaysForMonth(
+                    getYearWeekBeginsIn($year, $month, $day),
+                    getMonthWeekBeginsIn($year, $month, $day)
+                ),
+                -1
+            )
+        )[0];
+}
+
+function getWeekNumber(int $year, int $month, int $day) {
+    $potentialMondays = array_filter(
+        getMondaysForMonth($year, $month),
+        function($monday) use ($day) {
+            return $monday <= $day;
+        }
+    );
+
+    return $potentialMondays
+        ? closestIndex($day, $potentialMondays) + 1
+        : count(
+            getMondaysForMonth(
+                getYearWeekBeginsIn($year, $month, $day),
+                getMonthWeekBeginsIn($year, $month, $day)
+            )
+        );
+}
+
+function getMonthWeekBeginsIn(int $year, int $month, int $day) {
+    return array_merge([12], range(1,11), [12])[
+        $month - ($day < getMondaysForMonth($year, $month)[0] ? 1 : 0)
+    ];
+}
+
+function getYearWeekBeginsIn(int $year, int $month, int $day) {
+    return $year - (int)($month == 1 && getMonthWeekBeginsIn($year, $month, $day) == 12);
+}
+
 function getFilePathsForMonth(int $year, int $monthNum) {
     return map(function($week) use ($year, $monthNum){
         return getFilePathForWeek($year, $monthNum, $week);
-    })(range(1,4));
+    })(range(1, count(getMondaysForMonth($year, $monthNum))));
 }
 
 function getFilePathsForSeason(int $year, string $season) {
@@ -326,7 +393,7 @@ function getFilePathsForYear(int $year) {
     })(['summer', 'winter', 'spring', 'autumn']));
 }
 
-function closestIndex($n, array $list) {
+function closestIndex(int $n, array $list) {
     $a = map(function(int $v) use ($n) : int {
             return (int)abs($v - $n);
         })
@@ -336,7 +403,7 @@ function closestIndex($n, array $list) {
     return array_keys($a)[0];
 }
 
-function closest($n, array $list) : int {
+function closest(int $n, array $list) : int {
     return $list[closestIndex($n, $list)];
 }