Completed
Push — master ( 71e3f4...1ed264 )
by Marin
02:34
created

Post_Meta_Container   D

Complexity

Total Complexity 103

Size/Duplication

Total Lines 622
Duplicated Lines 16.24 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 3.25%

Importance

Changes 9
Bugs 1 Features 0
Metric Value
wmc 103
c 9
b 1
f 0
lcom 1
cbo 3
dl 101
loc 622
rs 4.7835
ccs 9
cts 276
cp 0.0325

26 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 2
A set_datastore() 0 3 1
C check_setup_settings() 3 35 8
A init() 0 17 3
A save() 14 14 2
B is_valid_save() 0 11 6
D is_valid_save_conditions() 24 106 26
A attach() 0 16 3
A postbox_classes() 0 4 1
D is_valid_attach() 0 47 16
A detach() 11 11 2
A render() 0 3 1
A set_post_id() 0 4 1
B verify_unique_field_name() 17 17 5
A drop_unique_field_name() 8 8 3
A show_on_page_children() 0 11 2
A show_on_page() 0 15 3
A show_on_category() 0 5 1
A show_on_template() 12 12 3
A hide_on_template() 12 12 3
A show_on_level() 0 9 2
A show_on_taxonomy_term() 0 9 2
A show_on_post_format() 0 16 4
A show_on_post_type() 0 7 1
A set_context() 0 5 1
A set_priority() 0 5 1

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 Post_Meta_Container 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 Post_Meta_Container, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Carbon_Fields\Container;
4
5
use Carbon_Fields\Datastore\Meta_Datastore;
6
use Carbon_Fields\Datastore\Post_Meta_Datastore;
7
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
8
9
/**
10
 * Field container designed to extend WordPress custom fields functionality,
11
 * providing easier user interface to add, edit and delete text, media files, 
12
 * location information and more.
13
 */
