1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Hook reactor class. |
5
|
|
|
* |
6
|
|
|
* @package wordpoints-hooks-api |
7
|
|
|
* @since 1.0.0 |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* Bootstrap for performing pre-scripted reactions when an event is fired. |
12
|
|
|
* |
13
|
|
|
* When a hook event fires, it is the job of the reactor to perform the action |
14
|
|
|
* specified for each reaction object. For most reactors this means that they must |
15
|
|
|
* "hit" a "target". For example, it might award points to a particular user. |
16
|
|
|
* |
17
|
|
|
* @since 1.0.0 |
18
|
|
|
* |
19
|
|
|
* @property-read WordPoints_Hook_Reaction_StorageI|null $reactions |
20
|
|
|
* Object for accessing hook reactions for this reactor based on the |
21
|
|
|
* current network mode. If a reactor doesn't support network |
22
|
|
|
* reactions and network mode is on, this property is not available. |
23
|
|
|
*/ |
24
|
|
|
abstract class WordPoints_Hook_Reactor implements WordPoints_Hook_SettingsI { |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* The unique slug identifying this hook reactor. |
28
|
|
|
* |
29
|
|
|
* @since 1.0.0 |
30
|
|
|
* |
31
|
|
|
* @var string |
32
|
|
|
*/ |
33
|
|
|
protected $slug; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* The types of args that this reactor can target. |
37
|
|
|
* |
38
|
|
|
* @since 1.0.0 |
39
|
|
|
* |
40
|
|
|
* @var string|string[] |
41
|
|
|
*/ |
42
|
|
|
protected $arg_types; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* The settings fields used by this reactor. |
46
|
|
|
* |
47
|
|
|
* @since 1.0.0 |
48
|
|
|
* |
49
|
|
|
* @var array |
50
|
|
|
*/ |
51
|
|
|
protected $settings_fields; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* @since 1.0.0 |
55
|
|
|
*/ |
56
|
|
|
public function __get( $var ) { |
57
|
|
|
|
58
|
|
|
if ( 'reactions' !== $var ) { |
59
|
|
|
return null; |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
$reaction_group = $this->get_reaction_group( |
63
|
|
|
wordpoints_hooks()->get_current_mode() |
64
|
|
|
); |
65
|
|
|
|
66
|
|
|
if ( ! $reaction_group ) { |
67
|
|
|
return null; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
return $reaction_group; |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* Get a reaction group's storage object. |
75
|
|
|
* |
76
|
|
|
* @since 1.0.0 |
77
|
|
|
* |
78
|
|
|
* @param string $slug The slug of the reaction group to get. |
79
|
|
|
* |
80
|
|
|
* @return WordPoints_Hook_Reaction_StorageI|false The reaction storage object. |
81
|
|
|
*/ |
82
|
|
|
public function get_reaction_group( $slug ) { |
83
|
|
|
|
84
|
|
|
$reaction_group = wordpoints_hooks()->reaction_groups->get( |
85
|
|
|
$this->slug |
86
|
|
|
, $slug |
87
|
|
|
, array( $this ) |
88
|
|
|
); |
89
|
|
|
|
90
|
|
|
if ( ! $reaction_group instanceof WordPoints_Hook_Reaction_StorageI ) { |
91
|
|
|
return false; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
// Allowing access to groups out-of-context would lead to strange behavior. |
95
|
|
|
if ( false === $reaction_group->get_context_id() ) { |
96
|
|
|
return false; |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
return $reaction_group; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Get the slug of this reactor. |
104
|
|
|
* |
105
|
|
|
* @since 1.0.0 |
106
|
|
|
* |
107
|
|
|
* @return string The reactor's slug. |
108
|
|
|
*/ |
109
|
|
|
public function get_slug() { |
110
|
|
|
return $this->slug; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Get a list of the slugs of each type of arg that this reactor supports. |
115
|
|
|
* |
116
|
|
|
* @since 1.0.0 |
117
|
|
|
* |
118
|
|
|
* @return string[] The slugs of the arg types this reactor supports. |
119
|
|
|
*/ |
120
|
|
|
public function get_arg_types() { |
121
|
|
|
return (array) $this->arg_types; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Get the settings fields used by the reactor. |
126
|
|
|
* |
127
|
|
|
* @since 1.0.0 |
128
|
|
|
* |
129
|
|
|
* @return string[] The meta keys used to store this reactor's settings. |
130
|
|
|
*/ |
131
|
|
|
public function get_settings_fields() { |
132
|
|
|
return $this->settings_fields; |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Check what context this reactor exists in. |
137
|
|
|
* |
138
|
|
|
* When a reactor is not network-wide, network reactions are not supported. For |
139
|
|
|
* example, the points reactor is not network-wide when WordPoints isn't network- |
140
|
|
|
* active, because the points types are created per-site. We default all reactors |
141
|
|
|
* to being network wide only when WordPoints is network-active, but some may |
142
|
|
|
* need to override this. |
143
|
|
|
* |
144
|
|
|
* @since 1.0.0 |
145
|
|
|
* |
146
|
|
|
* @return string[] The slug(s) of the context in which this reactor exists. |
147
|
|
|
*/ |
148
|
|
|
public function get_context() { |
149
|
|
|
|
150
|
|
|
return is_wordpoints_network_active() |
151
|
|
|
? array( 'network' ) |
152
|
|
|
: array( 'network', 'site' ); |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* Get all reactions to a particular event for this reactor. |
157
|
|
|
* |
158
|
|
|
* On multisite it will return all reactions for the current site, both standard |
159
|
|
|
* ones and any network-wide ones (if this reactor offers a network storage |
160
|
|
|
* class). Or, if network mode is on, it will return only the network-wide ones. |
161
|
|
|
* |
162
|
|
|
* Speaking more generally, it will return the reactions from all reaction groups |
163
|
|
|
* that are available in the current context. |
164
|
|
|
* |
165
|
|
|
* @since 1.0.0 |
166
|
|
|
* |
167
|
|
|
* @param string $event_slug The event slug. |
168
|
|
|
* |
169
|
|
|
* @return WordPoints_Hook_ReactionI[] All of the reaction objects. |
170
|
|
|
*/ |
171
|
|
View Code Duplication |
public function get_all_reactions_to_event( $event_slug ) { |
|
|
|
|
172
|
|
|
|
173
|
|
|
$reactions = array(); |
174
|
|
|
|
175
|
|
|
$slugs = wordpoints_hooks()->reaction_groups->get_children_slugs( |
176
|
|
|
$this->slug |
177
|
|
|
); |
178
|
|
|
|
179
|
|
|
foreach ( $slugs as $slug ) { |
180
|
|
|
|
181
|
|
|
$storage = $this->get_reaction_group( $slug ); |
182
|
|
|
|
183
|
|
|
if ( ! $storage ) { |
184
|
|
|
continue; |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
$reactions = array_merge( |
188
|
|
|
$reactions |
189
|
|
|
, $storage->get_reactions_to_event( $event_slug ) |
190
|
|
|
); |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
return $reactions; |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* Get all reactions for this reactor. |
198
|
|
|
* |
199
|
|
|
* On multisite it will return all reactions for the current site, both standard |
200
|
|
|
* ones and any network-wide ones (if this reactor offers a network storage |
201
|
|
|
* class). Or, if network mode is on, it will return only the network-wide ones. |
202
|
|
|
* |
203
|
|
|
* Speaking more generally, it will return the reactions from all reaction groups |
204
|
|
|
* that are available in the current context. |
205
|
|
|
* |
206
|
|
|
* @since 1.0.0 |
207
|
|
|
* |
208
|
|
|
* @return WordPoints_Hook_ReactionI[] All of the reaction objects. |
209
|
|
|
*/ |
210
|
|
View Code Duplication |
public function get_all_reactions() { |
|
|
|
|
211
|
|
|
|
212
|
|
|
$reactions = array(); |
213
|
|
|
|
214
|
|
|
$slugs = wordpoints_hooks()->reaction_groups->get_children_slugs( |
215
|
|
|
$this->slug |
216
|
|
|
); |
217
|
|
|
|
218
|
|
|
foreach ( $slugs as $slug ) { |
219
|
|
|
|
220
|
|
|
$storage = $this->get_reaction_group( $slug ); |
221
|
|
|
|
222
|
|
|
if ( ! $storage ) { |
223
|
|
|
continue; |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
$reactions = array_merge( $reactions, $storage->get_reactions() ); |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
return $reactions; |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
/** |
233
|
|
|
* @since 1.0.0 |
234
|
|
|
*/ |
235
|
|
|
public function validate_settings( |
236
|
|
|
array $settings, |
237
|
|
|
WordPoints_Hook_Reaction_Validator $validator, |
238
|
|
|
WordPoints_Hook_Event_Args $event_args |
239
|
|
|
) { |
240
|
|
|
|
241
|
|
|
if ( |
242
|
|
|
empty( $settings['target'] ) |
243
|
|
|
|| ! is_array( $settings['target'] ) |
244
|
|
|
) { |
245
|
|
|
|
246
|
|
|
$validator->add_error( __( 'Invalid target.', 'wordpoints' ), 'target' ); |
247
|
|
|
|
248
|
|
|
} else { |
249
|
|
|
|
250
|
|
|
$target = $event_args->get_from_hierarchy( $settings['target'] ); |
251
|
|
|
|
252
|
|
|
if ( |
253
|
|
|
! $target instanceof WordPoints_Entity |
254
|
|
|
|| ! in_array( $target->get_slug(), (array) $this->arg_types ) |
255
|
|
|
) { |
256
|
|
|
$validator->add_error( __( 'Invalid target.', 'wordpoints' ), 'target' ); |
257
|
|
|
} |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
return $settings; |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
/** |
264
|
|
|
* @since 1.0.0 |
265
|
|
|
*/ |
266
|
|
|
public function update_settings( WordPoints_Hook_ReactionI $reaction, array $settings ) { |
267
|
|
|
$reaction->update_meta( 'target', $settings['target'] ); |
268
|
|
|
} |
269
|
|
|
|
270
|
|
|
/** |
271
|
|
|
* Perform an action when the reactor is hit by an event being fired. |
272
|
|
|
* |
273
|
|
|
* @since 1.0.0 |
274
|
|
|
* |
275
|
|
|
* @param WordPoints_Hook_Event_Args $event_args The event args. |
276
|
|
|
* @param WordPoints_Hook_ReactionI $reaction The reaction. |
277
|
|
|
*/ |
278
|
|
|
abstract public function hit( |
279
|
|
|
WordPoints_Hook_Event_Args $event_args, |
280
|
|
|
WordPoints_Hook_ReactionI $reaction |
281
|
|
|
); |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
// EOF |
285
|
|
|
|
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.