Completed
Push — main ( ec0f68...b41cf0 )
by Andreas
14s queued 12s
created

SwapDecorator   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 65
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
eloc 27
c 1
b 0
f 0
dl 0
loc 65
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getName() 0 3 1
A __construct() 0 5 1
A dateMatches() 0 11 3
A isHoliday() 0 3 1
A ruleMatches() 0 3 1
A isModifiedDate() 0 19 4
1
<?php
2
3
/**
4
 * Copyright Andreas Heigl <[email protected]>
5
 *
6
 * Licensed under the MIT-license. For details see the included file LICENSE.md
7
 */
8
9
declare(strict_types=1);
10
11
namespace Org_Heigl\Holidaychecker\IteratorItem;
12
13
use DateTimeInterface;
14
use IntlCalendar;
15
use Org_Heigl\Holidaychecker\CalendarDay;
16
use Org_Heigl\Holidaychecker\GregorianWeekday;
17
use Org_Heigl\Holidaychecker\HolidayIteratorItemInterface;
18
use Org_Heigl\Holidaychecker\SwapDirection;
19
use Org_Heigl\Holidaychecker\SwapRule;
20
use function in_array;
21
22
class SwapDecorator implements HolidayIteratorItemInterface
23
{
24
	/** @var HolidayIteratorItemInterface  */
25
	private $rule;
26
27
	/** @var CalendarDay  */
28
	private $day;
29
30
	/** @var SwapRule[]  */
31
	private $swapRules;
32
33
	public function __construct(HolidayIteratorItemInterface $rule, CalendarDay $day, SwapRule ...$swapRules)
34
	{
35
		$this->rule = $rule;
36
		$this->day = $day;
37
		$this->swapRules = $swapRules;
38
	}
39
40
	public function dateMatches(DateTimeInterface $date): bool
41
	{
42
		$year = (int) $date->format('Y');
43
		$weekday = GregorianWeekday::fromIntlWeekday($this->day->getWeekdayForGregorianYear($year));
44
		foreach ($this->swapRules as $rule) {
45
			if ($this->ruleMatches($rule, $weekday)) {
46
				return $this->isModifiedDate($date, $rule->getSwapToDay(), $rule->getDirection());
47
			}
48
		}
49
50
		return $this->rule->dateMatches($date);
51
	}
52
53
	public function getName(): string
54
	{
55
		return $this->rule->getName();
56
	}
57
58
	public function isHoliday(): bool
59
	{
60
		return $this->rule->isHoliday();
61
	}
62
63
	private function ruleMatches(SwapRule $rule, GregorianWeekday $weekday): bool
64
	{
65
		return in_array($weekday, $rule->getSwapWhenDays(), true);
66
	}
67
68
	private function isModifiedDate(DateTimeInterface $dateTime, GregorianWeekday $modifiedDay, SwapDirection $direction): bool
69
	{
70
		$cal = $this->day->getCalendar();
71
		$cal = CalendarDay::setGregorianYearForDate((int) $dateTime->format('Y'), $cal);
72
		$day = $cal->toDateTime();
73
		$day->modify($direction->getDateTimeDirection() . ' ' . $modifiedDay);
74
		$cal->setTime($day->getTimestamp() * 1000);
75
		$cal2 = $this->day->getCalendar();
76
		$cal2->setTime($dateTime->getTimestamp() * 1000);
77
78
		if ($this->day->hasYearSet() && $cal->get(IntlCalendar::FIELD_YEAR) !== $cal2->get(IntlCalendar::FIELD_YEAR)) {
79
			return false;
80
		}
81
82
		if ($cal->get(IntlCalendar::FIELD_MONTH) !== $cal2->get(IntlCalendar::FIELD_MONTH)) {
83
			return false;
84
		}
85
86
		return $cal->get(IntlCalendar::FIELD_DAY_OF_MONTH) === $cal2->get(IntlCalendar::FIELD_DAY_OF_MONTH);
87
	}
88
}
89