|
1
|
|
|
<?php |
|
2
|
|
|
namespace JClaveau\LogicalFilter\Rule; |
|
3
|
|
|
|
|
4
|
|
|
/** |
|
5
|
|
|
* a <= x |
|
6
|
|
|
*/ |
|
7
|
|
View Code Duplication |
class BelowOrEqualRule extends OrRule |
|
|
|
|
|
|
8
|
|
|
{ |
|
9
|
|
|
use Trait_RuleWithField; |
|
10
|
|
|
|
|
11
|
|
|
/** @var string operator */ |
|
12
|
|
|
const operator = '<='; |
|
13
|
|
|
|
|
14
|
|
|
/** @var mixed maximum */ |
|
15
|
|
|
protected $maximum; |
|
16
|
|
|
|
|
17
|
|
|
/** |
|
18
|
|
|
* @param string $field The field to apply the rule on. |
|
19
|
|
|
* @param array $value The value the field can below to. |
|
|
|
|
|
|
20
|
|
|
*/ |
|
21
|
33 |
|
public function __construct($field, $maximum, array $options=[]) |
|
22
|
|
|
{ |
|
23
|
33 |
|
if ( ! empty($options)) { |
|
24
|
16 |
|
$this->setOptions($options); |
|
25
|
16 |
|
} |
|
26
|
|
|
|
|
27
|
33 |
|
$this->field = $field; |
|
28
|
33 |
|
$this->maximum = $maximum; |
|
29
|
33 |
|
} |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* @return mixed The maximum for the field of this rule |
|
33
|
|
|
*/ |
|
34
|
33 |
|
public function getMaximum() |
|
35
|
|
|
{ |
|
36
|
33 |
|
return $this->maximum; |
|
37
|
|
|
} |
|
38
|
|
|
|
|
39
|
|
|
/** |
|
40
|
|
|
* Defines the maximum of the current rule |
|
41
|
|
|
* |
|
42
|
|
|
* @param mixed $maximum |
|
43
|
|
|
* @return BelowOrEqualRule $this |
|
44
|
|
|
*/ |
|
45
|
2 |
|
public function setMaximum($maximum) |
|
46
|
|
|
{ |
|
47
|
2 |
|
if (null === $maximum) { |
|
48
|
|
|
throw new \InvalidArgumentException( |
|
49
|
|
|
"The maximum of a below or equal rule cannot be null" |
|
50
|
|
|
); |
|
51
|
|
|
} |
|
52
|
|
|
|
|
53
|
2 |
|
if ($this->maximum == $maximum) { |
|
54
|
2 |
|
return $this; |
|
55
|
|
|
} |
|
56
|
|
|
|
|
57
|
|
|
$this->maximum = $maximum; |
|
58
|
|
|
$this->flushCache(); |
|
59
|
|
|
|
|
60
|
|
|
return $this; |
|
61
|
|
|
} |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* @return bool |
|
65
|
|
|
*/ |
|
66
|
15 |
|
public function isNormalizationAllowed(array $contextual_options=[]) |
|
67
|
|
|
{ |
|
68
|
15 |
|
return $this->getOption('below_or_equal.normalization', $contextual_options); |
|
69
|
|
|
} |
|
70
|
|
|
|
|
71
|
|
|
/** |
|
72
|
|
|
* @return array $operands |
|
73
|
|
|
*/ |
|
74
|
15 |
|
public function getOperands() |
|
75
|
|
|
{ |
|
76
|
15 |
|
if ( ! empty($this->cache['operands'])) { |
|
77
|
14 |
|
return $this->cache['operands']; |
|
78
|
|
|
} |
|
79
|
|
|
|
|
80
|
|
|
$operands = [ |
|
81
|
15 |
|
new BelowRule($this->field, $this->maximum), |
|
82
|
15 |
|
new EqualRule($this->field, $this->maximum), |
|
83
|
15 |
|
]; |
|
84
|
|
|
|
|
85
|
15 |
|
return $this->cache['operands'] = $operands; |
|
86
|
|
|
} |
|
87
|
|
|
|
|
88
|
|
|
/** |
|
89
|
|
|
* Set the maximum and the field of the current instance by giving |
|
90
|
|
|
* an array of opereands as parameter. |
|
91
|
|
|
* |
|
92
|
|
|
* @param array $operands |
|
93
|
|
|
* @return BelowOrEqualRule $this |
|
94
|
|
|
*/ |
|
95
|
3 |
|
public function setOperands(array $operands) |
|
96
|
|
|
{ |
|
97
|
3 |
|
foreach ($operands as $operand) { |
|
98
|
3 |
|
if ($operand instanceof EqualRule) { |
|
99
|
3 |
|
$equalRuleField = $operand->getField(); |
|
100
|
3 |
|
$equalRuleValue = $operand->getValue(); |
|
101
|
3 |
|
} |
|
102
|
3 |
|
elseif ($operand instanceof BelowRule) { |
|
103
|
3 |
|
$belowRuleField = $operand->getField(); |
|
104
|
3 |
|
$belowRuleValue = $operand->getUpperLimit(); |
|
105
|
3 |
|
} |
|
106
|
3 |
|
} |
|
107
|
|
|
|
|
108
|
3 |
|
if ( 2 != count($operands) |
|
109
|
3 |
|
|| ! isset($equalRuleValue) |
|
110
|
3 |
|
|| ! isset($belowRuleValue) |
|
111
|
3 |
|
|| $belowRuleValue != $equalRuleValue |
|
112
|
3 |
|
|| $belowRuleField != $equalRuleField |
|
|
|
|
|
|
113
|
3 |
|
) { |
|
114
|
1 |
|
throw new \InvalidArgumentException( |
|
115
|
|
|
"Operands must be an array of two rules like (field < maximum || field = maximum) instead of:\n" |
|
116
|
1 |
|
.var_export($operands, true) |
|
117
|
1 |
|
); |
|
118
|
|
|
} |
|
119
|
|
|
|
|
120
|
2 |
|
$this->setMaximum($belowRuleValue); |
|
121
|
2 |
|
$this->setField($belowRuleField); |
|
122
|
|
|
|
|
123
|
2 |
|
return $this; |
|
124
|
|
|
} |
|
125
|
|
|
|
|
126
|
|
|
/** |
|
127
|
|
|
* @return array |
|
128
|
|
|
*/ |
|
129
|
33 |
|
public function getValues() |
|
130
|
|
|
{ |
|
131
|
33 |
|
return $this->getMaximum(); |
|
132
|
|
|
} |
|
133
|
|
|
|
|
134
|
|
|
/** |
|
135
|
|
|
* @param array $options + show_instance=false Display the operator of the rule or its instance id |
|
136
|
|
|
* |
|
137
|
|
|
* @return array |
|
138
|
|
|
*/ |
|
139
|
33 |
|
public function toArray(array $options=[]) |
|
140
|
|
|
{ |
|
141
|
|
|
$default_options = [ |
|
142
|
33 |
|
'show_instance' => false, |
|
143
|
33 |
|
]; |
|
144
|
33 |
|
foreach ($default_options as $default_option => &$default_value) { |
|
145
|
33 |
|
if ( ! isset($options[ $default_option ])) { |
|
146
|
33 |
|
$options[ $default_option ] = $default_value; |
|
147
|
33 |
|
} |
|
148
|
33 |
|
} |
|
149
|
|
|
|
|
150
|
|
|
try { |
|
151
|
|
|
// TODO replace this rule by a simple OrRule? |
|
152
|
|
|
return [ |
|
153
|
33 |
|
$this->getField(), |
|
154
|
33 |
|
$options['show_instance'] ? $this->getInstanceId() : self::operator, |
|
155
|
33 |
|
$this->getValues(), |
|
156
|
33 |
|
]; |
|
157
|
|
|
} |
|
158
|
|
|
catch (\RuntimeException $e) { |
|
159
|
|
|
return parent::toArray(); |
|
160
|
|
|
} |
|
161
|
|
|
} |
|
162
|
|
|
|
|
163
|
|
|
/** |
|
164
|
|
|
*/ |
|
165
|
1 |
|
public function toString(array $options=[]) |
|
166
|
|
|
{ |
|
167
|
1 |
|
if (isset($this->cache['string'])) { |
|
168
|
1 |
|
return $this->cache['string']; |
|
169
|
|
|
} |
|
170
|
|
|
|
|
171
|
1 |
|
$operator = self::operator; |
|
172
|
|
|
|
|
173
|
1 |
|
return $this->cache['string'] = "['{$this->getField()}', '$operator', " . var_export($this->getValues(), true). "]"; |
|
174
|
|
|
} |
|
175
|
|
|
|
|
176
|
|
|
/**/ |
|
177
|
|
|
} |
|
178
|
|
|
|
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.