Completed
Push — master ( 873ec4...144c08 )
by J.D.
03:34
created

functions.php ➔ wordpoints_hooks_api_admin_menu()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 2
eloc 12
nc 2
nop 0
dl 0
loc 21
rs 9.3142
1
<?php
2
3
/**
4
 * Administration side functions.
5
 *
6
 * @package wordpoints-hooks-api
7
 * @since 1.0.0
8
 */
9
10
/**
11
 * Register the admin apps when the main app is initialized.
12
 *
13
 * @since 1.0.0
14
 *
15
 * @WordPress\action wordpoints_init_app-apps
16
 *
17
 * @param WordPoints_App $app The main WordPoints app.
18
 */
19
function wordpoints_hooks_register_admin_apps( $app ) {
20
21
	$apps = $app->sub_apps;
22
23
	$apps->register( 'admin', 'WordPoints_App' );
24
25
	/** @var WordPoints_App $admin */
26
	$admin = $apps->get( 'admin' );
27
28
	$admin->sub_apps->register( 'screen', 'WordPoints_Admin_Screens' );
29
}
30
31
/**
32
 * Register the admin screens.
33
 *
34
 * @since 1.0.0
35
 *
36
 * @WordPress\action admin_menu
37
 * @WordPress\action network_admin_menu
38
 */
39
function wordpoints_hooks_api_admin_menu() {
40
41
	$wordpoints_menu = wordpoints_get_main_admin_menu();
42
43
	/** @var WordPoints_Admin_Screens $admin_screens */
44
	$admin_screens = wordpoints_apps()->admin->screen;
0 ignored issues
show
Documentation introduced by
The property admin does not exist on object<WordPoints_App>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
45
46
	// Hooks page.
47
	$id = add_submenu_page(
48
		$wordpoints_menu
49
		, __( 'WordPoints — Points Types', 'wordpoints' )
50
		, __( 'Points Types', 'wordpoints' )
51
		, 'manage_options'
52
		, 'wordpoints_points_types'
53
		, array( $admin_screens, 'display' )
54
	);
55
56
	if ( $id ) {
57
		$admin_screens->register( $id, 'WordPoints_Admin_Screen_Points_Types' );
58
	}
59
}
60
61
/**
62
 * Register module admin scripts.
63
 *
64
 * @since 1.0.0
65
 *
66
 * @WordPress\action admin_init
67
 */
