32
32
class ScheduleCriteriaRequestEvent extends Event implements ScheduleCriteriaRequestInterface
33
33
{
34
34
public static $ NAME = 'schedule.criteria.request ' ;
35
- private $ criteria = [];
36
- private $ currentTypeIndex = null ;
37
- private $ currentMetric = null ;
35
+ private array $ criteria = [];
36
+ private ? int $ currentTypeIndex = null ;
37
+ private array $ currentMetric = [] ;
38
38
private array $ defaultConditions = [];
39
39
40
40
public function __construct ()
@@ -58,7 +58,21 @@ public function __construct()
58
58
*/
59
59
public function addType (string $ id , string $ type ): self
60
60
{
61
- // Initialize the type in the criteria array
61
+ // Ensure that 'types' key exists
62
+ if (!isset ($ this ->criteria ['types ' ])) {
63
+ $ this ->criteria ['types ' ] = [];
64
+ }
65
+
66
+ // Check if the type already exists
67
+ foreach ($ this ->criteria ['types ' ] as $ index => $ existingType ) {
68
+ if ($ existingType ['id ' ] === $ id ) {
69
+ // If the type exists, update currentTypeIndex and return
70
+ $ this ->currentTypeIndex = $ index ;
71
+ return $ this ;
72
+ }
73
+ }
74
+
75
+ // If the type doesn't exist, add it in the criteria array
62
76
$ this ->criteria ['types ' ][] = [
63
77
'id ' => $ id ,
64
78
'name ' => $ type ,
@@ -75,21 +89,38 @@ public function addType(string $id, string $type): self
75
89
*/
76
90
public function addMetric (string $ id , string $ name ): self
77
91
{
92
+ // Ensure the current type is set
93
+ if (!isset ($ this ->criteria ['types ' ][$ this ->currentTypeIndex ])) {
94
+ throw new ConfigurationException (__ ('Current type is not set. ' ));
95
+ }
96
+
97
+ // initialize the metric to add
78
98
$ metric = [
79
99
'id ' => $ id ,
80
100
'name ' => $ name ,
81
101
'conditions ' => $ this ->formatConditions ($ this ->defaultConditions ),
102
+ 'isUsingDefaultConditions ' => true ,
82
103
'values ' => null
83
104
];
84
105
85
- // Add the metric to the current type
86
- if (isset ($ this ->criteria ['types ' ][$ this ->currentTypeIndex ])) {
87
- $ this ->criteria ['types ' ][$ this ->currentTypeIndex ]['metrics ' ][] = $ metric ;
88
- $ this ->currentMetric = $ metric ;
89
- } else {
90
- throw new ConfigurationException (__ ('Current type is not set. ' ));
106
+ // Reference the current type's metrics
107
+ $ metrics = &$ this ->criteria ['types ' ][$ this ->currentTypeIndex ]['metrics ' ];
108
+
109
+ // Check if the metric already exists
110
+ foreach ($ metrics as &$ existingMetric ) {
111
+ if ($ existingMetric ['id ' ] === $ id ) {
112
+ // If the metric exists, set currentMetric and return
113
+ $ this ->currentMetric = $ existingMetric ;
114
+ return $ this ;
115
+ }
91
116
}
92
117
118
+ // If the metric doesn't exist, add it to the metrics array
119
+ $ metrics [] = $ metric ;
120
+
121
+ // Set the current metric for chaining
122
+ $ this ->currentMetric = $ metric ;
123
+
93
124
return $ this ;
94
125
}
95
126
@@ -99,6 +130,11 @@ public function addMetric(string $id, string $name): self
99
130
*/
100
131
public function addCondition (array $ conditions ): self
101
132
{
133
+ // Retain default conditions if provided condition array is empty
134
+ if (empty ($ conditions )) {
135
+ return $ this ;
136
+ }
137
+
102
138
// Ensure current type is set
103
139
if (!isset ($ this ->criteria ['types ' ][$ this ->currentTypeIndex ])) {
104
140
throw new ConfigurationException (__ ('Current type is not set. ' ));
@@ -111,10 +147,30 @@ public function addCondition(array $conditions): self
111
147
}
112
148
}
113
149
114
- // Assign conditions to the current metric
115
- foreach ($ this ->criteria ['types ' ][$ this ->currentTypeIndex ]['metrics ' ] as &$ metric ) {
116
- if ($ metric ['name ' ] === $ this ->currentMetric ['name ' ]) {
117
- $ metric ['conditions ' ] = $ this ->formatConditions ($ conditions );
150
+ // Reference the current type's metrics
151
+ $ metrics = &$ this ->criteria ['types ' ][$ this ->currentTypeIndex ]['metrics ' ];
152
+
153
+ // Find the current metric and handle conditions
154
+ foreach ($ metrics as &$ metric ) {
155
+ if ($ metric ['id ' ] === $ this ->currentMetric ['id ' ]) {
156
+ if ($ metric ['isUsingDefaultConditions ' ]) {
157
+ // If metric is using default conditions, replace with new ones
158
+ $ metric ['conditions ' ] = $ this ->formatConditions ($ conditions );
159
+ $ metric ['isUsingDefaultConditions ' ] = false ;
160
+ } else {
161
+ // Merge the new conditions with existing ones, avoiding duplicates
162
+ $ existingConditions = $ metric ['conditions ' ];
163
+ $ newConditions = $ this ->formatConditions ($ conditions );
164
+
165
+ // Combine the two condition arrays
166
+ $ mergedConditions = array_merge ($ existingConditions , $ newConditions );
167
+
168
+ // Remove duplicates
169
+ $ finalConditions = array_unique ($ mergedConditions , SORT_REGULAR );
170
+
171
+ $ metric ['conditions ' ] = array_values ($ finalConditions );
172
+ }
173
+
118
174
break ;
119
175
}
120
176
}
@@ -146,34 +202,54 @@ private function formatConditions(array $conditions): array
146
202
*/
147
203
public function addValues (string $ inputType , array $ values ): self
148
204
{
205
+ // Ensure current type is set
206
+ if (!isset ($ this ->criteria ['types ' ][$ this ->currentTypeIndex ])) {
207
+ throw new ConfigurationException (__ ('Current type is not set. ' ));
208
+ }
209
+
149
210
// Restrict input types to 'dropdown', 'number', 'text' and 'date'
150
211
$ allowedInputTypes = ['dropdown ' , 'number ' , 'text ' , 'date ' ];
151
212
if (!in_array ($ inputType , $ allowedInputTypes )) {
152
213
throw new ConfigurationException (__ ('Invalid input type. ' ));
153
214
}
154
215
155
- // Add values to the current metric
156
- if ( isset ( $ this ->criteria ['types ' ][$ this ->currentTypeIndex ])) {
157
- foreach ( $ this -> criteria [ ' types ' ][ $ this -> currentTypeIndex ][ ' metrics ' ] as & $ metric ) {
158
- // check if the current metric matches the metric from the current iteration
159
- if ( $ metric [ ' name ' ] === $ this -> currentMetric [ ' name ' ] ) {
160
- // format the values to separate id and title
161
- $ formattedValues = [];
162
- foreach ( $ values as $ id => $ title ) {
163
- $ formattedValues [] = [
164
- ' id ' => $ id ,
165
- ' title ' => $ title
166
- ];
167
- }
168
-
169
- $ metric [ ' values ' ] = [
170
- 'inputType ' => $ inputType ,
171
- 'values ' => $ formattedValues
216
+ // Reference the metrics of the current type
217
+ $ metrics = & $ this ->criteria ['types ' ][$ this ->currentTypeIndex ][ ' metrics ' ];
218
+
219
+ // Find the current metric and add or update values
220
+ foreach ( $ metrics as & $ metric ) {
221
+ if ( $ metric [ ' id ' ] === $ this -> currentMetric [ ' id ' ]) {
222
+ // Check if the input type matches the existing one (if any)
223
+ if ( isset ( $ metric [ ' values ' ][ ' inputType ' ]) && $ metric [ ' values ' ][ ' inputType ' ] !== $ inputType ) {
224
+ throw new ConfigurationException ( __ ( ' Input type does not match. ' ));
225
+ }
226
+
227
+ // Format the new values
228
+ $ formattedValues = [];
229
+ foreach ( $ values as $ id => $ title ) {
230
+ $ formattedValues [ ] = [
231
+ 'id ' => $ id ,
232
+ 'title ' => $ title
172
233
];
173
234
}
235
+
236
+ // Merge new values with existing ones, avoiding duplicates
237
+ $ existingValues = $ metric ['values ' ]['values ' ] ?? [];
238
+
239
+ // Combine the two value arrays
240
+ $ mergedValues = array_merge ($ existingValues , $ formattedValues );
241
+
242
+ // Remove duplicates
243
+ $ uniqueFormattedValues = array_unique ($ mergedValues , SORT_REGULAR );
244
+
245
+ // Update the metric's values
246
+ $ metric ['values ' ] = [
247
+ 'inputType ' => $ inputType ,
248
+ 'values ' => array_values ($ uniqueFormattedValues )
249
+ ];
250
+
251
+ break ;
174
252
}
175
- } else {
176
- throw new ConfigurationException (__ ('Current type is not set. ' ));
177
253
}
178
254
179
255
return $ this ;
0 commit comments