Completed
Push — master ( 3d46b5...fce27c )
by J.D.
03:47
created

WordPoints_Hook_Reactor::__get()   D

Complexity

Conditions 9
Paths 17

Size

Total Lines 37
Code Lines 21

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 37
rs 4.909
cc 9
eloc 21
nc 17
nop 1
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
 * @property-read WordPoints_Hook_Reaction_StorageI|null $standard_reactions
25
 *                Object for accessing standard hook reactions for this reactor. Not
26
 *                available when network mode is on.
27
 *
28
 * @property-read WordPoints_Hook_Reaction_StorageI|null $network_reactions
29
 *                Object for accessing network hook reactions for this reactor. May
30
 *                not be available for all reactors.
31
 */
32
abstract class WordPoints_Hook_Reactor implements WordPoints_Hook_SettingsI {
33
34
	/**
35
	 * The unique slug identifying this hook reactor.
36
	 *
37
	 * @since 1.0.0
38
	 *
39
	 * @var string
40
	 */
41
	protected $slug;
42
43
	/**
44
	 * The types of args that this reactor can target.
45
	 *
46
	 * @since 1.0.0
47
	 *
48
	 * @var string|string[]
49
	 */
50
	protected $arg_types;
51
52
	/**
53
	 * The settings fields used by this reactor.
54
	 *
55
	 * @since 1.0.0
56
	 *
57
	 * @var array
58
	 */
59
	protected $settings_fields;
60
61
	/**
62
	 * The storage object for the standard reactions.
63
	 *
64
	 * @since 1.0.0
65
	 *
66
	 * @var WordPoints_Hook_Reaction_StorageI
67
	 */
68
	protected $standard_reactions;
69
70
	/**
71
	 * The storage object for the network-wide reactions.
72
	 *
73
	 * @since 1.0.0
74
	 *
75
	 * @var WordPoints_Hook_Reaction_StorageI
76
	 */
77
	protected $network_reactions;
78
79
	/**
80
	 * The reaction storage class this reactor uses.
81
	 *
82
	 * @since 1.0.0
83
	 *
84
	 * @var string
85
	 */
86
	protected $standard_reactions_class = 'WordPoints_Hook_Reaction_Storage_Options';
87
88
	/**
89
	 * The network reaction storage class this reactor uses.
90
	 *
91
	 * @since 1.0.0
92
	 *
93
	 * @var string
94
	 */
95
	protected $network_reactions_class = 'WordPoints_Hook_Reaction_Storage_Options_Network';
96
97
	/**
98
	 * @since 1.0.0
99
	 */
100
	public function __get( $var ) {
101
102
		if ( 'reactions' === $var ) {
103
			$mode = wordpoints_hooks()->get_current_mode();
104
			$var  = "{$mode}_reactions";
105
		} elseif ( '_reactions' !== substr( $var, -10 ) ) {
106
			return null;
107
		} else {
108
			$mode = substr( $var, 0, -10 /* _reactions */ );
109
		}
110
111
		if ( 'network_reactions' === $var && ! $this->is_network_wide() ) {
112
			return null;
113
		}
114
115
		if ( ! isset( $this->$var ) ) {
116
117
			if ( isset( $this->{"{$var}_class"} ) ) {
118
				$this->$var = new $this->{"{$var}_class"}( $mode, $this );
119
			} else {
120
				return null;
121
			}
122
		}
123
124
		$store = $this->$var;
125
126
		if ( ! $store instanceof WordPoints_Hook_Reaction_StorageI ) {
127
			return null;
128
		}
129
130
		// Allowing access to stores out-of-context would lead to strange behavior.
131
		if ( false === $store->get_context_id() ) {
132
			return null;
133
		}
134
135
		return $store;
136
	}
137
138
	/**
139
	 * Get the slug of this reactor.
140
	 *
141
	 * @since 1.0.0
142
	 *
143
	 * @return string The reactor's slug.
144
	 */
145
	public function get_slug() {
146
		return $this->slug;
147
	}
148
149
	/**
150
	 * Get a list of the slugs of each type of arg that this reactor supports.
151
	 *
152
	 * @since 1.0.0
153
	 *
154
	 * @return string[] The slugs of the arg types this reactor supports.
155
	 */
156
	public function get_arg_types() {
157
		return (array) $this->arg_types;
158
	}
159
160
	/**
161
	 * Get the settings fields used by the reactor.
162
	 *
163
	 * @since 1.0.0
164
	 *
165
	 * @return string[] The meta keys used to store this reactor's settings.
166
	 */
167
	public function get_settings_fields() {
168
		return $this->settings_fields;
169
	}
170
171
	/**
172
	 * Check whether this reactor is network-wide.
173
	 *
174
	 * When a reactor is not network-wide, network reactions are not supported. For
175
	 * example, the points reactor is not network-wide when WordPoints isn't network-
176
	 * active, because the points types are created per-site. We default all reactors
177
	 * to being network wide only when WordPoints is network-active, but some may
178
	 * need to override this.
179
	 *
180
	 * @since 1.0.0
181
	 *
182
	 * @return bool Whether this reactor is network-wide.
183
	 */
184
	public function is_network_wide() {
185
		return is_wordpoints_network_active();
186
	}
187
188
	/**
189
	 * Get all reactions to a particular event for this reactor.
190
	 *
191
	 * On multisite it will return all reactions for the current site, both standard
192
	 * ones and any network-wide ones (if this reactor offers a network storage
193
	 * class). Or, if network mode is on, it will return only the network-wide ones.
194
	 *
195
	 * @since 1.0.0
196
	 *
197
	 * @param string $event_slug The event slug.
198
	 *
199
	 * @return WordPoints_Hook_ReactionI[] All of the reaction objects.
200
	 */
201 View Code Duplication
	public function get_all_reactions_to_event( $event_slug ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
202
203
		$reactions = array();
204
205
		foreach ( array( 'standard', 'network' ) as $store ) {
206
207
			$storage = $this->{"{$store}_reactions"};
208
209
			if ( ! $storage instanceof WordPoints_Hook_Reaction_StorageI ) {
210
				continue;
211
			}
212
213
			$reactions = array_merge(
214
				$reactions
215
				, $storage->get_reactions_to_event( $event_slug )
216
			);
217
		}
218
219
		return $reactions;
220
	}
221
222
	/**
223
	 * Get all reactions for this reactor.
224
	 *
225
	 * On multisite it will return all reactions for the current site, both standard
226
	 * ones and any network-wide ones (if this reactor offers a network storage
227
	 * class). Or, if network mode is on, it will return only the network-wide ones.
228
	 *
229
	 * @since 1.0.0
230
	 *
231
	 * @return WordPoints_Hook_ReactionI[] All of the reaction objects.
232
	 */
233 View Code Duplication
	public function get_all_reactions() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
234
235
		$reactions = array();
236
237
		foreach ( array( 'standard', 'network' ) as $store ) {
238
239
			$storage = $this->{"{$store}_reactions"};
240
241
			if ( ! $storage instanceof WordPoints_Hook_Reaction_StorageI ) {
242
				continue;
243
			}
244
245
			$reactions = array_merge( $reactions, $storage->get_reactions() );
246
		}
247
248
		return $reactions;
249
	}
