WordPoints_Points_Hooks   F
last analyzed

Complexity

Total Complexity 66

Size/Duplication

Total Lines 735
Duplicated Lines 2.04 %

Importance

Changes 0
Metric Value
dl 15
loc 735
rs 2.5531
c 0
b 0
f 0
wmc 66

19 Methods

Rating   Name   Duplication   Size   Complexity  
F points_type_form() 15 160 13
A get_defaults() 0 10 2
A initialize_hooks() 0 23 2
A get_points_type() 0 10 3
A get_points_type_hooks() 0 11 3
A get_handlers() 0 3 1
A sort_name_callback() 0 3 1
A set_network_mode() 0 4 2
A get_handler() 0 21 4
B list_hooks() 0 40 4
A register() 0 3 1
B list_by_points_type() 0 29 5
C uninstall_hook_types() 0 29 7
A init() 0 2 1
A get_network_mode() 0 3 1
C list_hook() 0 95 11
A get_handler_by_id_base() 0 7 2
A get_points_types_hooks() 0 5 1
A save_points_types_hooks() 0 6 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like WordPoints_Points_Hooks often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WordPoints_Points_Hooks, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * WordPoints_Points_Hooks class.
5
 *
6
 * This is a static class to help with points hooks.
7
 *
8
 * @package WordPoints\Points\Hooks
9
 * @since 1.0.0
10
 */
11
12
/**
13
 * Points hooks class.
14
 *
15
 * This is a static helper class to handle the storing of points hooks.
16
 *
17
 * The points hook API is based on WordPress's Widget API. There are different
18
 * types of points hooks (their widget API counterpart would be the widgets), and
19
 * each type is represented by a class. There may be  multiple instances of each type
20
 * of hook, and the class or "handler" for that hook type is used to save, update,
21
 * and trigger instances of that type of hook. Each instance of a hook is associated
22
 * with one of the points types (kind of like sidebars).
23
 *
24
 * This class provides an API to get the handler for a type of hook. It also provides
25
 * methods to get a list of hooks by what points type they are attached to, as well
26
 * as to determine to which points type a particular instance of a hook is attached.
27
 *
28
 * The first of the two (the handler API) works like this:
29
 *
30
 * Each points hook type's class is registered with self::register(). Later, after
31
 * any modules are loaded, self::initialize_hooks() instantiates each of the classes.
32
 * A list of the hook types and the handler (class object) for each is saved in
33
 * self::$hook_types when this occurs. This allows for the handler for a type of hook
34
 * to be easily retrieved, using the provided methods. This is necessary for saving,
35
 * updating, and deleting instances of a hook, as these actions must be performed by
36
 * the handler for that hook type.
37
 *
38
 * The latter (the points types API) works like this:
39
 *
40
 * Each hook instance is assigned a unique ID (this is handled by the handlers, i.e.
41
 * the WordPoints_Points_Hook class). A multidemensional array of hook instances,
42
 * indexed by points type, is maintained in the database. Checking this list is
43
 * currently the only means of determining what type of points a hook instance is
44
 * supposed to award. Several methods are provided for working with this list, and
45
 * these should always be used rather than accessing or altering it in the database
46
 * directly.
47
 *
48
 * For more information on how the handler for a type of hook actually awards the
49
 * points for each of its instances, see the docs for the WordPoints_Points_Hook
50
 * class.
51
 *
52
 * @since 1.0.0
53
 */
