GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Issues (42)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/Event/EventItemizer.php (5 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * @file
5
 * Class EventItemizer
6
 */
7
8
namespace Roomify\Bat\Event;
9
10
use Roomify\Bat\Event\EventInterface;
11
use Roomify\Bat\Unit\Unit;
12
13
/**
14
 * The EventItemizer class does the hard work of splitting an event into discrete time
15
 * units in the following structure
16
 * [BAT_DAY][year][month][day][value]
17
 * [BAT_HOUR][year][month][day][hour][value]
18
 * [BAT_MINUTE][year][month][hour][minute][value]
19
 *
20
 * This data structure allows to quickly retrieve the state of a unit for a provided time
21
 * period. The value is either the default value of the unit or the value that the event
22
 * introduced. If the value in either BAT_DAY or BAT_HOUR is -1 it means that that specific
23
 * day or that specific hour are non-determinant. This means that in order to determine the
24
 * value of the event for that point in time we need to look at a lower level of granularity.
25
 *
26
 * Example - consider breaking up the following event
27
 *
28
 * start-date: 2016-01-01 1210
29
 * end-date: 2016-01-03 1210
30
 * value: 10
31
 *
32
 * [BAT_DAY][2016][01][d1][-1] - The first day starts at 1210 so the DAY array is not enough
33
 * [BAT_DAY][2016][01][d2][10] - The second day is a full day at the same value of 10
34
 * [BAT_DAY][2016][01][d3][-1] - The last day is no a full day so the day array in non-determinant
35
 * [BAT_HOUR][2016][01][d1][h12][-1] - The first hour of the event starts at 10 minutes so the hour is non-determinant
36
 * [BAT_HOUR][2016][01][d1][h13][10]
37
 * [BAT_HOUR][2016][01][d1][h14][10]
38
 * [BAT_HOUR][2016][01][d1][h15][10]
39
 * [BAT_HOUR][2016][01][d1][h16][10]
40
 * [BAT_HOUR][2016][01][d1][h17][10]
41
 * [BAT_HOUR][2016][01][d1][h18][10]
42
 * [BAT_HOUR][2016][01][d1][h19][10]
43
 * [BAT_HOUR][2016][01][d1][h20][10]
44
 * [BAT_HOUR][2016][01][d1][h21][10]
45
 * [BAT_HOUR][2016][01][d1][h22][10]
46
 * [BAT_HOUR][2016][01][d1][h23][10]
47
 *                                    - we don't need to state anything about hours on the 2nd of Jan since the day array is determinant
48
 * [BAT_HOUR][2016][01][d3][h01][10]
49
 * [BAT_HOUR][2016][01][d3][h02][10]
50
 * [BAT_HOUR][2016][01][d3][h03][10]
51
 * [BAT_HOUR][2016][01][d3][h04][10]
52
 * [BAT_HOUR][2016][01][d3][h05][10]
53
 * [BAT_HOUR][2016][01][d3][h06][10]
54
 * [BAT_HOUR][2016][01][d3][h07][10]
55
 * [BAT_HOUR][2016][01][d3][h08][10]
56
 * [BAT_HOUR][2016][01][d3][h09][10]
57
 * [BAT_HOUR][2016][01][d3][h10][10]
58
 * [BAT_HOUR][2016][01][d3][h11][10]
59
 * [BAT_HOUR][2016][01][d3][h12][-1] - The last hour of the event ends at the 10th minute so will need to minute array
60
 *
61
 * [BAT_MINUTE][2016][01][d1][h12][m00][10] - Minutes, which is the maximum granularity, are always determinant
62
 * [BAT_MINUTE][2016][01][d1][h12][m01][10]
63
 * [BAT_MINUTE][2016][01][d1][h12][m02][10]
64
 * [BAT_MINUTE][2016][01][d1][h12][m03][10]
65
 * [BAT_MINUTE][2016][01][d1][h12][m04][10]
66
 * [BAT_MINUTE][2016][01][d1][h12][m05][10]
67
 * [BAT_MINUTE][2016][01][d1][h12][m06][10]
68
 * [BAT_MINUTE][2016][01][d1][h12][m07][10]
69
 * [BAT_MINUTE][2016][01][d1][h12][m08][10]
70
 * [BAT_MINUTE][2016][01][d1][h12][m09][10]
71
 * [BAT_MINUTE][2016][01][d1][h12][m10][10]
72
 *
73
 * [BAT_MINUTE][2016][01][d3][h12][m00][10]
74
 * [BAT_MINUTE][2016][01][d3][h12][m01][10]
75
 * [BAT_MINUTE][2016][01][d3][h12][m02][10]
76
 * [BAT_MINUTE][2016][01][d3][h12][m03][10]
77
 * [BAT_MINUTE][2016][01][d3][h12][m04][10]
78
 * [BAT_MINUTE][2016][01][d3][h12][m05][10]
79
 * [BAT_MINUTE][2016][01][d3][h12][m06][10]
80
 * [BAT_MINUTE][2016][01][d3][h12][m07][10]
81
 * [BAT_MINUTE][2016][01][d3][h12][m08][10]
82
 * [BAT_MINUTE][2016][01][d3][h12][m09][10]
83
 * [BAT_MINUTE][2016][01][d3][h12][m10][10]
84
 *
85
 * Class EventItemizer
86
 * @package Roomify\Bat\Event
87
 */
88
class EventItemizer {
89
90
  const BAT_DAY = 'bat_day';
91
  const BAT_HOUR = 'bat_hour';
92
  const BAT_MINUTE = 'bat_minute';
93
  const BAT_HOURLY = 'bat_hourly';
94
  const BAT_DAILY = 'bat_daily';
95
96
  /**
97
   * @var \Roomify\Bat\Event\EventInterface
98
   */
99
  protected $event;
100
101
  /**
102
   * @var string
103
   */
104
  protected $granularity;
105
106
  public function __construct(EventInterface $event, $granularity = EventItemizer::BAT_HOURLY) {
107
    $this->event = $event;
108
    $this->granularity = $granularity;
109
  }
110
111
  /**
112
   * Transforms the event in a breakdown of days, hours and minutes with associated states.
113
   *
114
   * @return array
115
   */
116
  public function itemizeEvent() {
117
    // In order to itemize the event we cycle through each day of the event and determine
118
    // what should go in the DAY array to start with. While we could use P1M this created
119
    // problems with months like February (because the period is 30 days) so stepping through
120
    // each day is safer.
121
    $interval = new \DateInterval('P1D');
122
123
    // Set the end date to the last day of the month so that we are sure to get that last month unless
124
    // we are already dealing with the last day of the month
125
    if ($this->event->getEndDate()->format('d') != $this->event->getEndDate()->format('t')) {
126
      $adjusted_end_day = new \DateTime($this->event->getEndDate()->format('Y-n-t'));
127
    }
128
    // Deal with the special case of last day of month and daily granularity where the DatePeriod will not indicate one day unless the time is slightly different
129
    // We add a minute to compensate
130
    elseif (($this->event->getStartDate()->format('Y-m-d H:i') == $this->event->getEndDate()->format('Y-m-d H:i')) && $this->granularity == EventItemizer::BAT_DAILY) {
131
      $adjusted_end_day = new \DateTime($this->event->getEndDate()->add(new \DateInterval('PT1M'))->format('Y-m-d H:i'));
132
    }
133
    else {
134
      $adjusted_end_day = new \DateTime($this->event->getEndDate()->format('Y-m-d H:i'));
135
    }
136
137
    $daterange = new \DatePeriod($this->event->getStartDate(), $interval, $adjusted_end_day);
138
139
    $itemized = array();
140
141
    $old_month = $this->event->getStartDate()->format('Y-n');
142
143
    $start = TRUE;
144
145
    // Cycle through each month
146
    foreach ($daterange as $date) {
147
148
      // Check if we have
149
      if (($date->format('Y-n') != $old_month) || ($start)) {
150
151
        $year = $date->format("Y");
152
        $dayinterval = new \DateInterval('P1D');
153
154
        // Handle the first month
155
        if ($this->event->isFirstMonth($date)) {
156
          // If we are in the same month the end date is the end date of the event
157
          if ($this->event->isSameMonth()) {
158
            $dayrange = new \DatePeriod($this->event->getStartDate(), $dayinterval, new \DateTime($this->event->getEndDate()->format("Y-n-j 23:59:59")));
159
          } else { // alternatively it is the last day of the start month
160
            $dayrange = new \DatePeriod($this->event->getStartDate(), $dayinterval, $this->event->endMonthDate($this->event->getStartDate()));
161
          }
162 View Code Duplication
          foreach ($dayrange as $day) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
163
            $itemized[EventItemizer::BAT_DAY][$year][$day->format('n')]['d' . $day->format('j')] = $this->event->getValue();
164
          }
165
        }
166
167
        // Handle the last month (will be skipped if event is same month)
168
        elseif ($this->event->isLastMonth($date)) {
169
          $dayrange = new \DatePeriod(new \DateTime($date->format("Y-n-1")), $dayinterval, $this->event->getEndDate());
170 View Code Duplication
          foreach ($dayrange as $day) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
171
            $itemized[EventItemizer::BAT_DAY][$year][$day->format('n')]['d' . $day->format('j')] = $this->event->getValue();
172
          }
173
        }
174
175
        // We are in an in-between month - just cycle through and set dates (time on end date set to ensure it is included)
176
        else {
177
          $dayrange = new \DatePeriod(new \DateTime($date->format("Y-n-1")), $dayinterval, new \DateTime($date->format("Y-n-t 23:59:59")));
178 View Code Duplication
          foreach ($dayrange as $day) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
179
            $itemized[EventItemizer::BAT_DAY][$year][$day->format('n')]['d' . $day->format('j')] = $this->event->getValue();
180
          }
181
        }
182
      }
183
      $start = FALSE;
184
      $old_month = $date->format('Y-n');
185
    }
