Passed
Push — add/multiplan ( 93f1e2...30efbe )
by Warwick
05:04
created

Admin::customizer_body_colours_handler()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 18
rs 9.9666
1
<?php
2
namespace lsx_health_plan\classes;
3
4
/**
5
 * LSX Health Plan Admin Class.
6
 *
7
 * @package lsx-health-plan
8
 */
9
class Admin {
10
11
	/**
12
	 * Holds class instance
13
	 *
14
	 * @since 1.0.0
15
	 *
16
	 * @var      object \lsx_health_plan\classes\Admin()
17
	 */
18
	protected static $instance = null;
19
20
	/**
21
	 * The post relation fields
22
	 *
23
	 * @var array
24
	 */
25
	public $connections = array();
26
27
	/**
28
	 * Stores the previous values needed to remove the post relations
29
	 *
30
	 * @var array
31
	 */
32
	public $previous_values = array();
33
34
	/**
35
	 * @var object \lsx_health_plan\classes\admin\Settings();
36
	 */
37
	public $settings;
38
39
	/**
40
	 * @var object \lsx_health_plan\classes\admin\Help_Page();
41
	 */
42
	public $help;
43
44
	/**
45
	 * Holds the settings page theme functions
46
	 *
47
	 * @var object \lsx_health_plan\classes\admin\Settings_Theme();
48
	 */
49
	public $settings_theme;
50
51
	/**
52
	 * Contructor
53
	 */
54
	public function __construct() {
55
		$this->load_classes();
56
		add_action( 'admin_menu', array( $this, 'order_menus' ), 200 );
57
		add_action( 'admin_enqueue_scripts', array( $this, 'assets' ) );
58
		add_filter( 'cmb2_override_meta_save', array( $this, 'save_previous_values' ), 20, 4 );
59
		add_filter( 'cmb2_override_meta_remove', array( $this, 'save_previous_values' ), 20, 4 );
60
		add_action( 'cmb2_save_field', array( $this, 'post_relations' ), 20, 4 );
61
		add_action( 'cmb2_save_field', array( $this, 'create_query_fields' ), 20, 4 );
62
		add_action( 'before_delete_post', array( $this, 'delete_post_meta_connections' ), 20, 1 );
63
		add_action( 'cmb2_save_post_fields', array( $this, 'extract_plan_fields' ), 10, 4 );
64
65
		// Customizer.
66
		add_filter( 'lsx_customizer_colour_selectors_body', array( $this, 'customizer_body_colours_handler' ), 15, 2 );
67
	}
68
69
	/**
70
	 * Return an instance of this class.
71
	 *
72
	 * @return object \lsx\member_directory\classes\Admin()    A single instance of this class.
73
	 */
74
	public static function get_instance() {
75
		// If the single instance hasn't been set, set it now.
76
		if ( null === self::$instance ) {
77
			self::$instance = new self();
78
		}
79
		return self::$instance;
80
	}
81
82
	/**
83
	 * Loads the admin subclasses
84
	 */
85
	private function load_classes() {
86
		require_once LSX_HEALTH_PLAN_PATH . 'classes/admin/class-settings.php';
87
		$this->settings = admin\Settings::get_instance();
88
89
		require_once LSX_HEALTH_PLAN_PATH . 'classes/admin/class-help-page.php';
90
		$this->help = admin\Help_Page::get_instance();
91
92
		require_once LSX_HEALTH_PLAN_PATH . 'classes/admin/class-settings-theme.php';
93
		$this->settings_theme = admin\Settings_Theme::get_instance();
94
	}
95
96
	/**
97
	 * Orders the HP menu Items
98
	 *
99
	 * @return void
100
	 */
101
	public function order_menus() {
102
		global $menu, $submenu;
103
		if ( ! empty( $submenu ) ) {
104
			$parent_check = array(
105
				'edit.php?post_type=plan',
106
				'edit.php?post_type=workout',
107
				'edit.php?post_type=meal',
108
			);
109
			foreach ( $submenu as $menu_id => $menu_values ) {
110
				if ( in_array( $menu_id, $parent_check ) ) {
111
					foreach ( $menu_values as $sub_menu_key => $sub_menu_values ) {
112
						switch ( $sub_menu_values[0] ) {
113
114
							case __( 'Add New', 'lsx-health-plan' ):
115
								unset( $submenu[ $menu_id ][ $sub_menu_key ] );
116
								break;
117
118
							case __( 'All', 'lsx-health-plan' ):
119
								$title = $sub_menu_values[0];
120
								// Check and change the label.
121
								switch ( $sub_menu_values[2] ) {
122
									case 'edit.php?post_type=meal':
123
										$title = esc_attr__( 'Meals', 'lsx-health-plan' );
124
										break;
125
126
									case 'edit.php?post_type=recipe':
127
										$title = esc_attr__( 'Recipes', 'lsx-health-plan' );
128
										break;
129
130
									case 'edit.php?post_type=workout':
131
										$title = esc_attr__( 'Workouts', 'lsx-health-plan' );
132
										break;
133
134
									case 'edit.php?post_type=plan':
135
										$title = esc_attr__( 'Plans', 'lsx-health-plan' );
136
										break;
137
138
									case 'edit.php?post_type=video':
139
										$title = esc_attr__( 'Videos', 'lsx-health-plan' );
140
										break;
141
142
									case 'edit.php?post_type=exercise':
143
										$title = esc_attr__( 'Exercises', 'lsx-health-plan' );
144
										break;
145
146
									case 'edit.php?post_type=tip':
147
										$title = esc_attr__( 'Tips', 'lsx-health-plan' );
148
										break;
149
150
									default:
151
										break;
152
								}
153
								$submenu[ $menu_id ][ $sub_menu_key ][0] = $title; // @codingStandardsIgnoreLine
154
								break;
155
156
							default:
157
								break;
158
						}
159
					}
160
				}
161
			}
162
		}
163
	}
164
165
	/**
166
	 * Undocumented function
167
	 *
168
	 * @return void
169
	 */
170
	public function assets() {
171
		wp_enqueue_script( 'media-upload' );
172
		wp_enqueue_script( 'thickbox' );
173
		wp_enqueue_style( 'thickbox' );
174
175
		wp_enqueue_script( 'lsx-health-plan-admin', LSX_HEALTH_PLAN_URL . 'assets/js/lsx-health-plan-admin.min.js', array( 'jquery' ), LSX_HEALTH_PLAN_VER, true );
176
		wp_enqueue_style( 'lsx-health-plan-admin', LSX_HEALTH_PLAN_URL . 'assets/css/lsx-health-plan-admin.css', array(), LSX_HEALTH_PLAN_VER );
177
	}
178
179
	/**
180
	 * Returns the registered connections.
181
	 *
182
	 * @return void
183
	 */
184
	public function get_connections() {
185
		return apply_filters( 'lsx_health_plan_connections', $this->connections );
186
	}
187
188
	/**
189
	 * Saves the previous values before they are overwritten by the new ones.
190
	 *
191
	 * @param [type] $value_to_save
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
192
	 * @param [type] $a
193
	 * @param [type] $args
194
	 * @param [type] $cmb2
195
	 * @return void
196
	 */
197
	public function save_previous_values( $value_to_save, $a, $args, $cmb2 ) {
198
		if ( isset( $cmb2->data_to_save['ID'] ) ) {
199
			$connections = $this->get_connections();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $connections is correct as $this->get_connections() targeting lsx_health_plan\classes\Admin::get_connections() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
200
			$post_type   = get_post_type( $cmb2->data_to_save['ID'] );
201
			if ( isset( $connections[ $post_type ] ) && array_key_exists( $a['field_id'], $connections[ $post_type ] ) ) {
202
				// Get the previous values if the field, so we can run through them and remove the current ID from them later.
203
				$this->previous_values = get_post_meta( $a['id'], $a['field_id'], true );
0 ignored issues
show
Documentation Bug introduced by
It seems like get_post_meta($a['id'], $a['field_id'], true) can also be of type false or string. However, the property $previous_values is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
204
			}
205
		}
206
		return $value_to_save;
207
	}
208
209
	/**
210
	 * Sets up the "post relations"
211
	 *
212
	 * @return    void
213
	 */
214
	public function post_relations( $field_id, $updated, $action, $cmb2 ) {
215
		// If the connections are empty then skip this function.
216
		$connections = $this->get_connections();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $connections is correct as $this->get_connections() targeting lsx_health_plan\classes\Admin::get_connections() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
217
		if ( empty( $connections ) ) {
218
			return;
219
		}
220
221
		// If the field has been updated.
222
		if ( isset( $cmb2->data_to_save['ID'] ) ) {
223
			$post_type = get_post_type( $cmb2->data_to_save['ID'] );
224
			if ( isset( $connections[ $post_type ] ) && array_key_exists( $field_id, $connections[ $post_type ] ) ) {
225
				$saved_values = get_post_meta( $cmb2->data_to_save['ID'], $field_id, true );
226
227
				if ( 'updated' === $action ) {
228
					$this->add_connected_posts( $saved_values, $cmb2->data_to_save['ID'], $connections[ $post_type ][ $field_id ] );
229
					// Check if any posts have been removed.
230
					if ( count( $this->previous_values ) > count( $saved_values ) ) {
0 ignored issues
show
Bug introduced by
It seems like $saved_values can also be of type false and string; however, parameter $var of count() does only seem to accept Countable|array, 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

230
					if ( count( $this->previous_values ) > count( /** @scrutinizer ignore-type */ $saved_values ) ) {
Loading history...
231
						$posts_to_remove = array_diff( $this->previous_values, $saved_values );
0 ignored issues
show
Bug introduced by
It seems like $saved_values can also be of type false and null and string; however, parameter $array2 of array_diff() does only seem to accept array, 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

231
						$posts_to_remove = array_diff( $this->previous_values, /** @scrutinizer ignore-type */ $saved_values );
Loading history...
232
						if ( ! empty( $posts_to_remove ) ) {
233
							$this->remove_connected_posts( $posts_to_remove, $cmb2->data_to_save['ID'], $connections[ $post_type ][ $field_id ] );
234
						}
235
					}
236
				} else if ( 'removed' === $action && ! empty( $this->previous_values ) ) {
237
					$this->remove_connected_posts( $this->previous_values, $cmb2->data_to_save['ID'], $connections[ $post_type ][ $field_id ] );
238
				}
239
			}
240
		}
241
	}
242
243
	/**
244
	 * Updates the connected posts witht he current post ID
245
	 *
246
	 * @param [type] $values
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
247
	 * @param [type] $current_id
248
	 * @param [type] $connected_key
249
	 * @return void
250
	 */
251
	public function add_connected_posts( $values, $current_id, $connected_key ) {
252
		foreach ( $values as $value ) {
253
			$current_post_array = get_post_meta( $value, $connected_key, true );
254
			$previous_values    = $current_post_array;
255
256
			if ( ! empty( $current_post_array ) ) {
257
				$current_post_array = array_map( 'strval', $current_post_array );
0 ignored issues
show
Bug introduced by
It seems like $current_post_array can also be of type string; however, parameter $arr1 of array_map() does only seem to accept array, 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

257
				$current_post_array = array_map( 'strval', /** @scrutinizer ignore-type */ $current_post_array );
Loading history...
258
				array_unique( $current_post_array );
259
			}
260
261
			// If the current connected post has no saved connections then we create it.
262
			if ( false === $current_post_array || empty( $current_post_array ) ) {
263
				$current_post_array = array( $current_id );
264
			} elseif ( ! in_array( (string) $current_id, $current_post_array, true ) ) {
0 ignored issues
show
Bug introduced by
It seems like $current_post_array can also be of type string; however, parameter $haystack of in_array() does only seem to accept array, 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

264
			} elseif ( ! in_array( (string) $current_id, /** @scrutinizer ignore-type */ $current_post_array, true ) ) {
Loading history...
265
				$current_post_array[] = $current_id;
266
			}
267
268
			// Check if the values are empty, if not update them.
269
			if ( ! empty( $current_post_array ) ) {
270
				update_post_meta( $value, $connected_key, $current_post_array, $previous_values );
271
			}
272
		}
273
	}
274
275
	/**
276
	 * Removes the post ID from the connected posts.
277
	 *
278
	 * @param [type] $values
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
279
	 * @param [type] $current_ID
280
	 * @param [type] $connected_key
281
	 * @return void
282
	 */
283
	public function remove_connected_posts( $values, $current_ID, $connected_key ) {
284
		foreach ( $values as $value ) {
285
			$current_post_array = get_post_meta( $value, $connected_key, true );
286
			$new_array          = array();
287
			// Loop through only if the current ID has been saved against the post.
288
			if ( in_array( $current_ID, $current_post_array, false ) ) {
0 ignored issues
show
Bug introduced by
It seems like $current_post_array can also be of type false and null and string; however, parameter $haystack of in_array() does only seem to accept array, 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

288
			if ( in_array( $current_ID, /** @scrutinizer ignore-type */ $current_post_array, false ) ) {
Loading history...
289
290
				// Loop through all the connected saved IDS.
291
				foreach ( $current_post_array as $cpa ) {
292
					if ( (int) $cpa !== (int) $current_ID ) {
293
						$new_array[] = $cpa;
294
					}
295
				}
296
				if ( ! empty( $new_array ) ) {
297
					$new_array = array_unique( $new_array );
298
					delete_post_meta( $value, $connected_key );
299
					add_post_meta( $value, $connected_key, $new_array, true );
300
				} else {
301
					delete_post_meta( $value, $connected_key );
302
				}
303
			}
304
		}
305
	}
306
307
	/**
308
	 * Runs on 'before_delete_post' to run through and remove this post ID from its connected values.
309
	 *
310
	 * @param string $item_id
311
	 * @return void
312
	 */
313
	public function delete_post_meta_connections( $item_id = '' ) {
314
		if ( '' !== $item_id ) {
315
			$post_type   = get_post_type( $item_id );
0 ignored issues
show
Bug introduced by
$item_id of type string is incompatible with the type WP_Post|integer|null expected by parameter $post of get_post_type(). ( Ignorable by Annotation )

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

315
			$post_type   = get_post_type( /** @scrutinizer ignore-type */ $item_id );
Loading history...
316
			$connections = $this->get_connections();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $connections is correct as $this->get_connections() targeting lsx_health_plan\classes\Admin::get_connections() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
317
			if ( isset( $connections[ $post_type ] ) && ! empty( $connections[ $post_type ] ) && is_array( $connections[ $post_type ] ) ) {
318
				foreach ( $connections[ $post_type ] as $this_key => $connected_key ) {
319
					$this->delete_connected_items( $item_id, $this_key, $connected_key );
320
				}
321
			}
322
		}
323
	}
324
325
	/**
326
	 * This function will remvoe the post id fomr its connected posts.
327
	 *
328
	 * @param string $item_id
329
	 * @param string $this_key
330
	 * @param string $connected_key
331
	 * @return void
332
	 */
333
	public function delete_connected_items( $item_id = '', $this_key, $connected_key ) {
334
		if ( '' !== $item_id ) {
335
			$connected_items = get_post_meta( $item_id, $this_key, true );
0 ignored issues
show
Bug introduced by
$item_id of type string is incompatible with the type integer expected by parameter $post_id of get_post_meta(). ( Ignorable by Annotation )

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

335
			$connected_items = get_post_meta( /** @scrutinizer ignore-type */ $item_id, $this_key, true );
Loading history...
336
			if ( ! empty( $connected_items ) ) {
337
				foreach ( $connected_items as $con_id ) {
338
					// Get the connected item array from the connected item.
339
					$their_connections = get_post_meta( $con_id, $connected_key, true );
340
					if ( ! empty( $their_connections ) ) {
341
						$new_connections = $their_connections;
342
						// Run through the array and remove the post to be deleteds ID.
343
						foreach ( $their_connections as $ckey => $cvalue ) {
344
							if ( (int) $item_id === (int) $cvalue ) {
345
								unset( $new_connections[ $ckey ] );
346
							}
347
						}
348
						// Now we save the field.
349
						update_post_meta( $con_id, $connected_key, $new_connections, $their_connections );
350
					}
351
				}
352
			}
353
		}
354
	}
355
356
	/**
357
	 * Saves the serialized post ids in singular custom fields so they are easily queried using WP_Query
358
	 *
359
	 * @return    void
360
	 */
361
	public function create_query_fields( $field_id, $updated, $action, $cmb2 ) {
362
		// If the connections are empty then skip this function.
363
		$search_fields = array(
364
			'plan_product',
365
		);
366
		if ( ! in_array( $field_id, $search_fields ) ) {
367
			return;
368
		}
369
370
		// If the field has been updated.
371
		if ( isset( $cmb2->data_to_save['ID'] ) && isset( $cmb2->data_to_save[ $field_id . '_results' ] ) && ! empty( $cmb2->data_to_save[ $field_id . '_results' ] ) ) {
372
			delete_post_meta( $cmb2->data_to_save['ID'], '_' . $field_id . '_id' );
373
			foreach ( $cmb2->data_to_save[ $field_id . '_results' ] as $temp ) {
374
				add_post_meta( $cmb2->data_to_save['ID'], '_' . $field_id . '_id', $temp, false );
375
			}
376
		}
377
	}
378
379
	/**
380
	 * Extract the plan fields so they save to an indexable array.
381
	 *
382
	 * @param [type] $object_id
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
383
	 * @param [type] $cmb_id
384
	 * @param [type] $updated
385
	 * @param [type] $cmb2
386
	 * @return void
387
	 */
388
	public function extract_plan_fields( $object_id, $cmb_id, $updated, $cmb2 ) {
389
		if ( 'plan_sections_metabox' === $cmb_id ) {
390
			// Check if our fields are available, and cycle through them.
391
			if ( isset( $cmb2->data_to_save['plan_sections'] ) && ! empty( $cmb2->data_to_save['plan_sections'] ) ) {
392
				$fields_to_save = array();
393
				// Run through each row of fields.
394
				foreach ( $cmb2->data_to_save['plan_sections'] as $field_index => $fields ) {
395
					// Run through each field in that section.
396
					foreach ( $fields as $field_key => $field_value ) {
397
						$stored_values_key = 'plan_sections_' . $field_index . '_' . $field_key . '_store';
398
						if ( isset( $cmb2->data_to_save[ $stored_values_key ] ) && ! empty( $cmb2->data_to_save[ $stored_values_key ] ) ) {
399
							$stored_values = $cmb2->data_to_save[ $stored_values_key ];
400
							$stored_values = explode( ',', $stored_values );
401
							foreach ( $stored_values as $id_to_save ) {
402
								$fields_to_save[ $field_key ][] = $id_to_save;
403
							}
404
						}
405
					}
406
				}
407
				$this->save_field_array( $object_id, $fields_to_save );
408
			}
409
		}
410
	}
411
412
	/**
413
	 * Runs through the supplied array and saved the fields to the current Object.
414
	 *
415
	 * @param integer $object_id
416
	 * @param array   $fields_to_save
417
	 * @return void
418
	 */
419
	public function save_field_array( $object_id = 0, $fields_to_save = array() ) {
420
421
		// Run through the fields and save the meta items.
422
		if ( ! empty( $fields_to_save ) ) {
423
			foreach ( $fields_to_save as $field_key => $field_values ) {
424
				delete_post_meta( $object_id, $field_key );
425
426
				$field_values = array_unique( $field_values );
427
				foreach ( $field_values as $field_value ) {
428
					add_post_meta( $object_id, $field_key, $field_value, false );
429
				}
430
			}
431
		}
432
	}
433
434
	/**
435
	 * Handle body colours that might be change by LSX Customizer.
436
	 */
437
	public function customizer_body_colours_handler( $css, $colors ) {
438
		$css .= '
439
			@import "' . LSX_HEALTH_PLAN_PATH . '/assets/css/scss/partials/customizer-health-plan-body-colours";
440
441
			/**
442
			 * LSX Customizer - Body (LSX Health Plan)
443
			 */
444
			@include customizer-health-plan-body-colours (
445
				$bg: 		' . $colors['background_color'] . ',
446
				$breaker: 	' . $colors['body_line_color'] . ',
447
				$color:    	' . $colors['body_text_color'] . ',
448
				$link:    	' . $colors['body_link_color'] . ',
449
				$hover:    	' . $colors['body_link_hover_color'] . ',
450
				$small:    	' . $colors['body_text_small_color'] . '
451
			);
452
		';
453
454
		return $css;
455
	}
456
}
457