14
class Post_Meta_Container extends Container {
15
	/**
16
	 * List of registered unique field names
17
	 *
18
	 * @see verify_unique_field_name()
19
	 * @var array
20
	 */
21
	protected static $registered_field_names;
22
23
	/**
24
	 * ID of the post the container is working with
25
	 *
26
	 * @see init()
27
	 * @var int
28
	 */
29
	protected $post_id;
30
31
	/**
32
	 * List of default container settings
33
	 *
34
	 * @see init()
35
	 * @var array
36
	 */
37
	public $settings = array(
38
		'post_type' => array( 'post' ),
39
		'panel_context' => 'normal',
40
		'panel_priority' => 'high',
41
		'show_on' => array(
42
			'category' => null,
43
			'template_names' => array(),
44
			'not_in_template_names' => array(),
45
			'post_formats' => array(),
46
			'level_limit' => null,
47
			'tax_term_id' => null,
48
			'page_id' => null,
49
			'parent_page_id' => null,
50
			'post_path' => null,
51
		),
52
	);
53
54
	/**
55
	 * Create a new post meta fields container
56
	 *
57
	 * @param string $title Unique title of the container
58
	 **/
59 7
	public function __construct( $title ) {
60 7
		parent::__construct( $title );
61
62 6
		if ( ! $this->get_datastore() ) {
63 6
			$this->set_datastore( new Post_Meta_Datastore() );
64 6
		}
65 6
	}
66
67
	/**
68
	 * Assign DataStore instance for use by the container fields
69
	 *
70
	 * @param object $store
71
	 **/
72 6
	public function set_datastore( Meta_Datastore $store ) {
73 6
		parent::set_datastore( $store );
74 6
	}
75
76
	/**
77
	 * Check if all required container settings have been specified
78
	 *
79
	 * @param array $settings Container settings
80
	 **/
81
	public function check_setup_settings( &$settings = array() ) {
82
		if ( isset( $settings['show_on'] ) ) {
83
			$invalid_settings = array_diff_key( $settings['show_on'], $this->settings['show_on'] );
84 View Code Duplication
			if ( ! empty( $invalid_settings ) ) {
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...
85
				Incorrect_Syntax_Exception::raise( 'Invalid show_on settings supplied to setup(): "' . implode( '", "', array_keys( $invalid_settings ) ) . '"' );
86
			}
87
		}
88
89
		if ( isset( $settings['show_on']['post_formats'] ) ) {
90
			$settings['show_on']['post_formats'] = (array) $settings['show_on']['post_formats'];
91
		}
92
93
		if ( isset( $settings['show_on']['post_path'] ) ) {
94
			$page = get_page_by_path( $settings['show_on']['post_path'] );
95
96
			if ( $page ) {
97
				$settings['show_on']['page_id'] = $page->ID;
98
			} else {
99
				$settings['show_on']['page_id'] = -1;
100
			}
101
		}
102
103
		// Transform category slug to taxonomy + term slug + term id
104
		if ( isset( $settings['show_on']['category'] ) ) {
105
			$term = get_term_by( 'slug', $settings['show_on']['category'], 'category' );
106
107
			if ( $term ) {
108
				$settings['show_on']['tax_slug'] = $term->taxonomy;
109
				$settings['show_on']['tax_term'] = $term->slug;
110
				$settings['show_on']['tax_term_id'] = $term->term_id;
111
			}
112
		}
113
114
		return parent::check_setup_settings( $settings );
115
	}
116
117
	/**
118
	 * Create DataStore instance, set post ID to operate with (if such exists).
119
	 * Bind attach() and save() to the appropriate WordPress actions.
120
	 **/
121
	public function init() {
122
		if ( isset( $_GET['post'] ) ) {
1 ignored issue
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
123
			$this->set_post_id( $_GET['post'] );
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
124
		}
125
126
		// force post_type to be array
127
		if ( ! is_array( $this->settings['post_type'] ) ) {
128
			$this->settings['post_type'] = array( $this->settings['post_type'] );
129
		}
130
131
		add_action( 'admin_init', array( $this, '_attach' ) );
132
		add_action( 'save_post', array( $this, '_save' ) );
133
134
		// support for attachments
135
		add_action( 'add_attachment', array( $this, '_save' ) );
136
		add_action( 'edit_attachment', array( $this, '_save' ) );
137
	}
138
139
	/**
140
	 * Perform save operation after successful is_valid_save() check.
141
	 * The call is propagated to all fields in the container.
142
	 *
143
	 * @param int $post_id ID of the post against which save() is ran
144
	 **/
145 View Code Duplication
	public function save( $post_id ) {
1 ignored issue
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...
146
		// Unhook action to garantee single save
147
		remove_action( 'save_post', array( $this, '_save' ) );
148
149
		$this->set_post_id( $post_id );
150
151
		foreach ( $this->fields as $field ) {
152
			$field->set_value_from_input();
153
			$field->save();
154
		}
155
156
		do_action( 'carbon_after_save_custom_fields', $post_id );
157
		do_action( 'carbon_after_save_post_meta', $post_id );
158
	}
159
160
	/**
161
	 * Perform checks whether the current save() request is valid
162
	 * Possible errors are triggering save() for autosave requests
163
	 * or performing post save outside of the post edit page (like Quick Edit)
164
	 *
165
	 * @see is_valid_save_conditions()
166
	 * @param int $post_id ID of the post against which save() is ran
167
	 * @return bool
168
	 **/
169
	public function is_valid_save( $post_id = 0 ) {
170
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
171
			return false;
172
		} else if ( ! isset( $_REQUEST[ $this->get_nonce_name() ] ) || ! wp_verify_nonce( $_REQUEST[ $this->get_nonce_name() ], $this->get_nonce_name() ) ) { // Input var okay.
0 ignored issues
show
introduced by
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
173
			return false;
174
		} else if ( $post_id < 1 ) {
175
			return false;
176
		}
177
178
		return $this->is_valid_save_conditions( $post_id );
179
	}
180
181
	/**
182
	 * Perform checks whether the current save() request is valid
183
	 * Possible errors are triggering save() for autosave requests
184
	 * or performing post save outside of the post edit page (like Quick Edit)
185
	 *
186
	 * @param int $post_id ID of the post against which save() is ran
187
	 * @return bool
188
	 **/
