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.
Completed
Push — master ( d1dd9b...46f6a0 )
by Ronald
03:34
created

AbstractEvent::itemizeEvent()   C

Complexity

Conditions 11
Paths 12

Size

Total Lines 66
Code Lines 31

Duplication

Lines 9
Ratio 13.64 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
c 4
b 0
f 0
dl 9
loc 66
rs 5.9447
cc 11
eloc 31
nc 12
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @file
5
 * Class AbstractEvent
6
 */
7
8
namespace Roomify\Bat\Event;
9
10
use Roomify\Bat\Event\EventInterface;
11
use Roomify\Bat\Store\Store;
12
13
abstract class AbstractEvent implements EventInterface {
14
15
  const BAT_DAY = 'bat_day';
16
  const BAT_HOUR = 'bat_hour';
17
  const BAT_MINUTE = 'bat_minute';
18
  const BAT_HOURLY = 'bat_hourly';
19
  const BAT_DAILY = 'bat_daily';
20
21
  /**
22
   * The booking unit the event is relevant to
23
   * @var int
24
   */
25
  protected $unit_id;
26
27
  /**
28
   * The unit the event is relevant to
29
   */
30
  protected $unit;
31
32
  /**
33
   * The start date for the event.
34
   *
35
   * @var \DateTime
36
   */
37
  protected $start_date;
38
39
  /**
40
   * The end date for the event.
41
   *
42
   * @var \DateTime
43
   */
44
  protected $end_date;
45
46
  /**
47
   * The value associated with this event.
48
   * This can represent an availability state or a pricing value
49
   *
50
   * @var int
51
   */
52
  protected $value;
53
54
  /**
55
   * Returns the value.
56
   *
57
   * @return int
58
   */
59
  public function getValue() {
60
    return $this->value;
61
  }
62
63
  /**
64
   * Set the value.
65
   *
66
   * @param int $value
67
   */
68
  public function setValue($value) {
69
    $this->value = $value;
70
  }
71
72
  /**
73
   * Returns the unit id.
74
   *
75
   * @return int
76
   */
77
  public function getUnitId() {
78
    return $this->unit_id;
79
  }
80
81
  /**
82
   * Set the unit id.
83
   *
84
   * @param int $unit_id
85
   */
86
  public function setUnitId($unit_id) {
87
    $this->unit_id = $unit_id;
88
  }
89
90
  /**
91
   * Returns the start date.
92
   *
93
   * @return DateTime
94
   */
95
  public function getStartDate() {
96
    return clone($this->start_date);
97
  }
98
99
  /**
100
   * Utility function to always give us a standard format for viewing the start date.
101
   * @return mixed
102
   */
103
  public function startDateToString($format = 'Y-m-d H:i') {
104
    return $this->start_date->format($format);
105
  }
106
107
  /**
108
   * Set the start date.
109
   *
110
   * @param DateTime $start_date
111
   */
112
  public function setStartDate(\DateTime $start_date) {
113
    $this->start_date = clone($start_date);
114
  }
115
116
  /**
117
   * Returns the end date.
118
   *
119
   * @return DateTime
120
   */
121
  public function getEndDate() {
122
    return clone($this->end_date);
123
  }
124
125
  /**
126
   * Utility function to always give us a standard format for viewing the end date.
127
   * @return mixed
128
   */
129
  public function endDateToString($format = 'Y-m-d H:i') {
130
    return $this->end_date->format($format);
131
  }
132
133
  /**
134
   * Set the end date.
135
   *
136
   * @param DateTime $end_date
137
   */
138
  public function setEndDate(\DateTime $end_date) {
139
    $this->end_date = clone($end_date);
140
  }
141
142
  /**
143
   * {@inheritdoc}
144
   */
145
  public function startDay($format = 'j') {
146
    return $this->start_date->format($format);
147
  }
148
149
  /**
150
   * {@inheritdoc}
151
   */
152
  public function endDay($format = 'j') {
153
    return $this->end_date->format($format);
154
  }
155
156
  /**
157
   * {@inheritdoc}
158
   */
159
  public function startMonth($format = 'n') {
160
    return $this->start_date->format($format);
161
  }
162
163
  /**
164
   * {@inheritdoc}
165
   */
166
  public function endMonth($format = 'n') {
167
    return $this->end_date->format($format);
168
  }
169
170
  /**
171
   *{@inheritdoc)
172
   */
173
  public function endMonthDate(\DateTime $date) {
174
    // The time is added so that the end date is included
175
    $date_format = $date->format('Y-n-t 23:59:59');
176
    return new \DateTime($date_format);
177
  }
178
179
  /**
180
   * {@inheritdoc}
181
   */
182
  public function startYear($format = 'Y') {
183
    return $this->start_date->format($format);
184
  }
185
186
  /**
187
   * {@inheritdoc}
188
   */
189
  public function endYear($format = 'Y') {
190
    return $this->end_date->format($format);
191
  }
192
193
  /**
194
   * {@inheritdoc}
195
   */
196
  public function startWeek($format = 'W') {
197
    return $this->start_date->format($format);
198
  }
199
200
  /**
201
   * {@inheritdoc}
202
   */
203
  public function endWeek($format = 'W') {
204
    return $this->end_date->format($format);
205
  }
206
207
  /**
208
   * {@inheritdoc}
209
   */
210
  public function startHour($format = 'G') {
211
    return $this->start_date->format($format);
212
  }
213
214
  /**
215
   * {@inheritdoc}
216
   */
217
  public function endHour($format = 'G') {
218
    return $this->end_date->format($format);
219
  }
220
221
  /**
222
   * {@inheritdoc}
223
   */
224
  public function startMinute($format = 'i') {
225
    return $this->start_date->format($format);
226
  }
227
228
  /**
229
   * {@inheritdoc}
230
   */
231
  public function endMinute($format = 'i') {
232
    return $this->end_date->format($format);
233
  }
234
235
  /**
236
   * {@inheritdoc}
237
   */
238
  public function isFirstMonth($date) {
239
    if ($date->format("n") == $this->startMonth() && $date->format("Y") == $this->startYear()) {
240
      return TRUE;
241
    }
242
243
    return FALSE;
244
  }
245
246
  /**
247
   * {@inheritdoc}
248
   */
249
  public function isLastMonth($date) {
250
    if ($date->format("n") == $this->endMonth() && $date->format("Y") == $this->endYear()) {
251
      return TRUE;
252
    }
253
254
    return FALSE;
255
  }
256
257
  /**
258
   * {@inheritdoc}
259
   */
260
  public function isFirstDay($date) {
261
    if (($date->format('j') == $this->startDay()) && ($this->isFirstMonth($date))) {
262
      return TRUE;
263
    }
264
265
    return FALSE;
266
  }
267
268
  /**
269
   * {@inheritdoc}
270
   */
271
  public function isFirstHour($date) {
272
    if ($date->format('G') == $this->startHour() && $this->isFirstDay($date)) {
273
      return TRUE;
274
    }
275
276
    return FALSE;
277
  }
278
279
  /**
280
   * {@inheritdoc}
281
   */
282
  public function isSameYear() {
283
    if ($this->startYear() == $this->endYear()) {
284
      return TRUE;
285
    }
286
287
    return FALSE;
288
  }
289
290
  /**
291
   * {@inheritdoc}
292
   */
293
  public function isSameMonth() {
294
    if (($this->startMonth() == $this->endMonth()) && $this->isSameYear()) {
295
      return TRUE;
296
    }
297
298
    return FALSE;
299
  }
300
301
  /**
302
   * {@inheritdoc}
303
   */
304
  public function isSameDay() {
305
    if (($this->startDay() == $this->endDay()) && $this->isSameMonth()) {
306
      return TRUE;
307
    }
308
309
    return FALSE;
310
  }
311
312
  /**
313
   * {@inheritdoc}
314
   */
315
  public function isSameHour() {
316
    if (($this->startHour() == $this->endHour()) && $this->isSameDay()) {
317
      return TRUE;
318
    }
319
320
    return FALSE;
321
  }
322
323
  /**
324
   * {@inheritdoc}
325
   */
326
  public function diff() {
327
    $interval = $this->start_date->diff($this->end_date);
328
    return $interval;
329
  }
330
331
  /**
332
   * Returns true if the event overlaps at all with the time period within
333
   * the start and end time.
334
   *
335
   * @param \DateTime $start
336
   * @param \DateTime $end
337
   * @return bool
338
   */
339
  public function overlaps(\DateTime $start, \DateTime $end) {
340
    $overlaps = FALSE;
341
342
    if ($this->dateIsEarlier($start) &&
343
      ($this->dateIsInRange($end) || $this->dateIsLater($end))) {
344
      $overlaps = TRUE;
345
    }
346
    elseif ($this->dateIsInRange($start) &&
347
      ($this->dateIsInRange($end) || $this->dateIsLater($end))) {
348
      $overlaps = TRUE;
349
    }
350
351
    return $overlaps;
352
  }
353
354
  /**
355
   * Checks if date supplied is in range of event
356
   *
357
   * @param \DateTime $date
358
   * @return bool
359
   */
360
  public function dateIsInRange(\DateTime $date) {
361
    $dateInRange = FALSE;
362
363
    $t1 = $this->start_date->getTimeStamp();
364
    $t2 = $this->end_date->getTimeStamp();
365
366
    $t3 = $date->getTimeStamp();
367
368
    if (($t3 >= $t1) && ($t3 <= $t2)) {
369
      $dateInRange = TRUE;
370
    }
371
372
    return $dateInRange;
373
  }
374
375
  /**
376
   * Checks if the date supplied starts earlier than our event
377
   * @param \DateTime $date
378
   * @return bool
379
   */
380 View Code Duplication
  public function dateIsEarlier(\DateTime $date) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
381
    $dateEarlier = FALSE;
382
383
    $t1 = $this->start_date->getTimeStamp();
384
385
    $t3 = $date->getTimeStamp();
386
387
    if ($t3 < $t1) {
388
      $dateEarlier = TRUE;
389
    }
390
391
    return $dateEarlier;
392
  }