250
251
	/**
252
	 * @since 1.0.0
253
	 */
254
	public function validate_settings(
255
		array $settings,
256
		WordPoints_Hook_Reaction_Validator $validator,
257
		WordPoints_Hook_Event_Args $event_args
258
	) {
259
260
		if (
261
			empty( $settings['target'] )
262
			|| ! is_array( $settings['target'] )
263
		) {
264
265
			$validator->add_error( __( 'Invalid target.', 'wordpoints' ), 'target' );
266
267
		} else {
268
269
			$target = $event_args->get_from_hierarchy( $settings['target'] );
270
271
			if (
272
				! $target instanceof WordPoints_Entity
273
				|| ! in_array( $target->get_slug(), (array) $this->arg_types )
274
			) {
275
				$validator->add_error( __( 'Invalid target.', 'wordpoints' ), 'target' );
276
			}
277
		}
278
279
		return $settings;
280
	}
281
282
	/**
283
	 * @since 1.0.0
284
	 */
285
	public function update_settings( WordPoints_Hook_ReactionI $reaction, array $settings ) {
286
		$reaction->update_meta( 'target', $settings['target'] );
287
	}
288
289
	/**
290
	 * Perform an action when the reactor is hit by an event being fired.
291
	 *
292
	 * @since 1.0.0
293
	 *
294
	 * @param WordPoints_Hook_Event_Args $event_args The event args.
295
	 * @param WordPoints_Hook_ReactionI  $reaction   The reaction.
296
	 */
297
	abstract public function hit(
298
		WordPoints_Hook_Event_Args $event_args,
299
		WordPoints_Hook_ReactionI $reaction
300
	);
301
}
302
303
// EOF
304