189
	public function is_valid_save_conditions( $post_id ) {
190
		$valid = true;
191
		$post = get_post( $post_id );
192
193
		// Check post type
194
		if ( ! in_array( $post->post_type, $this->settings['post_type'] ) ) {
195
			return false;
196
		}
197
198
		// Check show on conditions
199
		foreach ( $this->settings['show_on'] as $condition => $value ) {
200
			if ( is_null( $value ) ) {
201
				continue;
202
			}
203
204
			switch ( $condition ) {
205
				// show_on_post_format
206
				case 'post_formats':
207
					if ( empty( $value ) || $post->post_type != 'post' ) {
208
						break;
209
					}
210
211
					$current_format = get_post_format( $post_id );
212
					if ( ! in_array( $current_format, $value ) ) {
213
						$valid = false;
214
						break 2;
215
					}
216
217
					break;
218
219
				// show_on_taxonomy_term or show_on_category
220
				case 'category':
221
					$this->show_on_category( $value );
222
223
					/* fall-through intended */
224
				case 'tax_term_id':
225
					$current_terms = wp_get_object_terms( $post_id, $this->settings['show_on']['tax_slug'], array( 'fields' => 'ids' ) );
226
227
					if ( ! is_array( $current_terms ) || ! in_array( $this->settings['show_on']['tax_term_id'], $current_terms ) ) {
228
						$valid = false;
229
						break 2;
230
					}
231
232
					break;
233
234
				// show_on_level
235
				case 'level_limit':
236
					$post_level = count( get_post_ancestors( $post_id ) ) + 1;
237
238
					if ( $post_level != $value ) {
239
						$valid = false;
240
						break 2;
241
					}
242
243
					break;
244
245
				// show_on_page
246
				case 'page_id':
247
					if ( $post_id != $value ) {
248
						$valid = false;
249
						break 2;
250
					}
251
252
					break;
253
254
				// show_on_page_children
255
				case 'parent_page_id':
256
					if ( $post->post_parent != $value ) {
257
						$valid = false;
258
						break 2;
259
					}
260
261
					break;
262
263
				// show_on_template
264 View Code Duplication
				case 'template_names':
1 ignored issue
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...
265
					if ( empty( $value ) || $post->post_type != 'page' ) {
266
						break;
267
					}
268
					$current_template = get_post_meta( $post_id, '_wp_page_template', 1 );
269
270
					if ( ! in_array( $current_template, $value ) ) {
271
						$valid = false;
272
						break 2;
273
					}
274
275
					break;
276
277
				// hide_on_template
278 View Code Duplication
				case 'not_in_template_names':
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...
279
					if ( empty( $value ) || $post->post_type != 'page' ) {
280
						break;
281
					}
282
					$current_template = get_post_meta( $post_id, '_wp_page_template', 1 );
283
284
					if ( in_array( $current_template, $value ) ) {
285
						$valid = false;
286
						break 2;
287
					}
288
289
					break;
290
			}
291
		}
292
293
		return $valid;
294
	}
295
296
	/**
297
	 * Add meta box for each of the container post types
298
	 **/
299
	public function attach() {
300
		foreach ( $this->settings['post_type'] as $post_type ) {
301
			add_meta_box(
302
				$this->id, 
303
				$this->title, 
304
				array( $this, 'render' ), 
305
				$post_type, 
306
				$this->settings['panel_context'],
307
				$this->settings['panel_priority']
308
			);
309
		}
310
311
		foreach ( $this->settings['post_type'] as $post_type ) {
312
			add_filter( "postbox_classes_{$post_type}_{$this->id}", array( $this, 'postbox_classes' ) );
313
		}
314
	}
315
316
	/**
317
	 * Classes to add to the post meta box
318
	 */
319
	public function postbox_classes( $classes ) {
320
		$classes[] = 'carbon-box';
321
		return $classes;
322
	}
323
324
	/**
325
	 * Perform checks whether the container should be attached during the current request
326
	 *
327
	 * @return bool True if the container is allowed to be attached
328
	 **/
329
	public function is_valid_attach() {
330
		global $pagenow;
331
332
		if ( $pagenow !== 'post.php' && $pagenow !== 'post-new.php' ) {
333
			return false;
334
		}
335
336
		// Post types check
337
		if ( ! empty( $this->settings['post_type'] ) ) {
338
			$post_type = '';
339
340
			if ( $this->post_id ) {
341
				$post_type = get_post_type( $this->post_id );
342
			} elseif ( ! empty( $_GET['post_type'] ) ) {
343
				$post_type = $_GET['post_type'];
0 ignored issues
show
introduced by
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_GET
Loading history...
344
			} elseif ( $pagenow === 'post-new.php' ) {
345
				$post_type = 'post';
346
			}
347
348
			if ( ! $post_type || ! in_array( $post_type, $this->settings['post_type'] ) ) {
349
				return false;
350
			}
351
		}
352
353
		// Check show on conditions
354
		foreach ( $this->settings['show_on'] as $condition => $value ) {
355
			if ( is_null( $value ) ) {
356
				continue;
357
			}
358
359
			switch ( $condition ) {
360
				case 'page_id':
361
					if ( $value < 1 || $this->post_id != $value ) {
362
						return false;
363
					}
364
					break;
365
				case 'parent_page_id':
366
					// Check if such page exists
367
					if ( $value < 1 ) {
368
						return false;
369
					}
370
					break;
371
			}
372
		}
373
374
		return true;
375
	}
