Passed
Pull Request — master (#21)
by Samuel
10:54
created

Recurrence::setFrequency()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 5
ccs 0
cts 2
cp 0
rs 10
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
namespace Recurrence\Model;
4
5
use Recurrence\Constraint\DatetimeConstraint\DatetimeConstraintInterface;
6
use Recurrence\Constraint\ProviderConstraint\EndOfMonthConstraint;
7
use Recurrence\Constraint\ProviderConstraint\ProviderConstraintInterface;
8
use Recurrence\Constraint\RecurrenceConstraintInterface;
9
use Recurrence\Model\Exception\InvalidRecurrenceException;
10
11
class Recurrence
12
{
13 1
    public function __construct(
14
        private Frequency $frequency,
15
        private int $interval,
16
        private \DateTime $periodStartAt,
17
        private ?\DateTime $periodEndAt = null,
18
        private ?int $count = null,
19
        private array $constraints = [],
20
    ) {
21 1
        if ($count && $periodEndAt) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $count of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
22
            throw new InvalidRecurrenceException('Recurrence cannot have [COUNT] and [UNTIL] option at the same time');
23
        }
24
25 1
        if (null === $count && null === $periodEndAt) {
26
            throw new InvalidRecurrenceException('Recurrence required [COUNT] or [UNTIL] option');
27
        }
28
29 1
        $constraintNames = array_map(static function ($constraint) { return $constraint::class; }, $constraints);
30 1
        $duplicateConstraints = array_diff_key($constraintNames, array_unique($constraintNames));
31
32 1
        if (!empty($duplicateConstraints)) {
33 1
            throw new \InvalidArgumentException(sprintf('Duplicate constraint [%s]', implode(', ', $duplicateConstraints)));
34
        }
35 1
    }
36
37
    public function getFrequency(): ?Frequency
38
    {
39
        return $this->frequency;
40
    }
41
42
    public function getInterval(): int
43
    {
44
        return $this->interval;
45
    }
46
47
    public function getPeriodStartAt(): \DateTime
48
    {
49 1
        return $this->periodStartAt;
50
    }
51
52
    public function getPeriodEndAt(): ?\DateTime
53
    {
54
        return $this->periodEndAt;
55
    }
56
57
    public function hasPeriodEndAt(): bool
58
    {
59
        return null !== $this->periodEndAt;
60
    }
61
62
    public function getCount(): ?int
63
    {
64
        return $this->count;
65
    }
66
67
    public function hasCount(): bool
68
    {
69
        return null !== $this->count;
70
    }
71
72
    public function getConstraints(): array
73
    {
74 1
        return $this->constraints;
75
    }
76
77
    public function hasConstraints(): bool
78
    {
79 1
        return !empty($this->constraints);
80
    }
81
82
    public function hasConstraint(string $constraintClassName): bool
83
    {
84 1
        foreach ($this->constraints as $key => $constraint) {
85 1
            if ($constraint::class == $constraintClassName) {
86 1
                return true;
87
            }
88
        }
89
90 1
        return false;
91
    }
92
93
    public function addConstraint(RecurrenceConstraintInterface $constraint): self
94
    {
95 1
        if ($this->hasConstraint($constraint::class)) {
96
            throw new \InvalidArgumentException(sprintf('Duplicate constraint [%s]', get_class($constraint)));
97
        }
98
99 1
        if ($constraint instanceof EndOfMonthConstraint && Frequency::FREQUENCY_MONTHLY !== $this->frequency->__toString()) {
100
            throw new InvalidRecurrenceException('End of month constraint can be applied only with monthly frequency');
101
        }
102
103 1
        $this->constraints[] = $constraint;
104
105 1
        return $this;
106
    }
107
108
    public function removeConstraint(string $constraintClassName): self
109
    {
110 1
        foreach ($this->constraints as $key => $constraint) {
111 1
            if ($constraint::class == $constraintClassName) {
112 1
                unset($this->constraints[$key]);
113
114 1
                break;
115
            }
116
        }
117
118 1
        $this->constraints = array_values($this->constraints);
119
120 1
        return $this;
121
    }
122
123
    public function hasProviderConstraint(): bool
124
    {
125 1
        foreach ($this->constraints as $key => $constraint) {
126 1
            if ($constraint instanceof ProviderConstraintInterface) {
127 1
                return true;
128
            }
129
        }
130
131 1
        return false;
132
    }
133
134
    public function hasDatetimeConstraint(): bool
135
    {
136 1
        foreach ($this->constraints as $key => $constraint) {
137 1
            if ($constraint instanceof DatetimeConstraintInterface) {
138 1
                return true;
139
            }
140
        }
141
142 1
        return false;
143
    }
144
}
145