68
function wordpoints_hooks_admin_register_scripts() {
69
70
	$assets_url = wordpoints_modules_url( '/assets', dirname( __FILE__ ) );
71
72
	// CSS
73
74
	wp_register_style(
75
		'wordpoints-hooks-admin'
76
		, $assets_url . '/css/hooks.css'
77
		, array( 'dashicons', 'wp-jquery-ui-dialog' )
78
		, WORDPOINTS_VERSION
79
	);
80
81
	// JS
82
83
	wp_register_script(
84
		'wordpoints-hooks-models'
85
		, $assets_url . '/js/hooks/models.js'
86
		, array( 'backbone', 'jquery-ui-dialog', 'wp-util' )
87
		, WORDPOINTS_VERSION
88
	);
89
90
	wp_register_script(
91
		'wordpoints-hooks-views'
92
		, $assets_url . '/js/hooks/views.js'
93
		, array( 'wordpoints-hooks-models' )
94
		, WORDPOINTS_VERSION
95
	);
96
97
	wp_localize_script(
98
		'wordpoints-hooks-views'
99
		, 'WordPointsHooksAdminL10n'
100
		, array(
101
			'unexpectedError' => __( 'There was an unexpected error. Try reloading the page.', 'wordpoints' ),
102
			'changesSaved'    => __( 'Your changes have been saved.', 'wordpoints' ),
103
			/* translators: the name of the field that cannot be empty */
104
			'emptyField'      => sprintf( __( '%s cannot be empty.', 'wordpoints' ), '{{ data.label }}' ),
105
			'confirmDelete'   => __( 'Are you sure that you want to delete this reaction? This action cannot be undone.', 'wordpoints' ),
106
			'confirmTitle'    => __( 'Are you sure?', 'wordpoints' ),
107
			'deleteText'      => __( 'Delete', 'wordpoints' ),
108
			'cancelText'      => __( 'Cancel', 'wordpoints' ),
109
			'separator'       => __( ' » ', 'wordpoints' ),
110
			'target_label'    => __( 'Target', 'wordpoints' ),
111
		)
112
	);
113
114
	wp_script_add_data(
115
		'wordpoints-hooks-views'
116
		, 'wordpoints-templates'
117
		, '
118
		<script type="text/template" id="tmpl-wordpoints-hook-reaction">
119
			<div class="view">
120
				<div class="title"></div>
121
				<button type="button" class="edit button-secondary">
122
					' . esc_html__( 'Edit', 'wordpoints' ) . '
123
				</button>
124
				<button type="button" class="close button-secondary">
125
					' . esc_html__( 'Close', 'wordpoints' ) . '
126
				</button>
127
			</div>
128
			<div class="form">
129
				<form>
130
					<div class="fields">
131
						<div class="settings"></div>
132
						<div class="target"></div>
133
					</div>
134
					<div class="messages">
135
						<div class="success"></div>
136
						<div class="err"></div>
137
					</div>
138
					<div class="actions">
139
						<div class="spinner-overlay">
140
							<span class="spinner is-active"></span>
141
						</div>
142
						<div class="action-buttons">
143
							<button type="button" class="save button-primary" disabled>
144
								' . esc_html__( 'Save', 'wordpoints' ) . '
145
							</button>
146
							<button type="button" class="cancel button-secondary">
147
								' . esc_html__( 'Cancel', 'wordpoints' ) . '
148
							</button>
149
							<button type="button" class="close button-secondary">
150
								' . esc_html__( 'Close', 'wordpoints' ) . '
151
							</button>
152
							<button type="button" class="delete button-secondary">
153
								' . esc_html__( 'Delete', 'wordpoints' ) . '
154
							</button>
155
						</div>
156
					</div>
157
				</form>
158
			</div>
159
		</script>
160
161
		<script type="text/template" id="tmpl-wordpoints-hook-arg-selector">
162
			<div class="arg-selector">
163
				<label>
164
					{{ data.label }}
165
					<select name="{{ data.name }}"></select>
166
				</label>
167
			</div>
168
		</script>
169
170
		<script type="text/template" id="tmpl-wordpoints-hook-arg-option">
171
			<option value="{{ data.slug }}">{{ data.title }}</option>
172
		</script>
173
174
		<script type="text/template" id="tmpl-wordpoints-hook-reaction-field">
175
			<p class="description description-thin">
176
				<label>
177
					{{ data.label }}
178
					<input type="{{ data.type }}" class="widefat" name="{{ data.name }}"
179
					       value="{{ data.value }}"/>
180
				</label>
181
			</p>
182
		</script>
183
184
		<script type="text/template" id="tmpl-wordpoints-hook-reaction-select-field">
185
			<p class="description description-thin">
186
				<label>
187
					{{ data.label }}
188
					<select name="{{ data.name }}" class="widefat"></select>
189
				</label>
190
			</p>
191
		</script>
192
193
		<script type="text/template" id="tmpl-wordpoints-hook-reaction-hidden-field">
194
			<input type="hidden" name="{{ data.name }}" value="{{ data.value }}"/>
195
		</script>
196
		'
197
	);
198
199
	wp_register_script(
200
		'wordpoints-hooks-reactor-points'
201
		, $assets_url . '/js/hooks/reactors/points.js'
202
		, array( 'wordpoints-hooks-views' )
203
		, WORDPOINTS_VERSION
204
	);
205
206
	wp_register_script(
207
		'wordpoints-hooks-extension-conditions'
208
		, $assets_url . '/js/hooks/extensions/conditions.js'
209
		, array( 'wordpoints-hooks-views' )
210
		, WORDPOINTS_VERSION
211
	);
212
213
	wp_script_add_data(
214
		'wordpoints-hooks-extension-conditions'
215
		, 'wordpoints-templates'
216
		, '
217
			<script type="text/template" id="tmpl-wordpoints-hook-condition-groups">
218
				<div class="conditions-title section-title">
219
					<h4>' . esc_html__( 'Conditions', 'wordpoints' ) . '</h4>
220
					<button type="button" class="add-new button-secondary button-link">
221
						<span class="screen-reader-text">' . esc_html__( 'Add New Condition', 'wordpoints' ) . '</span>
222
						<span class="dashicons dashicons-plus"></span>
223
					</button>
224
				</div>
225
				<div class="add-condition-form hidden">
226
					<div class="no-conditions hidden">
227
						' . esc_html__( 'No conditions available.', 'wordpoints' ) . '
228
					</div>
229
					<div class="condition-selectors">
230
						<div class="arg-selectors"></div>
231
						<div class="condition-selector"></div>
232
					</div>
233
					<button type="button" class="confirm-add-new button-secondary" disabled aria-label="' . esc_attr__( 'Add Condition', 'wordpoints' ) . '">
234
						' . esc_html_x( 'Add', 'reaction condition', 'wordpoints' ) . '
235
					</button>
236
					<button type="button" class="cancel-add-new button-secondary" aria-label="' . esc_attr__( 'Cancel Adding New Condition', 'wordpoints' ) . '">
237
						' . esc_html_x( 'Cancel', 'reaction condition', 'wordpoints' ) . '
238
					</button>
239
				</div>
240
				<div class="condition-groups section-content"></div>
241
			</script>
242
243
			<script type="text/template" id="tmpl-wordpoints-hook-reaction-condition-group">
244
				<div class="condition-group-title"></div>
245
			</script>
246
247
			<script type="text/template" id="tmpl-wordpoints-hook-reaction-condition">
248
				<div class="condition-controls">
249
					<div class="condition-title"></div>
250
					<button type="button" class="delete button-secondary button-link">
251
						<span class="screen-reader-text">' . esc_html__( 'Remove Condition', 'wordpoints' ) . '</span>
252
						<span class="dashicons dashicons-no"></span>
253
					</button>
254
				</div>
255
				<div class="condition-settings"></div>
256
			</script>
257
258
			<script type="text/template" id="tmpl-wordpoints-hook-condition-selector">
259
				<label>
260
					{{ data.label }}
261
					<select name="{{ data.name }}"></select>
262
				</label>
263
			</script>
264
		'
265
	);
266
267
	wp_register_script(
268
		'wordpoints-hooks-extension-periods'
269
		, $assets_url . '/js/hooks/extensions/periods.js'
270
		, array( 'wordpoints-hooks-views' )
271
		, WORDPOINTS_VERSION
272
	);
273
274
	wp_script_add_data(
275
		'wordpoints-hooks-extension-periods'
276
		, 'wordpoints-templates'
277
		, '
278
			<script type="text/template" id="tmpl-wordpoints-hook-periods">
279
				<div class="periods-title section-title">
280
					<h4>' . esc_html__( 'Rate Limit', 'wordpoints' ) . '</h4>
281
				</div>
282
				<div class="periods section-content"></div>
283
			</script>
284
		'
285
	);
286
}
287
288
/**
289
 * Export the data for the scripts needed to make the hooks UI work.
290
 *
291
 * @since 1.0.0
292
 */