393
394
  /**
395
   * Checks if the date supplied ends after our event ends
396
   * @param \DateTime $date
397
   * @return bool
398
   */
399 View Code Duplication
  public function dateIsLater(\DateTime $date) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
400
    $dateLater = FALSE;
401
402
    $t2 = $this->end_date->getTimeStamp();
403
404
    $t4 = $date->getTimestamp();
405
406
    if ($t2 < $t4) {
407
      $dateLater = TRUE;
408
    }
409
410
    return $dateLater;
411
  }
412
413
  /**
414
   * Checks if our event ends after the date supplied
415
   * @param \DateTime $date
416
   * @return bool
417
   */
418 View Code Duplication
  public function endsLater(\DateTime $date) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
419
    $later = FALSE;
420
421
    $t2 = $this->end_date->getTimeStamp();
422
423
    $t4 = $date->getTimestamp();
424
425
    if ($t2 > $t4) {
426
      $later = TRUE;
427
    }
428
429
    return $later;
430
  }
431
432
  /**
433
   * Checks if our event starts earlier than the date supplied
434
   * @param \DateTime $date
435
   * @return bool
436
   */
437 View Code Duplication
  public function startsEarlier(\DateTime $date) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
438
    $earlier = FALSE;
439
440
    $t1 = $this->start_date->getTimeStamp();
