TimeScheduler   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 16
c 1
b 1
f 0
lcom 1
cbo 2
dl 0
loc 120
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A setScheduleTimeSlots() 0 5 1
A setLastTimeslot() 0 4 1
B getNextTimeSlot() 0 37 6
C validateSlots() 0 34 7
1
<?php
2
namespace TimeScheduler\Classes;
3
4
use TimeScheduler\Exceptions\BadTimeslotException;
5
use TimeScheduler\Interfaces\TimeScheduleInterface;
6
use TimeScheduler\Exceptions\NoTimeslotsException;
7
8
class TimeScheduler implements TimeScheduleInterface
9
{
10
11
    private $timeslots = [];
12
    private $lastTimeslot = null;
13
14
    function __construct()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
15
    {
16
        $this->lastTimeslot = time();
17
    }
18
19
    /**
20
     * Set configuration data of time slots
21
     * Accepts array where keys are weekdays in format date("D")
22
     * If the key is missed - this day will not have publications
23
     *
24
     * @param $slots
25
     * @return mixed
26
     */
27
    public function setScheduleTimeSlots(array $slots)
28
    {
29
        $this->validateSlots($slots);
30
        $this->timeslots = $slots;
31
    }
32
33
    /**
34
     * Set last timeslot to start with
35
     * Otherwise should start from now()
36
     *
37
     * @param $unixtimestamp
38
     * @return mixed
39
     */
40
    public function setLastTimeslot($unixtimestamp)
41
    {
42
        $this->lastTimeslot = $unixtimestamp;
43
    }
44
45
    /**
46
     * Return next timeslot for publication in unixtimestamp
47
     *
48
     * @return int
49
     */
50
    public function getNextTimeSlot()
51
    {
52
        if (!count($this->timeslots)) {
53
            throw new NoTimeslotsException();
54
        }
55
56
        $timeslots_unix = [];
57
58
        // transform given timeslots to UNIX timestamps in the nearest future
59
        foreach ($this->timeslots as $weekday => $day_timeslots) {
60
61
            // modifier for use in "strtotime"
62
            $weekday_time_modifier = (date("D", $this->lastTimeslot) == $weekday) ? "today" : "next " . $weekday;
63
64
            // for each timeslot on this day turn it to the UNIX timestamp (relative to last timeslot)
65
            foreach ($day_timeslots as $slot) {
66
                // get slot unix timestamp (relative to lastTimeslot)
67
                $slot_ux = strtotime($weekday_time_modifier . " " . $slot, $this->lastTimeslot);
68
69
                // skip slots that are in the past
70
                if ($slot_ux > $this->lastTimeslot) {
71
                    $timeslots_unix[] = $slot_ux;
72
                }
73
            }
74
75
        }
76
77
        // sort resulting unix timeslots by nearest to current time
78
        sort($timeslots_unix, SORT_NUMERIC);
79
80
        // save as lastTimestamp
81
        $this->lastTimeslot = $timeslots_unix[0];
82
83
        // and return
84
        return $this->lastTimeslot;
85
86
    }
87
88
    /**
89
     * Validate that given timeslots is given
90
     */
91
    private function validateSlots($slots)
92
    {
93
94
        // this variable will be untouched if no good timestamp found in timeslots
95
        $found_good_timeslot = false;
96
        $good_keys = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
97
98
99
        foreach ($slots as $week_day => $timestamps) {
100
101
            if (!in_array($week_day, $good_keys)) {
102
                throw new BadTimeslotException("Weekday expected as date('D') return but found: " . $week_day);
103
            }
104
105
            // timestamp MUST be as array
106
            if (!is_array($timestamps)) {
107
                throw new BadTimeslotException("Array expected, but found: " . $timestamps);
108
            }
109
110
            foreach ($timestamps as $timestamp) {
111
                // make sure timeslot has good time value like "22:50" and not "25:60".
112
                if (!preg_match("#^([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$#", $timestamp)) {
113
                    throw new BadTimeslotException("Timestamp on " . $week_day . " has bad value: " . $timestamp);
114
                } else {
115
                    $found_good_timeslot = true;
116
                }
117
            }
118
        }
119
120
        if (!$found_good_timeslot) {
121
            throw new NoTimeslotsException();
122
        }
123
124
    }
125
126
127
}