293
function wordpoints_hooks_ui_setup_script_data() {
294
295
	$hooks = wordpoints_hooks();
296
297
	$event_index = $hooks->router->get_event_index();
298
	$event_index = call_user_func_array( 'array_merge_recursive', $event_index );
299
300
	$event_action_types = array();
301
302
	foreach ( $event_index as $action_type => $events ) {
303
		$event_action_types = array_merge_recursive(
304
			$event_action_types
305
			, array_fill_keys( array_keys( $events ), array( $action_type ) )
306
		);
307
	}
308
309
	$extensions_data = array();
310
311
	foreach ( $hooks->extensions->get_all() as $slug => $extension ) {
312
313
		if ( $extension instanceof WordPoints_Hook_Extension ) {
314
			$extensions_data[ $slug ] = $extension->get_ui_script_data();
315
		}
316
317
		if ( wp_script_is( "wordpoints-hooks-extension-{$slug}", 'registered' ) ) {
318
			wp_enqueue_script( "wordpoints-hooks-extension-{$slug}" );
319
		}
320
	}
321
322
	$action_types = $hooks->router->get_reactor_index();
323
324
	$reactor_data = array();
325
326
	foreach ( $hooks->reactors->get_all() as $slug => $reactor ) {
327
328
		if ( $reactor instanceof WordPoints_Hook_Reactor ) {
329
			$reactor_data[ $slug ] = $reactor->get_ui_script_data();
330
		}
331
332
		$reactor_data[ $slug ]['action_types'] = $action_types[ $slug ];
333
334
		if ( wp_script_is( "wordpoints-hooks-reactor-{$slug}", 'registered' ) ) {
335
			wp_enqueue_script( "wordpoints-hooks-reactor-{$slug}" );
336
		}
337
	}
338
339
	$entities = wordpoints_entities();
340
341
	$entities_data = array();
342
343
	/** @var WordPoints_Class_Registry_Children $entity_children */
344
	$entity_children = $entities->children;
0 ignored issues
show
Documentation introduced by
The property children does not exist on object<WordPoints_App_Registry>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
345
346
	/** @var WordPoints_Entity $entity */
347
	foreach ( $entities->get_all() as $slug => $entity ) {
348
349
		$child_data = array();
350
351
		/** @var WordPoints_EntityishI $child */
352
		foreach ( $entity_children->get_children( $slug ) as $child_slug => $child ) {
353
354
			$child_data[ $child_slug ] = array(
355
				'slug'  => $child_slug,
356
				'title' => $child->get_title(),
357
			);
358
359
			if ( $child instanceof WordPoints_Entity_Attr ) {
360
361
				$child_data[ $child_slug ]['_type'] = 'attr';
362
				$child_data[ $child_slug ]['data_type']  = $child->get_data_type();
363
364
			} elseif ( $child instanceof WordPoints_Entity_Relationship ) {
365
366
				$child_data[ $child_slug ]['_type']     = 'relationship';
367
				$child_data[ $child_slug ]['primary']   = $child->get_primary_entity_slug();
368
				$child_data[ $child_slug ]['secondary'] = $child->get_related_entity_slug();
369
			}
370
371
			/**
372
			 * Filter the data for an entity child.
373
			 *
374
			 * Entity children include attributes and relationships.
375
			 *
376
			 * @param array                $data  The data for the entity child.
377
			 * @param WordPoints_Entityish $child The child's object.
378
			 */
379
			$child_data[ $child_slug ] = apply_filters( 'wordpoints_hooks_ui_data_entity_child', $child_data[ $child_slug ], $child );
380
		}
381
382
		$entities_data[ $slug ] = array(
383
			'slug'     => $slug,
384
			'title'    => $entity->get_title(),
385
			'children' => $child_data,
386
			'id_field' => $entity->get_id_field(),
387
			'_type'    => 'entity',
388
		);
389
390
		if ( $entity instanceof WordPoints_Entity_EnumerableI ) {
391
392
			$values = array();
393
394
			foreach ( $entity->get_enumerated_values() as $value ) {
395
				if ( $entity->set_the_value( $value ) ) {
396
					$values[] = array(
397
						'value' => $entity->get_the_id(),
398
						'label' => $entity->get_the_human_id(),
399
					);
400
				}
401
			}
402
403
			$entities_data[ $slug ]['values'] = $values;
404
		}
405
406
		/**
407
		 * Filter the data for an entity.
408
		 *
409
		 * @param array             $data   The data for the entity.
410
		 * @param WordPoints_Entity $entity The entity object.
411
		 */
412
		$entities_data[ $slug ] = apply_filters( 'wordpoints_hooks_ui_data_entity', $entities_data[ $slug ], $entity );
413
	}
414
415
	$data = array(
416
		'fields'     => (object) array(),
417
		'reactions'  => (object) array(),
418
		'events'     => (object) array(),
419
		'extensions' => $extensions_data,
420
		'entities'   => $entities_data,
421
		'reactors'   => $reactor_data,
422
		'action_types' => $event_action_types,
423
	);
424
425
	/**
426
	 * Filter the hooks data used to provide the UI.
427
	 *
428
	 * This is currently exported as JSON to the Backbone.js powered UI. But
429
	 * that could change in the future. The important thing is that the data is
430
	 * bing exported and will be used by something somehow.
431
	 *
432
	 * @param array $data The data.
433
	 */
434
	$data = apply_filters( 'wordpoints_hooks_ui_data', $data );
435
436
	wp_localize_script(
437
		'wordpoints-hooks-models'
438
		, 'WordPointsHooksAdminData'
439
		, $data
440
	);
441
}
442
443
/**
444
 * Append templates registered in wordpoints-templates script data to scripts.
445
 *
446
 * One day templates will probably be stored in separate files instead.
447
 *
448
 * @link https://core.trac.wordpress.org/ticket/31281
449
 *
450
 * @since 1.0.0
451
 *
452
 * @WordPress\filter script_loader_tag
453
 *
454
 * @param string $html   The HTML for the script.
455
 * @param string $handle The handle of the script.
456
 *
457
 * @return string The HTML with templates appended.
458
 */
459
function wordpoints_script_templates_filter( $html, $handle ) {
460
461
	global $wp_scripts;
462
463
	$templates = $wp_scripts->get_data( $handle, 'wordpoints-templates' );
464
465
	if ( $templates ) {
466
		$html .= $templates;
467
	}
468
469
	return $html;
470
}
471
472
/**
473
 * Initialize the Ajax actions.
474
 *
475
 * @since 1.0.0
476
 *
477
 * @WordPress\action admin_init
478
 */
479
function wordpoints_hooks_admin_ajax() {
480
481
	if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
482
		new WordPoints_Admin_Ajax_Hooks;
483
	}
484
}
485
486
// EOF
487