441
442
    $t3 = $date->getTimestamp();
443
444
    if ($t1 < $t3) {
445
      $earlier = TRUE;
446
    }
447
448
    return $earlier;
449
  }
450
451
  /**
452
   * Based on the start and end dates of the event it creates the appropriate granular events
453
   * and adds them to an array suitable for manipulating easily or storing in the database.
454
   *
455
   * @param array $itemized
456
   * @return array
457
   */
458
  public function createDayGranural($itemized = array()) {
459
    $interval = new \DateInterval('PT1M');
460
461
    $sy = $this->start_date->format('Y');
462
    $sm = $this->start_date->format('n');
463
    $sd = $this->start_date->format('j');
464
465
    $ey = $this->end_date->format('Y');
466
    $em = $this->end_date->format('n');
467
    $ed = $this->end_date->format('j');
468
469
    // Clone the dates otherwise changes will change the event itself
470
    $start_date = clone($this->start_date);
471
    $end_date = clone($this->end_date);
472
473
    if ($this->isSameDay()) {
474
      if (!($this->end_date->format('H:i') == '23:59')) {
475
        $period = new \DatePeriod($start_date, $interval, $end_date->add(new \DateInterval('PT1M')));
476
        $itemized_same_day = $this->createHourlyGranular($period, $start_date);
477
        $itemized[AbstractEvent::BAT_DAY][$sy][$sm]['d' . $sd] = -1;
478
        $itemized[AbstractEvent::BAT_HOUR][$sy][$sm]['d' . $sd] = $itemized_same_day[AbstractEvent::BAT_HOUR][$sy][$sm]['d' . $sd];
479
        $itemized[AbstractEvent::BAT_MINUTE][$sy][$sm]['d' . $sd] = $itemized_same_day[AbstractEvent::BAT_MINUTE][$sy][$sm]['d' . $sd];
480
      }
481
    }
482
    else {
483
      // Deal with the start day unless it starts on midnight precisely at which point the whole day is booked
484
      if (!($this->start_date->format('H:i') == '00:00')) {
485
        $start_period = new \DatePeriod($start_date, $interval, new \DateTime($start_date->format("Y-n-j 23:59:59")));
486
        $itemized_start = $this->createHourlyGranular($start_period, $start_date);
487
        $itemized[AbstractEvent::BAT_DAY][$sy][$sm]['d' . $sd] = -1;
488
        $itemized[AbstractEvent::BAT_HOUR][$sy][$sm]['d' . $sd] = $itemized_start[AbstractEvent::BAT_HOUR][$sy][$sm]['d' . $sd];
489
        $itemized[AbstractEvent::BAT_MINUTE][$sy][$sm]['d' . $sd] = $itemized_start[AbstractEvent::BAT_MINUTE][$sy][$sm]['d' . $sd];
490
      }
491
      else {
492
        // Just set an empty hour and minute
493
        $itemized[AbstractEvent::BAT_HOUR][$sy][$sm]['d' . $sd] = array();
494
        $itemized[AbstractEvent::BAT_MINUTE][$sy][$sm]['d' . $sd] = array();
495
      }
496
497
      // Deal with the end date unless it ends just before midnight at which point we don't need to go further
498
      if ($this->end_date->format('H:i') == '23:59' ) {
499
        $itemized[AbstractEvent::BAT_HOUR][$ey][$em]['d' . $ed] = array();
500
        $itemized[AbstractEvent::BAT_MINUTE][$ey][$em]['d' . $ed] = array();
501
      } else {
502
        $end_period = new \DatePeriod(new \DateTime($end_date->format("Y-n-j 00:00:00")), $interval, $end_date->add(new \DateInterval('PT1M')));
503
        $itemized_end = $this->createHourlyGranular($end_period, new \DateTime($end_date->format("Y-n-j 00:00:00")));
504
        $itemized[AbstractEvent::BAT_DAY][$ey][$em]['d' . $ed] = -1;
505
        $itemized[AbstractEvent::BAT_HOUR][$ey][$em]['d' . $ed] = $itemized_end[AbstractEvent::BAT_HOUR][$ey][$em]['d' . $ed];
506
        $itemized[AbstractEvent::BAT_MINUTE][$ey][$em]['d' . $ed] = $itemized_end[AbstractEvent::BAT_MINUTE][$ey][$em]['d' . $ed];
507
      }
508
    }
509
510
    return $itemized;
511
  }