376
	
377
	/**
378
	 * Revert the result of attach()
379
	 **/
380 View Code Duplication
	public function detach() {
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...
381
		parent::detach();
382
383
		remove_action( 'admin_init', array( $this, '_attach' ) );
384
		remove_action( 'save_post', array( $this, '_save' ) );
385
386
		// unregister field names
387
		foreach ( $this->fields as $field ) {
388
			$this->drop_unique_field_name( $field->get_name() );
389
		}
390
	}
391
392
	/**
393
	 * Output the container markup
394
	 **/
395
	public function render() {
396
		include \Carbon_Fields\DIR . '/templates/Container/post_meta.php';
397
	}
398
399
	/**
400
	 * Set the post ID the container will operate with.
401
	 *
402
	 * @param int $post_id
403
	 **/
404
	public function set_post_id( $post_id ) {
405
		$this->post_id = $post_id;
406
		$this->store->set_id( $post_id );
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Carbon_Fields\Datastore\Datastore_Interface as the method set_id() does only exist in the following implementations of said interface: Carbon_Fields\Datastore\Comment_Meta_Datastore, Carbon_Fields\Datastore\Meta_Datastore, Carbon_Fields\Datastore\Nav_Menu_Datastore, Carbon_Fields\Datastore\Post_Meta_Datastore, Carbon_Fields\Datastore\Term_Meta_Datastore, Carbon_Fields\Datastore\User_Meta_Datastore.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
407
	}
408
409
	/**
410
	 * Perform checks whether there is a field registered with the name $name.
411
	 * If not, the field name is recorded.
412
	 *
413
	 * @param string $name
414
	 **/
415 View Code Duplication
	public function verify_unique_field_name( $name ) {
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...
416
		if ( empty( $this->settings['post_type'] ) ) {
417
			Incorrect_Syntax_Exception::raise( 'Panel instance is not setup correctly (missing post type)' );
418
		}
419
420
		foreach ( $this->settings['post_type'] as $post_type ) {
421
			if ( ! isset( self::$registered_field_names[ $post_type ] ) ) {
422
				self::$registered_field_names[ $post_type ] = array();
423
			}
424
425
			if ( in_array( $name, self::$registered_field_names[ $post_type ] ) ) {
426
				Incorrect_Syntax_Exception::raise( 'Field name "' . $name . '" already registered' );
427
			}
428
429
			self::$registered_field_names[ $post_type ][] = $name;
430
		}
431
	}
432
433
	/**
434
	 * Remove field name $name from the list of unique field names
435
	 *
436
	 * @param string $name
437
	 **/
438 View Code Duplication
	public function drop_unique_field_name( $name ) {
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...
439
		foreach ( $this->settings['post_type'] as $post_type ) {
440
			$index = array_search( $name, self::$registered_field_names[ $post_type ] );
441
			if ( $index !== false ) {
442
				unset( self::$registered_field_names[ $post_type ][ $index ] );
443
			}
444
		}
445
	}
446
447
	/**
448
	 * Show the container only on pages whose parent is referenced by $parent_page_path.
449
	 *
450
	 * @param string $parent_page_path
451
	 * @return object $this
452
	 **/
453
	public function show_on_page_children( $parent_page_path ) {
454
		$page = get_page_by_path( $parent_page_path );
455
456
		if ( $page ) {
457
			$this->settings['show_on']['parent_page_id'] = $page->ID;
458
		} else {
459
			$this->settings['show_on']['parent_page_id'] = -1;
460
		}
461
462
		return $this;
463
	}
464
	
465
	/**
466
	 * Show the container only on particular page referenced by it's path.
467
	 *
468
	 * @param int|string $page page ID or page path
469
	 * @return object $this
470
	 **/
471
	public function show_on_page( $page ) {
472
		if ( is_int( $page ) ) {
473
			$page_obj = get_post( $page );
474
		} else {
475
			$page_obj = get_page_by_path( $page );
476
		}
477
478
		if ( $page_obj ) {
479
			$this->settings['show_on']['page_id'] = $page_obj->ID;
480
		} else {
481
			$this->settings['show_on']['page_id'] = -1;
482
		}
483
484
		return $this;
485
	}
486
	
487
	/**
488
	 * Show the container only on posts from the specified category.
489
	 *
490
	 * @see show_on_taxonomy_term()
491
	 *
492
	 * @param string $category_slug
493
	 * @return object $this
494
	 **/