186
187
    if ($this->granularity == EventItemizer::BAT_HOURLY) {
188
      // Add granural info in
189
      $itemized = $this->createDayGranural($itemized);
190
    }
191
192
    return $itemized;
193
  }
194
195
  /**
196
   * Based on the start and end dates of the event it creates the appropriate granular events
197
   * and adds them to an array suitable for manipulating easily or storing in the database.
198
   *
199
   * @param array $itemized
200
   * @return array
201
   */
202
  private function createDayGranural($itemized = array()) {
203
    $interval = new \DateInterval('PT1M');
204
205
    $sy = $this->event->getStartDate()->format('Y');
206
    $sm = $this->event->getStartDate()->format('n');
207
    $sd = $this->event->getStartDate()->format('j');
208
209
    $ey = $this->event->getEndDate()->format('Y');
210
    $em = $this->event->getEndDate()->format('n');
211
    $ed = $this->event->getEndDate()->format('j');
212
213
    // Clone the dates otherwise changes will change the event dates themselves
214
    $start_date = clone($this->event->getStartDate());
215
    $end_date = clone($this->event->getEndDate());
216
217
    if ($this->event->isSameDay()) {
218
      if (!($this->event->getStartDate()->format('H:i') == '00:00' && $this->event->getEndDate()->format('H:i') == '23:59')) {
219
        $itemized_same_day = $this->createHourlyGranular($start_date, $end_date->add(new \DateInterval('PT1M')), $interval);
220
        $itemized[EventItemizer::BAT_DAY][$sy][$sm]['d' . $sd] = -1;
221
        $itemized[EventItemizer::BAT_HOUR][$sy][$sm]['d' . $sd] = $itemized_same_day[EventItemizer::BAT_HOUR][$sy][$sm]['d' . $sd];
222
        $itemized[EventItemizer::BAT_MINUTE][$sy][$sm]['d' . $sd] = $itemized_same_day[EventItemizer::BAT_MINUTE][$sy][$sm]['d' . $sd];
223
      }
224
    }
225
    else {
226
      // Deal with the start day unless it starts on midnight precisely at which point the whole day is booked
227 View Code Duplication
      if (!($this->event->getStartDate()->format('H:i') == '00:00')) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
228
        $itemized_start = $this->createHourlyGranular($start_date, new \DateTime($start_date->format("Y-n-j 23:59:59")), $interval);
229
        $itemized[EventItemizer::BAT_DAY][$sy][$sm]['d' . $sd] = -1;
230
        $itemized[EventItemizer::BAT_HOUR][$sy][$sm]['d' . $sd] = $itemized_start[EventItemizer::BAT_HOUR][$sy][$sm]['d' . $sd];
231
        $itemized[EventItemizer::BAT_MINUTE][$sy][$sm]['d' . $sd] = $itemized_start[EventItemizer::BAT_MINUTE][$sy][$sm]['d' . $sd];
232
      }
233
      else {
234
        // Just set an empty hour and minute
235
        $itemized[EventItemizer::BAT_HOUR][$sy][$sm]['d' . $sd] = array();
236
        $itemized[EventItemizer::BAT_MINUTE][$sy][$sm]['d' . $sd] = array();
237
      }
238
239
      // Deal with the end date unless it ends just before midnight at which point we don't need to go further
240 View Code Duplication
      if ($this->event->getEndDate()->format('H:i') == '23:59') {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
241
        $itemized[EventItemizer::BAT_HOUR][$ey][$em]['d' . $ed] = array();
242
        $itemized[EventItemizer::BAT_MINUTE][$ey][$em]['d' . $ed] = array();
243
      }
244
      else {
245
        $itemized_end = $this->createHourlyGranular(new \DateTime($end_date->format("Y-n-j 00:00:00")), $end_date->add(new \DateInterval('PT1M')), $interval);
246
        $itemized[EventItemizer::BAT_DAY][$ey][$em]['d' . $ed] = -1;
247
        $itemized[EventItemizer::BAT_HOUR][$ey][$em]['d' . $ed] = $itemized_end[EventItemizer::BAT_HOUR][$ey][$em]['d' . $ed];
248
        $itemized[EventItemizer::BAT_MINUTE][$ey][$em]['d' . $ed] = $itemized_end[EventItemizer::BAT_MINUTE][$ey][$em]['d' . $ed];
249
      }
250
    }