512
513
  /**
514
   * Given a DatePeriod it transforms it in hours and minutes. Used to break the first and
515
   * last days of an event into more granular events.
516
   *
517
   * @param \DatePeriod $period
518
   * @return array
519
   */
520
  public function createHourlyGranular(\DatePeriod $period, \DateTime $period_start) {
521
    $itemized = array();
522
523
    $counter = (int)$period_start->format('i');
524
    $start_minute = $counter;
525
    foreach($period as $minute) {
526
      // Doing minutes so set the values in the minute array
527
      $itemized[AbstractEvent::BAT_MINUTE][$minute->format('Y')][$minute->format('n')]['d'. $minute->format('j')]['h'. $minute->format('G')]['m' .$minute->format('i')] = $this->getValue();
528
      // Let the hours know that it cannot determine availability
529
      $itemized[AbstractEvent::BAT_HOUR][$minute->format('Y')][$minute->format('n')]['d'. $minute->format('j')]['h'. $minute->format('G')] = -1;
530
      $counter++;
531
532
      if ($counter == 60 && $start_minute!==0) {
533
        // Not a real hour - leave as is and move on
534
        $counter = 0;
535
        $start_minute = 0;
536
      }
537
      elseif ($counter == 60 && $start_minute == 0) {
538
        // Did a real whole hour so initialize the hour
539
        $itemized[AbstractEvent::BAT_HOUR][$minute->format('Y')][$minute->format('n')]['d' . $minute->format('j')]['h' . $minute->format('G')] = $this->getValue();
540
        // We have a whole hour so get rid of the minute info
541
        unset($itemized[AbstractEvent::BAT_MINUTE][$minute->format('Y')][$minute->format('n')]['d'. $minute->format('j')]['h'. $minute->format('G')]);
542
        $counter = 0;
543
        $start_minute = 0;
544
      }
545
    }
546
547
    return $itemized;
548
  }