495
	public function show_on_category( $category_slug ) {
496
		$this->settings['show_on']['category'] = $category_slug;
497
498
		return $this->show_on_taxonomy_term( $category_slug, 'category' );
499
	}
500
	
501
	/**
502
	 * Show the container only on pages whose template has filename $template_path.
503
	 *
504
	 * @param string|array $template_path
505
	 * @return object $this
506
	 **/
507 View Code Duplication
	public function show_on_template( $template_path ) {
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...
508
		if ( is_array( $template_path ) ) {
509
			foreach ( $template_path as $path ) {
510
				$this->show_on_template( $path );
511
			}
512
			return $this;
513
		}
514
515
		$this->settings['show_on']['template_names'][] = $template_path;
516
517
		return $this;
518
	}
519
	
520
	/**
521
	 * Hide the container from pages whose template has filename $template_path.
522
	 *
523
	 * @param string|array $template_path
524
	 * @return object $this
525
	 **/
526 View Code Duplication
	public function hide_on_template( $template_path ) {
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...
527
		if ( is_array( $template_path ) ) {
528
			foreach ( $template_path as $path ) {
529
				$this->hide_on_template( $path );
530
			}
531
			return $this;
532
		}
533
534
		$this->settings['show_on']['not_in_template_names'][] = $template_path;
535
536
		return $this;
537
	}
538
	
539
	/**
540
	 * Show the container only on hierarchical posts of level $level.
541
	 * Levels start from 1 (top level post)
542
	 *
543
	 * @param int $level
544
	 * @return object $this
545
	 **/
546
	public function show_on_level( $level ) {
547
		if ( $level < 0 ) {
548
			Incorrect_Syntax_Exception::raise( 'Invalid level limitation (' . $level . ')' );
549
		}
550
551
		$this->settings['show_on']['level_limit'] = $level;
552
553
		return $this;
554
	}
555
	
556
	/**
557
	 * Show the container only on posts which have term $term_slug from the $taxonomy_slug taxonomy.
558
	 *
559
	 * @param string $taxonomy_slug
560
	 * @param string $term_slug
561
	 * @return object $this
562
	 **/
563
	public function show_on_taxonomy_term( $term_slug, $taxonomy_slug ) {
564
		$term = get_term_by( 'slug', $term_slug, $taxonomy_slug );
565
566
		$this->settings['show_on']['tax_slug'] = $taxonomy_slug;
567
		$this->settings['show_on']['tax_term'] = $term_slug;
568
		$this->settings['show_on']['tax_term_id'] = $term ? $term->term_id : null;
569
570
		return $this;
571
	}
572
	
573
	/**
574
	 * Show the container only on posts from the specified format.
575
	 * Learn more about {@link http://codex.wordpress.org/Post_Formats Post Formats (Codex)}
576
	 *
577
	 * @param string|array $post_format Name of the format as listed on Codex
578
	 * @return object $this
579
	 **/
580
	public function show_on_post_format( $post_format ) {
581
		if ( is_array( $post_format ) ) {
582
			foreach ( $post_format as $format ) {
583
				$this->show_on_post_format( $format );
584
			}
585
			return $this;
586
		}
587
588
		if ( $post_format === 'standard' ) {
589
			$post_format = 0;
590
		}
591
592
		$this->settings['show_on']['post_formats'][] = strtolower( $post_format );
593
594
		return $this;
595
	}
596
597
	/**
598
	 * Show the container only on posts from the specified type(s).
599
	 *
600
	 * @param string|array $post_types
601
	 * @return object $this
602
	 **/
603
	public function show_on_post_type( $post_types ) {
604
		$post_types = (array) $post_types;
605
606
		$this->settings['post_type'] = $post_types;
607
608
		return $this;
609
	}
610
611
	/**
612
	 * Sets the meta box container context
613
	 *
614
	 * @see https://codex.wordpress.org/Function_Reference/add_meta_box
615
	 * @param string $context ('normal', 'advanced' or 'side')
616
	 */
617
	public function set_context( $context ) {
618
		$this->settings['panel_context'] = $context;
619
620
		return $this;
621
	}
622
623
	/**
624
	 * Sets the meta box container priority
625
	 *
626
	 * @see https://codex.wordpress.org/Function_Reference/add_meta_box
627
	 * @param string $priority ('high', 'core', 'default' or 'low')
628
	 */
629
	public function set_priority( $priority ) {
630
		$this->settings['panel_priority'] = $priority;
631
632
		return $this;
633
	}
634
635
} // END Post_Meta_Container 
636