54
final class WordPoints_Points_Hooks {
55
56
	//
57
	// Private Vars.
58
	//
59
60
	/**
61
	 * A list of registered hook type class names.
62
	 *
63
	 * Holds the list of classes registered with the self::register() method,
64
	 * accessed only by self::initialize_hooks().
65
	 *
66
	 * @since 1.5.0
67
	 *
68
	 * @param string[] $classes
69
	 */
70
	private static $classes;
71
72
	/**
73
	 * The instances of the handlers for the registered types of points hooks.
74
	 *
75
	 * @since 1.5.0
76
	 *
77
	 * @type WordPoints_Points_Hook[] $hook_types
78
	 */
79
	private static $hook_types = array();
80
81
	/**
82
	 * Whether to display network hooks.
83
	 *
84
	 * @since 1.2.0
85
	 *
86
	 * @type bool $network_mode
87
	 */
88
	private static $network_mode = false;
89
90
	//
91
	// Public Methods.
92
	//
93
94
	/**
95
	 * Initialize the class.
96
	 *
97
	 * @since 1.0.0
98
	 * @deprecated 2.1.0
99
	 */
100
	public static function init() {
101
		_deprecated_function( __METHOD__, '2.1.0' );
0 ignored issues
show
Bug introduced by
The function _deprecated_function was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

101
		/** @scrutinizer ignore-call */ 
102
  _deprecated_function( __METHOD__, '2.1.0' );
Loading history...
102
	}
103
104
	/**
105
	 * Register a points hook type's handler class.
106
	 *
107
	 * @since 1.0.0
108
	 *
109
	 * @param string $class_name A 'WordPoints_Points_Hook' class name.
110
	 */
111
	public static function register( $class_name ) {
112
113
		self::$classes[] = $class_name;
114
	}
115
116
	/**
117
	 * Register all points hooks.
118
	 *
119
	 * @since 1.0.0
120
	 *
121
	 * @action wordpoints_extensions_loaded Added by the init() method.
122
	 */
123
	public static function initialize_hooks() {
124
125
		/**
126
		 * Points hooks may be registered on this action.
127
		 *
128
		 * @since 1.4.0
129
		 */
130
		do_action( 'wordpoints_points_hooks_register' );
0 ignored issues
show
Bug introduced by
The function do_action was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

130
		/** @scrutinizer ignore-call */ 
131
  do_action( 'wordpoints_points_hooks_register' );
Loading history...
131
132
		$classes = array_unique( self::$classes );
133
134
		foreach ( $classes as $class_name ) {
135
136
			$hook_type = new $class_name();
137
			self::$hook_types[ $hook_type->get_id_base() ] = $hook_type;
138
		}
139
140
		/**
141
		 * All points hooks registered and initialized.
142
		 *
143
		 * @since 1.0.0
144
		 */
145
		do_action( 'wordpoints_points_hooks_registered' );
146
	}
147
148
	/**
149
	 * Get a list of registered points hook handlers.
150
	 *
151
	 * @since 1.5.0
152
	 *
153
	 * @return WordPoints_Points_Hook[] The registered points hook types.
154
	 */
155
	public static function get_handlers() {
156
157
		return self::$hook_types;
158
	}
159
160
	/**
161
	 * Get the object representing the hook type of a hook by its ID.
162
	 *
163
	 * @since 1.0.0
164
	 *
165
	 * @param string $hook_id The unique ID of the hook to get the handler for.
166
	 *
167
	 * @return WordPoints_Points_Hook|false The hook object, or false for invalid ID.
168
	 */
169
	public static function get_handler( $hook_id ) {
170
171
		list( $hook_type, $id_number ) = explode( '-', $hook_id );
172
173
		$hook_type = self::get_handler_by_id_base( $hook_type );
174
175
		if ( false === $hook_type ) {
176
			return false;
177
		}
178
179
		$type = ( self::$network_mode ) ? 'network' : 'standard';
180
181
		$instances = $hook_type->get_instances( $type );
182
183
		if ( ! isset( $instances[ $id_number ] ) ) {
184
			return false;
185
		}
186
187
		$hook_type->set_number( $id_number );
188
189
		return $hook_type;
190
	}
191
192
	/**
193
	 * Get the handler object for a hook by id_base (hook type).
194
	 *
195
	 * This is used to get the handler for a new hook instance so that it can be
196
	 * created.
197
	 *
198
	 * @since 1.0.0
199
	 *
200
	 * @param string $id_base The basic identifier the type of hook.
201
	 *
202
	 * @return WordPoints_Points_Hook|false False if no handler found.
203
	 */
204
	public static function get_handler_by_id_base( $id_base ) {
205
206
		if ( ! isset( self::$hook_types[ $id_base ] ) ) {
207
			return false;
208
		}
209
210
		return self::$hook_types[ $id_base ];
211
	}
212
213
	/**
214
	 * Delete the database data for a list of hook types.
215
	 *
216
	 * @since 1.7.0
217
	 * @deprecated 2.0.0 Use an un/installer class instead.
218
	 *
219
	 * @param array|string $hook_types The hook type(s) to uninstall.
220
	 * @param int[]        $site_ids   List of site IDs where this hook type is
221
	 *                                 installed. Only needed if on multisite. If
222
	 *                                 omitted, the current site ID is used.
223
	 */
224
	public static function uninstall_hook_types( $hook_types, array $site_ids = null ) {
225
226
		_deprecated_function( __METHOD__, '2.0.0', 'WordPoints_Un_Installer_Base::$uninstall' );
0 ignored issues
show
Bug introduced by
The function _deprecated_function was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

226
		/** @scrutinizer ignore-call */ 
227
  _deprecated_function( __METHOD__, '2.0.0', 'WordPoints_Un_Installer_Base::$uninstall' );
Loading history...
227
228
		$hook_types = (array) $hook_types;
229
230
		if ( is_multisite() ) {
0 ignored issues
show
Bug introduced by
The function is_multisite was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

230
		if ( /** @scrutinizer ignore-call */ is_multisite() ) {
Loading history...
231
232
			foreach ( $hook_types as $hook_type ) {
233
				delete_site_option( "wordpoints_hook-{$hook_type}" );
0 ignored issues
show
Bug introduced by
The function delete_site_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

233
				/** @scrutinizer ignore-call */ 
234
    delete_site_option( "wordpoints_hook-{$hook_type}" );
Loading history...
234
			}
235
236
			if ( ! isset( $site_ids ) ) {
237
				$site_ids = array( get_current_blog_id() );
0 ignored issues
show
Bug introduced by
The function get_current_blog_id was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

237
				$site_ids = array( /** @scrutinizer ignore-call */ get_current_blog_id() );
Loading history...
238
			}
239
240
			foreach ( $site_ids as $site_id ) {
241
242
				switch_to_blog( $site_id );
0 ignored issues
show
Bug introduced by
The function switch_to_blog was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

242
				/** @scrutinizer ignore-call */ 
243
    switch_to_blog( $site_id );
Loading history...
243
				foreach ( $hook_types as $hook_type ) {
244
					delete_option( "wordpoints_hook-{$hook_type}" );
0 ignored issues
show
Bug introduced by
The function delete_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

244
					/** @scrutinizer ignore-call */ 
245
     delete_option( "wordpoints_hook-{$hook_type}" );
Loading history...
245
				}
246
				restore_current_blog();
0 ignored issues
show
Bug introduced by
The function restore_current_blog was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

246
				/** @scrutinizer ignore-call */ 
247
    restore_current_blog();
Loading history...
247
			}
248
249
		} else {
250
251
			foreach ( $hook_types as $hook_type ) {
252
				delete_option( "wordpoints_hook-{$hook_type}" );
253
			}
254
		}
255
	}
256
257
	/**
258
	 * Displays a list of available hooks for the Points Hooks administration panel.
259
	 *
260
	 * @since 1.0.0
261
	 *
262
	 * @uses WordPoints_Points_Hooks::sort_name_callback()
263
	 * @uses WordPoints_Points_Hooks::list_hook()
264
	 */
265
	public static function list_hooks() {
266
267
		// Sort the hooks by name.
268
		$hook_types = self::$hook_types;
269
		uasort( $hook_types, array( __CLASS__, 'sort_name_callback' ) );
270
271
		$disabled_hooks = wordpoints_get_maybe_network_array_option(
272
			'wordpoints_legacy_points_hooks_disabled'
273
			, is_network_admin()
0 ignored issues
show
Bug introduced by
The function is_network_admin was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

273
			, /** @scrutinizer ignore-call */ is_network_admin()
Loading history...
274
		);
275
276
		$i = 0;
277
278
		// Display a representative for each hook type.
279
		foreach ( $hook_types as $id_base => $hook_type ) {
280
281
			if ( isset( $disabled_hooks[ $id_base ] ) ) {
282
				continue;
283
			}
284
285
			$i++;
286
287
			$args = $hook_type->get_options();
288
289
			$args['_add']       = 'multi';
290
			$args['_display']   = 'template';
291
			$args['_multi_num'] = $hook_type->next_hook_id_number();
292
			$args['_id_slug']   = $i;
293
294
			$hook_type->set_options( $args );
295
296
			self::list_hook( $hook_type->get_id( 0 ), $hook_type );
297
		}
298
299
		// If there were none, give the user a message.
300
		if ( empty( $hook_types ) ) {
301
302
			echo '<div class="wordpoints-no-hooks">'
303
				. esc_html__( 'There are no points hooks currently available.', 'wordpoints' )
0 ignored issues
show
Bug introduced by
The function esc_html__ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

303
				. /** @scrutinizer ignore-call */ esc_html__( 'There are no points hooks currently available.', 'wordpoints' )
Loading history...
304
				. '</div>';
305
		}
306
	}
307
308
	/**
309
	 * Display hooks by points type.
310
	 *
311
	 * @since 1.0.0
312
	 * @since 1.2.0 Now displays only the forms for the hooks, not the points type.
313
	 *
314
	 * @uses wordpoints_is_points_type()   To check if $slug is valid.
315
	 * @uses self::get_points_type_hooks() To get all hooks for this points type.
316
	 *
317
	 * @param string $slug The slug of the points type to display the hooks for.
318
	 *
319
	 * @return void
320
	 */
321
	public static function list_by_points_type( $slug ) {
322
323
		if ( '_inactive_hooks' !== $slug && ! wordpoints_is_points_type( $slug ) ) {
324
			return;
325
		}
326
327
		$points_type_hooks = self::get_points_type_hooks( $slug );
328
329
		foreach ( $points_type_hooks as $hook_id ) {
330
331
			list( $hook_type ) = explode( '-', $hook_id );
332
333
			$hook_type = self::get_handler_by_id_base( $hook_type );
0 ignored issues
show
Bug introduced by
$hook_type of type false|WordPoints_Points_Hook is incompatible with the type string expected by parameter $id_base of WordPoints_Points_Hooks::get_handler_by_id_base(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

333
			$hook_type = self::get_handler_by_id_base( /** @scrutinizer ignore-type */ $hook_type );
Loading history...
334
335
			if ( false === $hook_type ) {
336
				continue;
337
			}
338
339
			$options = $hook_type->get_options();
340
341
			$options['_display'] = 'instance';
342
343
			unset( $options['_add'] );
344
345
			$options['_id_slug'] = $slug;
346
347
			$hook_type->set_options( $options );
348
349
			self::list_hook( $hook_id, $hook_type, $slug );
350
		}
351
	}
352
353
	/**
354
	 * Set network mode.
355
	 *
356
	 * When network mode is on, the network-wide hooks will be displayed. This is
357
	 * only relevant on multisite installs.
358
	 *
359
	 * Network mode is off by default.
360
	 *
361
	 * @since 1.2.0
362
	 *
363
	 * @param bool $on Whether to turn network mode on or off.
364
	 */
365
	public static function set_network_mode( $on ) {
366
367
		if ( $on !== self::$network_mode ) {
368
			self::$network_mode = (bool) $on;
369
		}
370
	}
371
372
	/**
373
	 * Get the network mode.
374
	 *
375
	 * @see WordPoints_Points_Hooks::set_network_mode()
376
	 *
377
	 * @since 1.2.0
378
	 *
379
	 * @return bool Whether network mode is on.
380
	 */
381
	public static function get_network_mode() {
382
383
		return self::$network_mode;
384
	}
385
386
	/**
387
	 * Retrieve full list of points types and their hooks.
388
	 *
389
	 * @since 1.0.0
390
	 *
391
	 * @return array
392
	 */
393
	public static function get_points_types_hooks() {
394
395
		return wordpoints_get_maybe_network_array_option(
396
			'wordpoints_points_types_hooks'
397
			, self::$network_mode
398
		);
399
	}
400
401
	/**
402
	 * Retrieve the hooks for a points type.
403
	 *
404
	 * @since 1.0.0
405
	 *
406
	 * @uses WordPoints_Points_Hooks::get_points_types_hooks()
407
	 * @param string $slug The slug for the points type.
408
	 *
409
	 * @return array
410
	 */
411
	public static function get_points_type_hooks( $slug ) {
412
413
		$points_types_hooks = self::get_points_types_hooks();
414
415
		if ( isset( $points_types_hooks[ $slug ] ) && is_array( $points_types_hooks[ $slug ] ) ) {
416
			$points_type_hooks = $points_types_hooks[ $slug ];
417
		} else {
418
			$points_type_hooks = array();
419
		}
420
421
		return $points_type_hooks;
422
	}
423
424
	/**
425
	 * Save a full list of points types and their hooks.
426
	 *
427
	 * @since 1.0.0
428
	 *
429
	 * @param array $points_types_hooks The list of points types and their hooks.
430
	 */
431
	public static function save_points_types_hooks( array $points_types_hooks ) {
432
433
		if ( self::$network_mode ) {
434
			update_site_option( 'wordpoints_points_types_hooks', $points_types_hooks );
0 ignored issues
show
Bug introduced by
The function update_site_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

434
			/** @scrutinizer ignore-call */ 
435
   update_site_option( 'wordpoints_points_types_hooks', $points_types_hooks );
Loading history...
435
		} else {
436
			update_option( 'wordpoints_points_types_hooks', $points_types_hooks );
0 ignored issues
show
Bug introduced by
The function update_option was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

436
			/** @scrutinizer ignore-call */ 
437
   update_option( 'wordpoints_points_types_hooks', $points_types_hooks );
Loading history...
437
		}
438
	}
439
440
	/**
441
	 * Retrieve points type by hook ID.
442
	 *
443
	 * @since 1.0.0
444
	 *
445
	 * @param string $hook_id The ID of the hook.
446
	 *
447
	 * @return string|false The points type for the hook. False if not found.
448
	 */
449
	public static function get_points_type( $hook_id ) {
450
451
		foreach ( self::get_points_types_hooks() as $points_type => $hooks ) {
452
453
			if ( in_array( $hook_id, $hooks, true ) ) {
454
				return $points_type;
455
			}
456
		}
457
458
		return false;
459
	}
460
461
	/**
462
	 * Retrieve empty settings for hooks.
463
	 *
464
	 * @since 1.0.0
465
	 *
466
	 * @return array[] An array of empty arrays indexed by points type slugs.
467
	 */
468
	public static function get_defaults() {
469
470
		$defaults = array();
471
472
		foreach ( wordpoints_get_points_types() as $slug => $settings ) {
473
474
			$defaults[ $slug ] = array();
475
		}
476
477
		return $defaults;
478
	}
479
480
	/**
481
	 * Display a settings form for a type of points.
482
	 *
483
	 * By default, this function wraps the form in a widget like container. To over-
484
	 * ride this, the seccond parameter may be set to 'none'. If $slug is not set,
485
	 * $wrap will always be 'none'. If the inputs should be wrapped only in a form
486
	 * and the .hook-content div, then $wrap may be set to 'hook-content'.
487
	 *
488
	 * @since 1.0.0
489
	 * @deprecated 2.1.0
490
	 *
491
	 * @uses do_action() Calls 'wordpoints_points_type_form_top' at the top of the
492
	 *       settings form with $slug and $settings. A null slug indicated a new
493
	 *       points type is being added. Calls 'wordpoints_points_type_form_bottom'
494
	 *       at the bottom of the form, with the same values.
495
	 *
496
	 * @param string $slug The slug for this type of points.
497
	 * @param string $wrap Whether to wrap the form inputs in a "widget" or not.
498
	 */
499
	public static function points_type_form( $slug = null, $wrap = 'hook' ) {
500
501
		_deprecated_function(
0 ignored issues
show
Bug introduced by
The function _deprecated_function was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

501
		/** @scrutinizer ignore-call */ 
502
  _deprecated_function(
Loading history...
502
			__METHOD__
503
			, '2.1.0'
504
			, 'Only the Points Types screen should be used to manage points types.'
505
		);
506
507
		$add_new = 0;
508
509
		$points_type = wordpoints_get_points_type( $slug );
510
511
		if ( ! $points_type ) {
512
513
			$points_type = array();
514
			$add_new     = wp_create_nonce( 'wordpoints_add_new_points_type' );
0 ignored issues
show
Bug introduced by
The function wp_create_nonce was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

514
			$add_new     = /** @scrutinizer ignore-call */ wp_create_nonce( 'wordpoints_add_new_points_type' );
Loading history...
515
		}
516
517
		$points_type = array_merge(
518
			array(
519
				'name'   => '',
520
				'prefix' => '',
521
				'suffix' => '',
522
			)
523
			, $points_type
524
		);
525
526
		if ( ! isset( $slug ) && 'hook' === $wrap ) {
527
			$wrap = 'hook-content';
528
		}
529
530
		switch ( $wrap ) {
531
532
			case 'hook':
533
				$hook_wrap         = true;
534
				$hook_content_wrap = true;
535
			break;
536
537
			case 'hook-content':
538
				$hook_wrap         = false;
539
				$hook_content_wrap = true;
540
			break;
541
542
			default:
543
				$hook_wrap         = false;
544
				$hook_content_wrap = false;
545
		}
546
547
		?>
548
549
		<?php if ( $hook_wrap ) : ?>
550
			<div class="hook points-settings">
551
				<div class="hook-top">
552
					<div class="hook-title-action">
553
						<a class="hook-action hide-if-no-js" href="#available-hooks"></a>
554
					</div>
555
					<div class="hook-title"><h3><?php esc_html_e( 'Settings', 'wordpoints' ); ?><span class="in-hook-title"></span></h3></div>
0 ignored issues
show
Bug introduced by
The function esc_html_e was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

555
					<div class="hook-title"><h3><?php /** @scrutinizer ignore-call */ esc_html_e( 'Settings', 'wordpoints' ); ?><span class="in-hook-title"></span></h3></div>
Loading history...
556
				</div>
557
558
				<div class="hook-inside">
559
		<?php endif; ?>
560
561
			<?php if ( $hook_content_wrap ) : ?>
562
				<form method="post">
563
					<div class="hook-content">
564
			<?php endif; ?>
565
566
						<?php if ( $slug ) : ?>
0 ignored issues
show
Bug Best Practice introduced by
The expression $slug of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
567
						<p><span class="wordpoints-points-slug"><em><?php esc_html_e( 'Slug', 'wordpoints' ); ?>: <?php echo esc_html( $slug ); ?></em></span></p>
0 ignored issues
show
Bug introduced by
The function esc_html was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

567
						<p><span class="wordpoints-points-slug"><em><?php esc_html_e( 'Slug', 'wordpoints' ); ?>: <?php echo /** @scrutinizer ignore-call */ esc_html( $slug ); ?></em></span></p>
Loading history...
568
						<?php endif; ?>
569
570
						<?php
571
572
						/**
573
						 * At the top of the points type settings form.
574
						 *
575
						 * Called before the default inputs are displayed.
576
						 *
577
						 * @since 1.0.0
578
						 *
579
						 * @param string $points_type The slug of the points type.
580
						 */
581
						do_action( 'wordpoints_points_type_form_top', $slug );
0 ignored issues
show
Bug introduced by
The function do_action was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

581
						/** @scrutinizer ignore-call */ 
582
      do_action( 'wordpoints_points_type_form_top', $slug );
Loading history...
582
583 View Code Duplication
						if ( 'hook-content' === $wrap ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
584
585
							// Mark the prefix and suffix optional on the add new form.
586
							$prefix = _x( 'Prefix (optional):', 'points type', 'wordpoints' );
0 ignored issues
show
Bug introduced by
The function _x was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

586
							$prefix = /** @scrutinizer ignore-call */ _x( 'Prefix (optional):', 'points type', 'wordpoints' );
Loading history...
587
							$suffix = _x( 'Suffix (optional):', 'points type', 'wordpoints' );
588
589
						} else {
590
591
							$prefix = _x( 'Prefix:', 'points type', 'wordpoints' );
592
							$suffix = _x( 'Suffix:', 'points type', 'wordpoints' );
593
						}
594
595
						?>
596
597
						<p>
598
							<label for="points-name-<?php echo esc_attr( $slug ); ?>"><?php echo esc_html_x( 'Name:', 'points type', 'wordpoints' ); ?></label>
0 ignored issues
show
Bug introduced by
The function esc_html_x was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

598
							<label for="points-name-<?php echo esc_attr( $slug ); ?>"><?php echo /** @scrutinizer ignore-call */ esc_html_x( 'Name:', 'points type', 'wordpoints' ); ?></label>
Loading history...
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

598
							<label for="points-name-<?php echo /** @scrutinizer ignore-call */ esc_attr( $slug ); ?>"><?php echo esc_html_x( 'Name:', 'points type', 'wordpoints' ); ?></label>
Loading history...
599
							<input class="widefat" type="text" id="points-name-<?php echo esc_attr( $slug ); ?>" name="points-name" value="<?php echo esc_attr( $points_type['name'] ); ?>" />
600
						</p>
601
						<p>
602
							<label for="points-prefix-<?php echo esc_attr( $slug ); ?>"><?php echo esc_html( $prefix ); ?></label>
603
							<input class="widefat" type="text" id="points-prefix-<?php echo esc_attr( $slug ); ?>" name="points-prefix" value="<?php echo esc_attr( $points_type['prefix'] ); ?>" />
604
						</p>
605
						<p>
606
							<label for="points-suffix-<?php echo esc_attr( $slug ); ?>"><?php echo esc_html( $suffix ); ?></label>
607
							<input class="widefat" type="text" id="points-suffix-<?php echo esc_attr( $slug ); ?>" name="points-suffix" value="<?php echo esc_attr( $points_type['suffix'] ); ?>" />
608
						</p>
609
610
						<?php
611
612
						/**
613
						 * At the bottom of the points type settings form.
614
						 *
615
						 * Called below the default inputs, but abouve the submit buttons.
616
						 *
617
						 * @since 1.0.0
618
						 *
619
						 * @param string $points_type The slug of the points type.
620
						 */
621
						do_action( 'wordpoints_points_type_form_bottom', $slug );
622
623
						?>
624
625
			<?php if ( $hook_content_wrap ) : ?>
626
					</div>
627
628
					<input type="hidden" name="points-slug" value="<?php echo esc_attr( $slug ); ?>" />
629
					<input type="hidden" name="add_new" class="add_new" value="<?php echo esc_attr( $add_new ); ?>" />
630
631
					<div class="hook-control-actions">
632
						<div class="alignleft">
633
							<?php
634
635 View Code Duplication
							if ( ! $add_new ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
636
								wp_nonce_field( "wordpoints_delete_points_type-{$slug}", 'delete-points-type-nonce' );
0 ignored issues
show
Bug introduced by
The function wp_nonce_field was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

636
								/** @scrutinizer ignore-call */ 
637
        wp_nonce_field( "wordpoints_delete_points_type-{$slug}", 'delete-points-type-nonce' );
Loading history...
637
								submit_button( _x( 'Delete', 'points type', 'wordpoints' ), 'delete', 'delete-points-type', false, array( 'id' => "delete_points_type-{$slug}" ) );
0 ignored issues
show
Bug introduced by
The function submit_button was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

637
								/** @scrutinizer ignore-call */ 
638
        submit_button( _x( 'Delete', 'points type', 'wordpoints' ), 'delete', 'delete-points-type', false, array( 'id' => "delete_points_type-{$slug}" ) );
Loading history...
638
							}
639
640
							?>
641
							<a class="hook-control-close" href="#close"><?php esc_html_e( 'Close', 'wordpoints' ); ?></a>
642
						</div>
643
						<div class="alignright">
644
							<?php submit_button( _x( 'Save', 'points type', 'wordpoints' ), 'primary hook-control-save right', 'save-points-type', false, array( 'id' => "points-{$slug}-save" ) ); ?>
645
							<span class="spinner"></span>
646
						</div>
647
						<br class="clear" />
648
					</div>
649
				</form>
650
			<?php endif; ?>
651
652
		<?php if ( $hook_wrap ) : ?>
653
				</div>
654
			</div>
655
656
			<hr class="points-hooks-settings-separator" />
657
		<?php endif; ?>
658
659
		<?php
660
	}
661
662
	/**
663
	 * Display the administration form for a hook.
664
	 *
665
	 * The $points_type parameter is only needed if the hook is hooked to a points
666
	 * type.
667
	 *
668
	 * @since 1.0.0
669
	 *
670
	 * @param string                 $hook_id     The ID of a hook.
671
	 * @param WordPoints_Points_Hook $hook        A points hook object.
672
	 * @param string                 $points_type The slug for a points type.
673
	 */
674
	private static function list_hook( $hook_id, $hook, $points_type = null ) {
675
676
		$number  = $hook->get_number_by_id( $hook_id );
677
		$id_base = $hook->get_id_base();
678
		$options = $hook->get_options();
679
680
		$id_format = $hook_id;
681
682
		$multi_number = ( isset( $options['_multi_num'] ) ) ? $options['_multi_num'] : '';
683
		$add_new      = ( isset( $options['_add'] ) ) ? $options['_add'] : '';
684
685
		// Prepare the URL query string.
686
		$query_arg = array( 'edithook' => $id_format );
687
688
		if ( $add_new ) {
689
690
			$query_arg['addnew'] = 1;
691
692
			if ( $multi_number ) {
693
694
				$query_arg['num']  = $multi_number;
695
				$query_arg['base'] = $id_base;
696
			}
697
698
		} else {
699
700
			$query_arg['points_type'] = $points_type;
701
		}
702
703
		if ( isset( $options['_display'] ) && 'template' === $options['_display'] ) {
704
705
			/*
706
			 * We aren't outputting the form for a hook, but a template form for this
707
			 * hook type. (In other words, we are in the "Available Hooks" section.)
708
			 */
709
710
			// number === 0 implies a template where id numbers are replaced by a generic '__i__'.
711
			$number = 0;
712
713
			// With id_base hook id's are constructed like {$id_base}-{$id_number}.
714
			$id_format = "{$id_base}-__i__";
715
		}
716
717
		?>
718
719
		<div id="hook-<?php echo esc_html( $options['_id_slug'] ); ?>_<?php echo esc_attr( $id_format ); ?>" class="hook <?php echo esc_attr( $options['_classname'] ); ?>">
0 ignored issues
show
Bug introduced by
The function esc_attr was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

719
		<div id="hook-<?php echo esc_html( $options['_id_slug'] ); ?>_<?php echo /** @scrutinizer ignore-call */ esc_attr( $id_format ); ?>" class="hook <?php echo esc_attr( $options['_classname'] ); ?>">
Loading history...
Bug introduced by
The function esc_html was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

719
		<div id="hook-<?php echo /** @scrutinizer ignore-call */ esc_html( $options['_id_slug'] ); ?>_<?php echo esc_attr( $id_format ); ?>" class="hook <?php echo esc_attr( $options['_classname'] ); ?>">
Loading history...
720
		<div class="hook-top">
721
			<div class="hook-title-action">
722
				<a class="hook-action hide-if-no-js" href="#available-hooks"></a>
723
				<a class="hook-control-edit hide-if-js" href="<?php echo esc_url( add_query_arg( $query_arg ) ); ?>">
0 ignored issues
show
Bug introduced by
The function add_query_arg was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

723
				<a class="hook-control-edit hide-if-js" href="<?php echo esc_url( /** @scrutinizer ignore-call */ add_query_arg( $query_arg ) ); ?>">
Loading history...
Bug introduced by
The function esc_url was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

723
				<a class="hook-control-edit hide-if-js" href="<?php echo /** @scrutinizer ignore-call */ esc_url( add_query_arg( $query_arg ) ); ?>">
Loading history...
724
					<span class="edit"><?php echo esc_html_x( 'Edit', 'hook', 'wordpoints' ); ?></span>
0 ignored issues
show
Bug introduced by
The function esc_html_x was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

724
					<span class="edit"><?php echo /** @scrutinizer ignore-call */ esc_html_x( 'Edit', 'hook', 'wordpoints' ); ?></span>
Loading history...
725
					<span class="add"><?php echo esc_html_x( 'Add', 'hook', 'wordpoints' ); ?></span>
726
					<span class="screen-reader-text"><?php echo esc_html( strip_tags( $hook->get_name() ) ); ?></span>
727
				</a>
728
			</div>
729
			<div class="hook-title"><h3><?php echo esc_html( strip_tags( $hook->get_name() ) ); ?><span class="in-hook-title"></span></h3></div>
730
		</div>
731
732
		<div class="hook-inside">
733
			<form method="post">
734
				<div class="hook-content">
735
					<?php
736
737
					$has_form = $hook->form_callback( $number );
0 ignored issues
show
Bug introduced by
It seems like $number can also be of type string; however, parameter $number of WordPoints_Points_Hook::form_callback() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

737
					$has_form = $hook->form_callback( /** @scrutinizer ignore-type */ $number );
Loading history...
738
739
					?>
740
				</div>
741
742
				<input type="hidden" name="hook-id" class="hook-id" value="<?php echo esc_attr( $id_format ); ?>" />
743
				<input type="hidden" name="id_base" class="id_base" value="<?php echo esc_attr( $id_base ); ?>" />
744
				<input type="hidden" name="hook-width" class="hook-width" value="<?php echo isset( $options['width'] ) ? esc_attr( $options['width'] ) : ''; ?>" />
745
				<input type="hidden" name="hook-height" class="hook-height" value="<?php echo isset( $options['height'] ) ? esc_attr( $options['height'] ) : ''; ?>" />
746
				<input type="hidden" name="hook_number" class="hook_number" value="<?php echo esc_attr( $number ); ?>" />
747
				<input type="hidden" name="multi_number" class="multi_number" value="<?php echo esc_attr( $multi_number ); ?>" />
748
				<input type="hidden" name="add_new" class="add_new" value="<?php echo esc_attr( $add_new ); ?>" />
749
750
				<div class="hook-control-actions">
751
					<div class="alignleft">
752
						<a class="hook-control-remove" href="#remove"><?php esc_html_e( 'Delete', 'wordpoints' ); ?></a> |
0 ignored issues
show
Bug introduced by
The function esc_html_e was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

752
						<a class="hook-control-remove" href="#remove"><?php /** @scrutinizer ignore-call */ esc_html_e( 'Delete', 'wordpoints' ); ?></a> |
Loading history...
753
						<a class="hook-control-close" href="#close"><?php esc_html_e( 'Close', 'wordpoints' ); ?></a>
754
					</div>
755
					<div class="alignright<?php echo ( false === $has_form ) ? ' hook-control-noform' : ''; ?>">
756
						<?php submit_button( __( 'Save', 'wordpoints' ), 'primary hook-control-save right', 'savehook', false, array( 'id' => "hook-{$id_format}-savehook" ) ); ?>
0 ignored issues
show
Bug introduced by
The function submit_button was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

756
						<?php /** @scrutinizer ignore-call */ submit_button( __( 'Save', 'wordpoints' ), 'primary hook-control-save right', 'savehook', false, array( 'id' => "hook-{$id_format}-savehook" ) ); ?>
Loading history...
Bug introduced by
The function __ was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

756
						<?php submit_button( /** @scrutinizer ignore-call */ __( 'Save', 'wordpoints' ), 'primary hook-control-save right', 'savehook', false, array( 'id' => "hook-{$id_format}-savehook" ) ); ?>
Loading history...
757
						<span class="spinner"></span>
758
					</div>
759
					<br class="clear" />
760
				</div>
761
			</form>
762
		</div>
763
764
		<div class="hook-description">
765
			<?php if ( ! empty( $options['description'] ) ) : ?>
766
				<?php echo esc_html( $options['description'] ); ?>
767
			<?php endif; ?>
768
		</div>
769
		</div>
770
771
		<?php
772
	}
773
774
	/**
775
	 * Callback to sort hooks by name.
776
	 *
777
	 * @see https://www.php.net/strnatcasecmp strnatcasecmp()
778
	 *
779
	 * @since 1.0.0
780
	 *
781
	 * @param WordPoints_Points_Hook $a The first hook object.
782
	 * @param WordPoints_Points_Hook $b The second hook object.
783
	 *
784
	 * @return int
785
	 */
786
	private static function sort_name_callback( $a, $b ) {
787
788
		return strnatcasecmp( $a->get_name(), $b->get_name() );
789
	}
790
791
} // class WordPoints_Points_Hooks
792
793
// EOF
794