Completed
Push — master ( 722949...84d505 )
by J.D.
27:47 queued 26:57
created

WordPoints_Hook_Reactor::__get()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 16
rs 9.4285
cc 3
eloc 8
nc 3
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
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 ) {
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...
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() {
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...
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