549
550
  /**
551
   * Transforms the event in a breakdown of days, hours and minutes with associated states.
552
   *
553
   * @return array
554
   */
555
  public function itemizeEvent($granularity = AbstractEvent::BAT_HOURLY) {
556
    // Set the interval to day - we are going to have to cycle through each single day and
557
    // check if month changes or not since month lengths can vary (30,31,28,29)
558
    $interval = new \DateInterval('P1D');
559
560
    // Set the end date to the last day of the month so that we are sure to get that last month
561
    $adjusted_end_day = new \DateTime($this->end_date->format('Y-n-t'));
562
563
    $daterange = new \DatePeriod($this->start_date, $interval ,$adjusted_end_day);
564
565
    $itemized = array();
566
567
    $old_month = $this->start_date->format('Y-n');
568
569
    $start = TRUE;
570
571
    // Cycle through each month
572
    foreach($daterange as $date) {
573
574
      // Check if we have
575
      if  (($date->format('Y-n') != $old_month) || ($start)) {
576
577
        $year = $date->format("Y");
578
        $dayinterval = new \DateInterval('P1D');
579
580
        // Handle the first month
581
        if ($this->isFirstMonth($date)) {
582
          // If we are in the same month the end date is the end date of the event
583
          if ($this->isSameMonth()) {
584
            $dayrange = new \DatePeriod($this->start_date, $dayinterval, new \DateTime($this->end_date->format("Y-n-j 23:59:59")));
585
          }
586
          else { // alternatively it is the last day of the start month
587
            $dayrange = new \DatePeriod($this->start_date, $dayinterval, $this->endMonthDate($this->start_date));
588
          }
589 View Code Duplication
          foreach ($dayrange as $day) {
0 ignored issues
show
Duplication introduced by
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...
590
            $itemized[AbstractEvent::BAT_DAY][$year][$day->format('n')]['d' . $day->format('j')] = $this->getValue();
591
          }
592
        }
593
594
        // Handle the last month (will be skipped if event is same month)
595
        elseif ($this->isLastMonth($date)) {
596
          $dayrange = new \DatePeriod(new \DateTime($date->format("Y-n-1")), $dayinterval, $this->end_date);
597 View Code Duplication
          foreach ($dayrange as $day) {
0 ignored issues
show
Duplication introduced by
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...
598
            $itemized[AbstractEvent::BAT_DAY][$year][$day->format('n')]['d' . $day->format('j')] = $this->getValue();
599
          }
600
        }
601
602
        // We are in an in-between month - just cycle through and set dates (time on end date set to ensure it is included)
603
        else {
604
          $dayrange = new \DatePeriod(new \DateTime($date->format("Y-n-1")), $dayinterval, new \DateTime($date->format("Y-n-t 23:59:59")));
605 View Code Duplication
          foreach ($dayrange as $day) {
0 ignored issues
show
Duplication introduced by
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...
606
            $itemized[AbstractEvent::BAT_DAY][$year][$day->format('n')]['d' . $day->format('j')] = $this->getValue();
607
          }
608
        }
609
      }
610
      $start = FALSE;
611
      $old_month = $date->format('Y-n');
612
    }
613
614
    if ($granularity == AbstractEvent::BAT_HOURLY) {
615
      // Add granural info in
616
      $itemized = $this->createDayGranural($itemized);
617
    }
618
619
    return $itemized;
620
  }
621
622
  /**
623
   * Saves an event using the Store object
624
   *
625
   * @param \Roomify\Bat\\Store\Store $store
626
   * @param string $granularity
627
   *
628
   * @return boolean
629
   */
630
  public function saveEvent(Store $store, $granularity = AbstractEvent::BAT_HOURLY) {
631
    return $store->storeEvent($this, $granularity);
0 ignored issues
show
Compatibility introduced by
$this of type object<Roomify\Bat\Event\AbstractEvent> is not a sub-type of object<Roomify\Bat\Event\Event>. It seems like you assume a child class of the class Roomify\Bat\Event\AbstractEvent to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
632
  }
633
634
}
635