1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Conditions hook extension class. |
5
|
|
|
* |
6
|
|
|
* @package wordpoints-hooks-api |
7
|
|
|
* @since 1.0.0 |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* Requires the event args to meet certain conditions for the target to be hit. |
12
|
|
|
* |
13
|
|
|
* @since 1.0.0 |
14
|
|
|
*/ |
15
|
|
|
class WordPoints_Hook_Extension_Conditions extends WordPoints_Hook_Extension { |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* @since 1.0.0 |
19
|
|
|
*/ |
20
|
|
|
protected $slug = 'conditions'; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* The conditions registry. |
24
|
|
|
* |
25
|
|
|
* @since 1.0.0 |
26
|
|
|
* |
27
|
|
|
* @var WordPoints_Class_Registry_Children |
28
|
|
|
*/ |
29
|
|
|
protected $conditions; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @since 1.0.0 |
33
|
|
|
*/ |
34
|
|
|
public function __construct() { |
35
|
|
|
$this->conditions = wordpoints_hooks()->conditions; |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @since 1.0.0 |
40
|
|
|
*/ |
41
|
|
|
public function get_ui_script_data() { |
42
|
|
|
|
43
|
|
|
$conditions_data = array(); |
44
|
|
|
|
45
|
|
|
foreach ( $this->conditions->get_all() as $data_type => $conditions ) { |
46
|
|
|
foreach ( $conditions as $slug => $condition ) { |
47
|
|
|
|
48
|
|
|
if ( ! ( $condition instanceof WordPoints_Hook_Condition ) ) { |
49
|
|
|
continue; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
$conditions_data[ $data_type ][ $slug ] = array( |
53
|
|
|
'slug' => $slug, |
54
|
|
|
'data_type' => $data_type, |
55
|
|
|
'title' => $condition->get_title(), |
56
|
|
|
'fields' => $condition->get_settings_fields(), |
57
|
|
|
); |
58
|
|
|
} |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
return array( 'conditions' => $conditions_data ); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* @since 1.0.0 |
66
|
|
|
*/ |
67
|
|
|
protected function validate_action_type_settings( $settings ) { |
68
|
|
|
return $this->validate_conditions( $settings ); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Validate the conditions. |
73
|
|
|
* |
74
|
|
|
* @since 1.0.0 |
75
|
|
|
* |
76
|
|
|
* @param array $conditions The args and their conditions. |
77
|
|
|
* @param WordPoints_Hook_Event_Args $event_args The event args object. |
78
|
|
|
* |
79
|
|
|
* @return array The validated settings. |
80
|
|
|
*/ |
81
|
|
|
public function validate_conditions( $conditions, WordPoints_Hook_Event_Args $event_args = null ) { |
82
|
|
|
|
83
|
|
|
if ( $event_args ) { |
84
|
|
|
$this->event_args = $event_args; |
85
|
|
|
$this->validator = $event_args->get_validator(); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
if ( ! is_array( $conditions ) ) { |
89
|
|
|
|
90
|
|
|
$this->validator->add_error( |
91
|
|
|
__( 'Conditions do not match expected format.', 'wordpoints' ) |
92
|
|
|
); |
93
|
|
|
|
94
|
|
|
return array(); |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
foreach ( $conditions as $arg_slug => $sub_args ) { |
98
|
|
|
|
99
|
|
|
if ( '_conditions' === $arg_slug ) { |
100
|
|
|
|
101
|
|
|
$this->validator->push_field( $arg_slug ); |
102
|
|
|
|
103
|
|
|
foreach ( $sub_args as $index => $settings ) { |
104
|
|
|
|
105
|
|
|
$this->validator->push_field( $index ); |
106
|
|
|
|
107
|
|
|
$condition = $this->validate_condition( $settings ); |
108
|
|
|
|
109
|
|
|
if ( $condition ) { |
110
|
|
|
$sub_args[ $index ] = $condition; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
$this->validator->pop_field(); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
$this->validator->pop_field(); |
117
|
|
|
|
118
|
|
|
} else { |
119
|
|
|
|
120
|
|
|
if ( ! $this->event_args->descend( $arg_slug ) ) { |
121
|
|
|
continue; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
$sub_args = $this->validate_action_type_settings( $sub_args ); |
125
|
|
|
|
126
|
|
|
$conditions[ $arg_slug ] = $sub_args; |
127
|
|
|
|
128
|
|
|
$this->event_args->ascend(); |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
$conditions[ $arg_slug ] = $sub_args; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
return $conditions; |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* Validate a condition's settings. |
139
|
|
|
* |
140
|
|
|
* @since 1.0.0 |
141
|
|
|
* |
142
|
|
|
* @param array $settings The condition settings. |
143
|
|
|
* |
144
|
|
|
* @return array|false The validated conditions settings, or false if unable to |
145
|
|
|
* validate. |
146
|
|
|
*/ |
147
|
|
|
protected function validate_condition( $settings ) { |
148
|
|
|
|
149
|
|
View Code Duplication |
if ( ! isset( $settings['type'] ) ) { |
|
|
|
|
150
|
|
|
$this->validator->add_error( __( 'Condition type is missing.', 'wordpoints' ) ); |
151
|
|
|
return false; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
$arg = $this->event_args->get_current(); |
155
|
|
|
|
156
|
|
|
$data_type = $this->get_data_type( $arg ); |
157
|
|
|
|
158
|
|
|
if ( ! $data_type ) { |
|
|
|
|
159
|
|
|
$this->validator->add_error( |
160
|
|
|
__( 'This type of condition does not work for the selected attribute.', 'wordpoints' ) |
161
|
|
|
); |
162
|
|
|
|
163
|
|
|
return false; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
$condition = wordpoints_hooks()->conditions->get( $data_type, $settings['type'] ); |
167
|
|
|
|
168
|
|
|
if ( ! $condition ) { |
|
|
|
|
169
|
|
|
|
170
|
|
|
$this->validator->add_error( |
171
|
|
|
sprintf( |
172
|
|
|
__( 'Unknown condition type “%s”.', 'wordpoints' ) |
173
|
|
|
, $settings['type'] |
174
|
|
|
) |
175
|
|
|
, 'type' |
176
|
|
|
); |
177
|
|
|
|
178
|
|
|
return false; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
View Code Duplication |
if ( ! isset( $settings['settings'] ) ) { |
|
|
|
|
182
|
|
|
$this->validator->add_error( __( 'Condition settings are missing.', 'wordpoints' ) ); |
183
|
|
|
return false; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
$this->validator->push_field( 'settings' ); |
187
|
|
|
|
188
|
|
|
// The condition may call this object's validate_settings() method to |
189
|
|
|
// validate some sub-conditions. When that happens, these properties will be |
190
|
|
|
// reset, so we need to back up their values and then restore them below. |
191
|
|
|
$backup = array( $this->validator, $this->event_args ); |
192
|
|
|
|
193
|
|
|
$settings['settings'] = $condition->validate_settings( |
194
|
|
|
$arg |
195
|
|
|
, $settings['settings'] |
196
|
|
|
, $this->validator |
197
|
|
|
); |
198
|
|
|
|
199
|
|
|
list( $this->validator, $this->event_args ) = $backup; |
200
|
|
|
|
201
|
|
|
$this->validator->pop_field(); |
202
|
|
|
|
203
|
|
|
return $settings; |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
/** |
207
|
|
|
* @since 1.0.0 |
208
|
|
|
*/ |
209
|
|
|
public function should_hit( WordPoints_Hook_Fire $fire ) { |
210
|
|
|
|
211
|
|
|
$conditions = $this->get_settings_from_fire( $fire ); |
212
|
|
|
|
213
|
|
|
if ( $conditions && ! $this->conditions_are_met( $conditions, $fire->event_args ) ) { |
214
|
|
|
return false; |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
return true; |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* Check if the event args meet the conditions. |
222
|
|
|
* |
223
|
|
|
* @since 1.0.0 |
224
|
|
|
* |
225
|
|
|
* @param array $conditions The conditions. |
226
|
|
|
* @param WordPoints_Hook_Event_Args $event_args The event args. |
227
|
|
|
* |
228
|
|
|
* @return bool Whether the conditions are met. |
229
|
|
|
*/ |
230
|
|
|
public function conditions_are_met( |
231
|
|
|
$conditions, |
232
|
|
|
WordPoints_Hook_Event_Args $event_args |
233
|
|
|
) { |
234
|
|
|
|
235
|
|
|
foreach ( $conditions as $arg_slug => $sub_args ) { |
236
|
|
|
|
237
|
|
|
$event_args->descend( $arg_slug ); |
238
|
|
|
|
239
|
|
|
if ( isset( $sub_args['_conditions'] ) ) { |
240
|
|
|
|
241
|
|
|
foreach ( $sub_args['_conditions'] as $settings ) { |
242
|
|
|
|
243
|
|
|
$condition = $this->conditions->get( |
244
|
|
|
$this->get_data_type( $event_args->get_current() ) |
|
|
|
|
245
|
|
|
, $settings['type'] |
246
|
|
|
); |
247
|
|
|
|
248
|
|
|
$is_met = $condition->is_met( $settings['settings'], $event_args ); |
249
|
|
|
|
250
|
|
|
if ( ! $is_met ) { |
251
|
|
|
$event_args->ascend(); |
252
|
|
|
return false; |
253
|
|
|
} |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
unset( $sub_args['_conditions'] ); |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
$are_met = $this->conditions_are_met( $sub_args, $event_args ); |
260
|
|
|
|
261
|
|
|
$event_args->ascend(); |
262
|
|
|
|
263
|
|
|
if ( ! $are_met ) { |
264
|
|
|
return false; |
265
|
|
|
} |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
return true; |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
/** |
272
|
|
|
* Get the data type of an entity. |
273
|
|
|
* |
274
|
|
|
* @since 1.0.0 |
275
|
|
|
* |
276
|
|
|
* @param WordPoints_EntityishI $arg An entity object. |
277
|
|
|
* |
278
|
|
|
* @return string|false The data type, or false. |
279
|
|
|
*/ |
280
|
|
|
protected function get_data_type( $arg ) { |
281
|
|
|
|
282
|
|
|
if ( $arg instanceof WordPoints_Entity_Attr ) { |
283
|
|
|
$data_type = $arg->get_data_type(); |
284
|
|
|
} elseif ( $arg instanceof WordPoints_Entity_Array ) { |
285
|
|
|
$data_type = 'entity_array'; |
286
|
|
|
} elseif ( $arg instanceof WordPoints_Entity ) { |
287
|
|
|
$data_type = 'entity'; |
288
|
|
|
} else { |
289
|
|
|
$data_type = false; |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
return $data_type; |
293
|
|
|
} |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
// EOF |
297
|
|
|
|
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.