251
252
    return $itemized;
253
  }
254
255
  /**
256
   * Given a DatePeriod it transforms it in hours and minutes. Used to break the first and
257
   * last days of an event into more granular events.
258
   *
259
   * @param \DateTime $start_date
260
   * @param \DateTime $end_date
261
   * @param \DateInterval $interval
262
   * @return array
263
   */
264
  public function createHourlyGranular(\DateTime $start_date, \DateTime $end_date, \DateInterval $interval) {
265
    $period = new \DatePeriod($start_date, $interval, $end_date);
266
267
    $itemized = array();
268
269
    $start_minute = (int)$start_date->format('i');
270
271
    $event_value = $this->event->getValue();
272
273
    $year = $start_date->format('Y');
274
    $month = $start_date->format('n');
275
    $day = $start_date->format('j');
276
    $hour = $start_date->format('G');
277
    $min = $start_date->format('i');
278
279
    foreach ($period as $minute) {
280
      // Re-calculate if we're at a day boundary.
281
      if ($hour == 24) {
282
        $year = $minute->format('Y');
283
        $month = $minute->format('n');
284
        $day = $minute->format('j');
285
        $hour = $minute->format('G');
286
        $min = $minute->format('i');
287
      }
288
289
      // Doing minutes so set the values in the minute array
290
      $itemized[EventItemizer::BAT_MINUTE][$year][$month]['d' . $day]['h' . $hour]['m' . $min] = $event_value;
291
      // Let the hours know that it cannot determine availability
292
      $itemized[EventItemizer::BAT_HOUR][$year][$month]['d' . $day]['h' . $hour] = -1;
293
      $min++;
294
295
      if ($min == 60 && $start_minute !== 0) {
296
        // Not a real hour - leave as is and move on
297
        $min = 0;
298
        $hour++;
299
        $start_minute = 0;
300
      }
301
      elseif ($min == 60 && $start_minute == 0) {
302
        // Did a real whole hour so initialize the hour
303
        $itemized[EventItemizer::BAT_HOUR][$year][$month]['d' . $day]['h' . $hour] = $event_value;
304
305
        $min = 0;
306
        $hour++;
307
        $start_minute = 0;
308
      }
309
310
      $min = str_pad($min, 2, 0, STR_PAD_LEFT);
311
    }
312
313
    // Daylight Saving Time
314
    $timezone = new \DateTimeZone(date_default_timezone_get());
315
    $transitions = $timezone->getTransitions($start_date->getTimestamp(), $end_date->getTimestamp());
316
317
    unset($transitions[0]);
318
    foreach ($transitions as $transition) {
319
      if ($transition['isdst']) {
320
        $date = new \DateTime();
321
        $date->setTimestamp($transition['ts']);
322
323
        $hour = $date->format('G');
324
        for ($i = 0; $i < 60; $i++) {
325
          $minute = ($i < 10) ? '0' . $i : $i;
326
327
          $itemized[EventItemizer::BAT_MINUTE][$date->format('Y')][$date->format('n')]['d' . $date->format('j')]['h' . $hour]['m' . $minute] = $this->event->getValue();
328
        }
329
      }
330
    }
331
332
    return $itemized;
333
  }
334
335
}
336