CMB2_hookup   D
last analyzed

Complexity

Total Complexity 137

Size/Duplication

Total Lines 825
Duplicated Lines 0.97 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 6.37%

Importance

Changes 0
Metric Value
dl 8
loc 825
ccs 24
cts 377
cp 0.0637
rs 4.4444
c 0
b 0
f 0
wmc 137
lcom 1
cbo 4

38 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A user_hooks() 4 16 2
A postbox_classes() 0 13 4
B save_post() 0 19 6
C universal_hooks() 0 24 7
C post_hooks() 0 39 8
A comment_hooks() 0 9 2
C term_hooks() 4 39 7
B register_styles() 0 17 6
A register_js() 0 10 3
A register_scripts() 0 4 1
B do_scripts() 0 24 4
B register_column_headers() 0 27 4
A column_display() 0 12 2
A return_column_display() 0 7 2
B add_context_metaboxes() 0 19 5
A output_context_metabox() 0 22 3
A context_box_title_markup_open() 0 19 2
A context_box_title_markup_close() 0 9 2
B add_metaboxes() 0 30 5
A remove_default_tax_metaboxes() 0 10 4
A alternate_context_postbox_classes() 0 18 4
A metabox_callback() 0 4 2
A user_new_metabox() 0 7 3
A user_metabox() 0 3 1
A term_metabox() 0 3 1
B show_form_for_type() 0 18 5
A show_on() 0 15 1
B get_priority() 0 22 4
A save_comment() 0 8 3
A save_user() 0 6 2
A save_term() 0 8 4
A delete_term() 0 11 3
B can_save() 0 14 9
B taxonomy_can_save() 0 13 5
B maybe_enqueue_column_display_styles() 0 11 5
A enqueue_cmb_css() 0 13 3
A enqueue_cmb_js() 0 8 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 CMB2_hookup 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 CMB2_hookup, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Handles hooking CMB2 forms/metaboxes into the post/attachement/user screens
4
 * and handles hooking in and saving those fields.
5
 *
6
 * @since  2.0.0
7
 *
8
 * @category  WordPress_Plugin
9
 * @package   CMB2
10
 * @author    WebDevStudios
11
 * @license   GPL-2.0+
12
 * @link      http://webdevstudios.com
13
 */
14
class CMB2_hookup extends CMB2_Hookup_Base {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
15
16
	/**
17
	 * Only allow JS registration once
18
	 *
19
	 * @var   bool
20
	 * @since 2.0.7
21
	 */
22
	protected static $js_registration_done = false;
23
24
	/**
25
	 * Only allow CSS registration once
26
	 *
27
	 * @var   bool
28
	 * @since 2.0.7
29
	 */
30
	protected static $css_registration_done = false;
31
32
	/**
33
	 * CMB taxonomies array for term meta
34
	 *
35
	 * @var   array
36
	 * @since 2.2.0
37
	 */
38
	protected $taxonomies = array();
39
40
	/**
41
	 * Custom field columns.
42
	 *
43
	 * @var   array
44
	 * @since 2.2.2
45
	 */
46
	protected $columns = array();
47
48
	/**
49
	 * Constructor
50
	 *
51
	 * @since 2.0.0
52
	 * @param CMB2 $cmb The CMB2 object to hookup
53
	 */
54
	public function __construct( CMB2 $cmb ) {
55
		$this->cmb = $cmb;
56
		$this->object_type = $this->cmb->mb_object_type();
57
	}
58
59
	public function universal_hooks() {
60
		foreach ( get_class_methods( 'CMB2_Show_Filters' ) as $filter ) {
61
			add_filter( 'cmb2_show_on', array( 'CMB2_Show_Filters', $filter ), 10, 3 );
62
		}
63
64
		if ( is_admin() ) {
65
			// register our scripts and styles for cmb
66
			$this->once( 'admin_enqueue_scripts', array( __CLASS__, 'register_scripts' ), 8 );
67
			$this->once( 'admin_enqueue_scripts', array( $this, 'do_scripts' ) );
68
69
			$this->maybe_enqueue_column_display_styles();
70
71
			switch ( $this->object_type ) {
72
				case 'post':
73
					return $this->post_hooks();
74
				case 'comment':
75
					return $this->comment_hooks();
76
				case 'user':
77
					return $this->user_hooks();
78
				case 'term':
79
					return $this->term_hooks();
80
			}
81
		}
82
	}
83
84
	public function post_hooks() {
85
86
		// Fetch the context we set in our call.
87
		$context = $this->cmb->prop( 'context' ) ? $this->cmb->prop( 'context' ) : 'normal';
88
89
		// Call the proper hook based on the context provided.
90
		switch ( $context ) {
91
92
			case 'form_top':
93
				add_action( 'edit_form_top', array( $this, 'add_context_metaboxes' ) );
94
				break;
95
96
			case 'before_permalink':
97
				add_action( 'edit_form_before_permalink', array( $this, 'add_context_metaboxes' ) );
98
				break;
99
100
			case 'after_title':
101
				add_action( 'edit_form_after_title', array( $this, 'add_context_metaboxes' ) );
102
				break;
103
104
			case 'after_editor':
105
				add_action( 'edit_form_after_editor', array( $this, 'add_context_metaboxes' ) );
106
				break;
107
108
			default:
109
				add_action( 'add_meta_boxes', array( $this, 'add_metaboxes' ) );
110
		}
111
112
		add_action( 'add_attachment', array( $this, 'save_post' ) );
113
		add_action( 'edit_attachment', array( $this, 'save_post' ) );
114
		add_action( 'save_post', array( $this, 'save_post' ), 10, 2 );
115
116
		if ( $this->cmb->has_columns ) {
0 ignored issues
show
Documentation introduced by
The property $has_columns is declared protected in CMB2. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
117
			foreach ( $this->cmb->prop( 'object_types' ) as $post_type ) {
118
				add_filter( "manage_{$post_type}_posts_columns", array( $this, 'register_column_headers' ) );
119
				add_action( "manage_{$post_type}_posts_custom_column", array( $this, 'column_display' ), 10, 2 );
120
			}
121
		}
122
	}
123
124
	public function comment_hooks() {
125
		add_action( 'add_meta_boxes_comment', array( $this, 'add_metaboxes' ) );
126
		add_action( 'edit_comment', array( $this, 'save_comment' ) );
127
128
		if ( $this->cmb->has_columns ) {
0 ignored issues
show
Documentation introduced by
The property $has_columns is declared protected in CMB2. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
129
			add_filter( 'manage_edit-comments_columns', array( $this, 'register_column_headers' ) );
130
			add_action( 'manage_comments_custom_column', array( $this, 'column_display' ), 10, 3 );
131
		}
132
	}
133
134
	public function user_hooks() {
135
		$priority = $this->get_priority();
136
137
		add_action( 'show_user_profile', array( $this, 'user_metabox' ), $priority );
138
		add_action( 'edit_user_profile', array( $this, 'user_metabox' ), $priority );
139
		add_action( 'user_new_form', array( $this, 'user_new_metabox' ), $priority );
140
141
		add_action( 'personal_options_update', array( $this, 'save_user' ) );
142
		add_action( 'edit_user_profile_update', array( $this, 'save_user' ) );
143
		add_action( 'user_register', array( $this, 'save_user' ) );
144
145 View Code Duplication
		if ( $this->cmb->has_columns ) {
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...
Documentation introduced by
The property $has_columns is declared protected in CMB2. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
146
			add_filter( 'manage_users_columns', array( $this, 'register_column_headers' ) );
147
			add_filter( 'manage_users_custom_column', array( $this, 'return_column_display' ), 10, 3 );
148
		}
149
	}
150
151
	public function term_hooks() {
152
		if ( ! function_exists( 'get_term_meta' ) ) {
153
			wp_die( esc_html__( 'Term Metadata is a WordPress 4.4+ feature. Please upgrade your WordPress install.', 'cmb2' ) );
154
		}
155
156
		if ( ! $this->cmb->prop( 'taxonomies' ) ) {
157
			wp_die( esc_html__( 'Term metaboxes configuration requires a "taxonomies" parameter.', 'cmb2' ) );
158
		}
159
160
		$this->taxonomies = (array) $this->cmb->prop( 'taxonomies' );
161
		$show_on_term_add = $this->cmb->prop( 'new_term_section' );
162
		$priority         = $this->get_priority( 8 );
163
164
		foreach ( $this->taxonomies as $taxonomy ) {
165
			// Display our form data
166
			add_action( "{$taxonomy}_edit_form", array( $this, 'term_metabox' ), $priority, 2 );
167
168
			$show_on_add = is_array( $show_on_term_add )
169
				? in_array( $taxonomy, $show_on_term_add )
170
				: (bool) $show_on_term_add;
171
172
			$show_on_add = apply_filters( "cmb2_show_on_term_add_form_{$this->cmb->cmb_id}", $show_on_add, $this->cmb );
0 ignored issues
show
Documentation introduced by
The property $cmb_id is declared protected in CMB2_Base. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
173
174
			// Display form in add-new section (unless specified not to)
175
			if ( $show_on_add ) {
176
				add_action( "{$taxonomy}_add_form_fields", array( $this, 'term_metabox' ), $priority, 2 );
177
			}
178
179 View Code Duplication
			if ( $this->cmb->has_columns ) {
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...
Documentation introduced by
The property $has_columns is declared protected in CMB2. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
180
				add_filter( "manage_edit-{$taxonomy}_columns", array( $this, 'register_column_headers' ) );
181
				add_filter( "manage_{$taxonomy}_custom_column", array( $this, 'return_column_display' ), 10, 3 );
182
			}
183
		}
184
185
		add_action( 'created_term', array( $this, 'save_term' ), 10, 3 );
186
		add_action( 'edited_terms', array( $this, 'save_term' ), 10, 2 );
187
		add_action( 'delete_term', array( $this, 'delete_term' ), 10, 3 );
188
189
	}
190
191
	/**
192
	 * Registers styles for CMB2
193
	 *
194
	 * @since 2.0.7
195
	 */
196 1
	protected static function register_styles() {
197 1
		if ( self::$css_registration_done ) {
198
			return;
199
		}
200
201
		// Only use minified files if SCRIPT_DEBUG is off
202 1
		$min   = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
203 1
		$front = is_admin() ? '' : '-front';
204 1
		$rtl   = is_rtl() ? '-rtl' : '';
205
206
		// Filter required styles and register stylesheet
207 1
		$dependencies = apply_filters( 'cmb2_style_dependencies', array() );
208 1
		wp_register_style( 'cmb2-styles', CMB2_Utils::url( "css/cmb2{$front}{$rtl}{$min}.css" ), $dependencies );
209 1
		wp_register_style( 'cmb2-display-styles', CMB2_Utils::url( "css/cmb2-display{$rtl}{$min}.css" ), $dependencies );
210
211 1
		self::$css_registration_done = true;
212 1
	}
213
214
	/**
215
	 * Registers scripts for CMB2
216
	 *
217
	 * @since  2.0.7
218
	 */
219 1
	protected static function register_js() {
220 1
		if ( self::$js_registration_done ) {
221
			return;
222
		}
223
224 1
		$hook = is_admin() ? 'admin_footer' : 'wp_footer';
225 1
		add_action( $hook, array( 'CMB2_JS', 'enqueue' ), 8 );
226
227 1
		self::$js_registration_done = true;
228 1
	}
229
230
	/**
231
	 * Registers scripts and styles for CMB2
232
	 *
233
	 * @since  1.0.0
234
	 */
235
	public static function register_scripts() {
236
		self::register_styles();
237
		self::register_js();
238
	}
239
240
	/**
241
	 * Enqueues scripts and styles for CMB2 in admin_head.
242
	 *
243
	 * @since  1.0.0
244
	 */
245
	public function do_scripts( $hook ) {
246
		$hooks = array(
247
			'post.php',
248
			'post-new.php',
249
			'page-new.php',
250
			'page.php',
251
			'comment.php',
252
			'edit-tags.php',
253
			'term.php',
254
			'user-new.php',
255
			'profile.php',
256
			'user-edit.php',
257
		);
258
		// only pre-enqueue our scripts/styles on the proper pages
259
		// show_form_for_type will have us covered if we miss something here.
260
		if ( in_array( $hook, $hooks, true ) ) {
261
			if ( $this->cmb->prop( 'cmb_styles' ) ) {
262
				self::enqueue_cmb_css();
263
			}
264
			if ( $this->cmb->prop( 'enqueue_js' ) ) {
265
				self::enqueue_cmb_js();
266
			}
267
		}
268
	}
269
270
	/**
271
	 * Register the CMB2 field column headers.
272
	 *
273
	 * @since 2.2.2
274
	 */
275
	public function register_column_headers( $columns ) {
276
		$fields = $this->cmb->prop( 'fields' );
277
278
		foreach ( $fields as $key => $field ) {
279
			if ( ! isset( $field['column'] ) ) {
280
				continue;
281
			}
282
283
			$column = $field['column'];
284
285
			if ( false === $column['position'] ) {
286
287
				$columns[ $field['id'] ] = $column['name'];
288
289
			} else {
290
291
				$before = array_slice( $columns, 0, absint( $column['position'] ) );
292
				$before[ $field['id'] ] = $column['name'];
293
				$columns = $before + $columns;
294
			}
295
296
			$column['field'] = $field;
297
			$this->columns[ $field['id'] ] = $column;
298
		}
299
300
		return $columns;
301
	}
302
303
	/**
304
	 * The CMB2 field column display output.
305
	 *
306
	 * @since 2.2.2
307
	 */
308
	public function column_display( $column_name, $object_id ) {
309
		if ( isset( $this->columns[ $column_name ] ) ) {
310
				$field = new CMB2_Field( array(
311
					'field_args'  => $this->columns[ $column_name ]['field'],
312
					'object_type' => $this->object_type,
313
					'object_id'   => $this->cmb->object_id( $object_id ),
314
					'cmb_id'      => $this->cmb->cmb_id,
0 ignored issues
show
Documentation introduced by
The property $cmb_id is declared protected in CMB2_Base. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
315
				) );
316
317
				$this->cmb->get_field( $field )->render_column();
318
		}
319
	}
320
321
	/**
322
	 * Returns the column display.
323
	 *
324
	 * @since 2.2.2
325
	 */
326
	public function return_column_display( $empty, $custom_column, $object_id ) {
327
		ob_start();
328
		$this->column_display( $custom_column, $object_id );
329
		$column = ob_get_clean();
330
331
		return $column ? $column : $empty;
332
	}
333
334
	/**
335
	 * Output the CMB2 box/fields in an alternate context (not in a standard metabox area).
336
	 *
337
	 * @since 2.2.4
338
	 */
339
	public function add_context_metaboxes() {
340
341
		if ( ! $this->show_on() ) {
342
			return;
343
		}
344
345
		$page = get_current_screen()->id;
346
347
		foreach ( $this->cmb->prop( 'object_types' ) as $object_type ) {
348
			$screen = convert_to_screen( $object_type );
349
350
			// If we're on the right post-type/object...
351
			if ( isset( $screen->id ) && $screen->id === $page ) {
352
353
				// Show the box.
354
				$this->output_context_metabox();
355
			}
356
		}
357
	}
358
359
	/**
360
	 * Output the CMB2 box/fields in an alternate context (not in a standard metabox area).
361
	 *
362
	 * @since 2.2.4
363
	 */
364
	public function output_context_metabox() {
365
		$title = $this->cmb->prop( 'title' );
366
367
		/*
368
		 * To keep from outputting the open/close markup, do not include
369
		 * a 'title' property in your metabox registration array.
370
		 *
371
		 * To output the fields 'naked' (without a postbox wrapper/style), then
372
		 * add a `'remove_box_wrap' => true` to your metabox registration array.
373
		 */
374
		$add_wrap = ! empty( $title ) || ! $this->cmb->prop( 'remove_box_wrap' );
375
		$add_handle = $add_wrap && ! empty( $title );
376
377
		// Open the context-box wrap.
378
		$add_handle = $this->context_box_title_markup_open( $add_handle );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $add_handle is correct as $this->context_box_title_markup_open($add_handle) (which targets CMB2_hookup::context_box_title_markup_open()) 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...
379
380
		// Show the form fields.
381
		$this->cmb->show_form();
382
383
		// Close the context-box wrap.
384
		$this->context_box_title_markup_close( $add_handle );
0 ignored issues
show
Documentation introduced by
$add_handle is of type null, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
385
	}
386
387
	/**
388
	 * Output the opening markup for a context box.
389
	 *
390
	 * @since 2.2.4
391
	 * @param $add_handle Whether to add the metabox handle and opening div for .inside
392
	 */
393
	public function context_box_title_markup_open( $add_handle = true ) {
394
		$title = $this->cmb->prop( 'title' );
395
396
		$page = get_current_screen()->id;
397
		add_filter( "postbox_classes_{$page}_{$this->cmb->cmb_id}", array( $this, 'postbox_classes' ) );
0 ignored issues
show
Documentation introduced by
The property $cmb_id is declared protected in CMB2_Base. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
398
399
		echo '<div id="' . $this->cmb->cmb_id . '" class="' . postbox_classes( $this->cmb->cmb_id, $page ) . '">' . "\n";
0 ignored issues
show
Documentation introduced by
The property $cmb_id is declared protected in CMB2_Base. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
400
401
		if ( $add_handle ) {
402
403
			echo '<button type="button" class="handlediv button-link" aria-expanded="true">';
404
				echo '<span class="screen-reader-text">' . sprintf( __( 'Toggle panel: %s' ), $title ) . '</span>';
405
				echo '<span class="toggle-indicator" aria-hidden="true"></span>';
406
			echo '</button>';
407
408
			echo '<h2 class="hndle"><span>' . esc_attr( $title ) . '</span></h2>' . "\n";
409
			echo '<div class="inside">' . "\n";
410
		}
411
	}
412
413
	/**
414
	 * Output the closing markup for a context box.
415
	 *
416
	 * @since 2.2.4
417
	 * @param $add_inside_close Whether to add closing div for .inside.
418
	 */
419
	public function context_box_title_markup_close( $add_inside_close = true ) {
420
421
		// Load the closing divs for a title box.
422
		if ( $add_inside_close ) {
423
			echo '</div>' . "\n"; // .inside
424
		}
425
426
		echo '</div>' . "\n"; // .context-box
427
	}
428
429
	/**
430
	 * Add metaboxes (to 'post' or 'comment' object types)
431
	 *
432
	 * @since 1.0.0
433
	 */
434
	public function add_metaboxes() {
435
436
		if ( ! $this->show_on() ) {
437
			return;
438
		}
439
440
		/*
441
		 * To keep from registering an actual post-screen metabox,
442
		 * omit the 'title' property from the metabox registration array.
443
		 *
444
		 * (WordPress will not display metaboxes without titles anyway)
445
		 *
446
		 * This is a good solution if you want to handle outputting your
447
		 * metaboxes/fields elsewhere in the post-screen.
448
		 */
449
		if ( ! $this->cmb->prop( 'title' ) ) {
450
			return;
451
		}
452
453
		$page = get_current_screen()->id;
454
		add_filter( "postbox_classes_{$page}_{$this->cmb->cmb_id}", array( $this, 'postbox_classes' ) );
0 ignored issues
show
Documentation introduced by
The property $cmb_id is declared protected in CMB2_Base. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
455
456
		foreach ( $this->cmb->prop( 'object_types' ) as $object_type ) {
457
			if ( count( $this->cmb->tax_metaboxes_to_remove ) ) {
0 ignored issues
show
Documentation introduced by
The property $tax_metaboxes_to_remove is declared protected in CMB2. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
458
				$this->remove_default_tax_metaboxes( $object_type );
459
			}
460
461
			add_meta_box( $this->cmb->cmb_id, $this->cmb->prop( 'title' ), array( $this, 'metabox_callback' ), $object_type, $this->cmb->prop( 'context' ), $this->cmb->prop( 'priority' ) );
0 ignored issues
show
Documentation introduced by
The property $cmb_id is declared protected in CMB2_Base. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
462
		}
463
	}
464
465
	/**
466
	 * Remove the specified default taxonomy metaboxes for a post-type.
467
	 *
468
	 * @since 2.2.3
469
	 * @param string $post_type Post type to remove the metabox for.
470
	 */
471
	protected function remove_default_tax_metaboxes( $post_type ) {
472
		foreach ( $this->cmb->tax_metaboxes_to_remove as $taxonomy ) {
0 ignored issues
show
Documentation introduced by
The property $tax_metaboxes_to_remove is declared protected in CMB2. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
473
			if ( ! taxonomy_exists( $taxonomy ) ) {
474
				continue;
475
			}
476
477
			$mb_id = is_taxonomy_hierarchical( $taxonomy ) ? "{$taxonomy}div" : "tagsdiv-{$taxonomy}";
478
			remove_meta_box( $mb_id, $post_type, 'side' );
479
		}
480
	}
481
482
	/**
483
	 * Modify metabox postbox classes.
484
	 *
485
	 * @since  2.2.4
486
	 * @param  array $classes Array of classes
487
	 * @return array           Modified array of classes
488
	 */
489
	public function postbox_classes( $classes ) {
490
		if ( $this->cmb->prop( 'closed' ) && ! in_array( 'closed', $classes ) ) {
491
			$classes[] = 'closed';
492
		}
493
494
		if ( $this->cmb->is_alternate_context_box() ) {
495
			$classes = $this->alternate_context_postbox_classes( $classes );
496
		} else {
497
			$classes[] = 'cmb2-postbox';
498
		}
499
500
		return $classes;
501
	}
502
503
	/**
504
	 * Modify metabox altnernate context postbox classes.
505
	 *
506
	 * @since  2.2.4
507
	 * @param  array $classes Array of classes
508
	 * @return array           Modified array of classes
509
	 */
510
	protected function alternate_context_postbox_classes( $classes ) {
511
		$classes[] = 'context-box';
512
		$classes[] = 'context-' . $this->cmb->prop( 'context' ) . '-box';
513
514
		if ( in_array( $this->cmb->cmb_id, get_hidden_meta_boxes( get_current_screen() ) ) ) {
0 ignored issues
show
Documentation introduced by
The property $cmb_id is declared protected in CMB2_Base. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
515
			$classes[] = 'hide-if-js';
516
		}
517
518
		$add_wrap = $this->cmb->prop( 'title' ) || ! $this->cmb->prop( 'remove_box_wrap' );
519
520
		if ( $add_wrap ) {
521
			$classes[] = 'cmb2-postbox postbox';
522
		} else {
523
			$classes[] = 'cmb2-no-box-wrap';
524
		}
525
526
		return $classes;
527
	}
528
529
	/**
530
	 * Display metaboxes for a post or comment object
531
	 *
532
	 * @since  1.0.0
533
	 */
534
	public function metabox_callback() {
535
		$object_id = 'comment' == $this->object_type ? get_comment_ID() : get_the_ID();
536
		$this->cmb->show_form( $object_id, $this->object_type );
537
	}
538
539
	/**
540
	 * Display metaboxes for new user page
541
	 *
542
	 * @since  1.0.0
543
	 */
544
	public function user_new_metabox( $section ) {
0 ignored issues
show
Coding Style introduced by
user_new_metabox uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
545
		if ( $section == $this->cmb->prop( 'new_user_section' ) ) {
546
			$object_id = $this->cmb->object_id();
547
			$this->cmb->object_id( isset( $_REQUEST['user_id'] ) ? $_REQUEST['user_id'] : $object_id );
548
			$this->user_metabox();
549
		}
550
	}
551
552
	/**
553
	 * Display metaboxes for a user object
554
	 *
555
	 * @since  1.0.0
556
	 */
557
	public function user_metabox() {
558
		$this->show_form_for_type( 'user' );
559
	}
560
561
	/**
562
	 * Display metaboxes for a taxonomy term object
563
	 *
564
	 * @since  2.2.0
565
	 */
566
	public function term_metabox() {
567
		$this->show_form_for_type( 'term' );
568
	}
569
570
	/**
571
	 * Display metaboxes for an object type
572
	 *
573
	 * @since  2.2.0
574
	 * @param  string $type Object type
575
	 * @return void
576
	 */
577
	public function show_form_for_type( $type ) {
578
		if ( $type != $this->cmb->mb_object_type() ) {
579
			return;
580
		}
581
582
		if ( ! $this->show_on() ) {
583
			return;
584
		}
585
586
		if ( $this->cmb->prop( 'cmb_styles' ) ) {
587
			self::enqueue_cmb_css();
588
		}
589
		if ( $this->cmb->prop( 'enqueue_js' ) ) {
590
			self::enqueue_cmb_js();
591
		}
592
593
		$this->cmb->show_form( 0, $type );
594
	}
595
596
	/**
597
	 * Determines if metabox should be shown in current context
598
	 *
599
	 * @since  2.0.0
600
	 * @return bool Whether metabox should be added/shown
601
	 */
602
	public function show_on() {
603
		// If metabox is requesting to be conditionally shown
604
		$show = $this->cmb->should_show();
605
606
		/**
607
		 * Filter to determine if metabox should show. Default is true
608
		 *
609
		 * @param array  $show          Default is true, show the metabox
610
		 * @param mixed  $meta_box_args Array of the metabox arguments
611
		 * @param mixed  $cmb           The CMB2 instance
612
		 */
613
		$show = (bool) apply_filters( 'cmb2_show_on', $show, $this->cmb->meta_box, $this->cmb );
0 ignored issues
show
Documentation introduced by
The property $meta_box is declared protected in CMB2. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
614
615
		return $show;
616
	}
617
618
	/**
619
	 * Get the CMB priority property set to numeric hook priority.
620
	 *
621
	 * @since  2.2.0
622
	 * @param  integer $default Default display hook priority.
623
	 * @return integer          Hook priority.
624
	 */
625
	public function get_priority( $default = 10 ) {
626
		$priority = $this->cmb->prop( 'priority' );
627
628
		if ( ! is_numeric( $priority ) ) {
629
			switch ( $priority ) {
630
631
				case 'high':
632
					$priority = 5;
633
					break;
634
635
				case 'low':
636
					$priority = 20;
637
					break;
638
639
				default:
640
					$priority = $default;
641
					break;
642
			}
643
		}
644
645
		return $priority;
646
	}
647
648
	/**
649
	 * Save data from post metabox
650
	 *
651
	 * @since  1.0.0
652
	 * @param  int   $post_id Post ID
653
	 * @param  mixed $post    Post object
654
	 * @return null
655
	 */
656
	public function save_post( $post_id, $post = false ) {
0 ignored issues
show
Coding Style introduced by
save_post uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
657
658
		$post_type = $post ? $post->post_type : get_post_type( $post_id );
659
660
		$do_not_pass_go = (
661
			! $this->can_save( $post_type )
662
			// check user editing permissions
663
			|| ( 'page' == $post_type && ! current_user_can( 'edit_page', $post_id ) )
664
			|| ! current_user_can( 'edit_post', $post_id )
665
		);
666
667
		if ( $do_not_pass_go ) {
668
			// do not collect $200
669
			return;
670
		}
671
672
		// take a trip to reading railroad – if you pass go collect $200
673
		$this->cmb->save_fields( $post_id, 'post', $_POST );
674
	}
675
676
	/**
677
	 * Save data from comment metabox
678
	 *
679
	 * @since  2.0.9
680
	 * @param  int $comment_id Comment ID
681
	 * @return null
682
	 */
683
	public function save_comment( $comment_id ) {
0 ignored issues
show
Coding Style introduced by
save_comment uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
684
685
		$can_edit = current_user_can( 'moderate_comments', $comment_id );
686
687
		if ( $this->can_save( get_comment_type( $comment_id ) ) && $can_edit ) {
688
			$this->cmb->save_fields( $comment_id, 'comment', $_POST );
689
		}
690
	}
691
692
	/**
693
	 * Save data from user fields
694
	 *
695
	 * @since  1.0.x
696
	 * @param  int $user_id  User ID
697
	 * @return null
698
	 */
699
	public function save_user( $user_id ) {
0 ignored issues
show
Coding Style introduced by
save_user uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
700
		// check permissions
701
		if ( $this->can_save( 'user' ) ) {
702
			$this->cmb->save_fields( $user_id, 'user', $_POST );
703
		}
704
	}
705
706
	/**
707
	 * Save data from term fields
708
	 *
709
	 * @since  2.2.0
710
	 * @param  int    $term_id  Term ID
711
	 * @param  int    $tt_id    Term Taxonomy ID
712
	 * @param  string $taxonomy Taxonomy
713
	 * @return null
714
	 */
715
	public function save_term( $term_id, $tt_id, $taxonomy = '' ) {
0 ignored issues
show
Coding Style introduced by
save_term uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
716
		$taxonomy = $taxonomy ? $taxonomy : $tt_id;
717
718
		// check permissions
719
		if ( $this->taxonomy_can_save( $taxonomy ) && $this->can_save( 'term' ) ) {
720
			$this->cmb->save_fields( $term_id, 'term', $_POST );
721
		}
722
	}
723
724
	/**
725
	 * Delete term meta when a term is deleted.
726
	 *
727
	 * @since  2.2.0
728
	 * @param  int    $term_id  Term ID
729
	 * @param  int    $tt_id    Term Taxonomy ID
730
	 * @param  string $taxonomy Taxonomy
731
	 * @return null
732
	 */
733
	public function delete_term( $term_id, $tt_id, $taxonomy = '' ) {
734
		if ( $this->taxonomy_can_save( $taxonomy ) ) {
735
736
			$data_to_delete = array();
737
			foreach ( $this->cmb->prop( 'fields' ) as $field ) {
738
				$data_to_delete[ $field['id'] ] = '';
739
			}
740
741
			$this->cmb->save_fields( $term_id, 'term', $data_to_delete );
742
		}
743
	}
744
745
	/**
746
	 * Determines if the current object is able to be saved
747
	 *
748
	 * @since  2.0.9
749
	 * @param  string $type Current post_type or comment_type
750
	 * @return bool          Whether object can be saved
751
	 */
752
	public function can_save( $type = '' ) {
0 ignored issues
show
Coding Style introduced by
can_save uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
753
		return apply_filters( 'cmb2_can_save', (
754
			$this->cmb->prop( 'save_fields' )
755
			// check nonce
756
			&& isset( $_POST[ $this->cmb->nonce() ] )
757
			&& wp_verify_nonce( $_POST[ $this->cmb->nonce() ], $this->cmb->nonce() )
758
			// check if autosave
759
			&& ! ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
760
			// get the metabox types & compare it to this type
761
			&& ( $type && in_array( $type, $this->cmb->prop( 'object_types' ) ) )
762
			// Don't do updates during a switch-to-blog instance.
763
			&& ! ( is_multisite() && ms_is_switched() )
764
		) );
765
	}
766
767
	/**
768
	 * Determine if taxonomy of term being modified is cmb2-editable.
769
	 *
770
	 * @since  2.2.0
771
	 * @param  string $taxonomy Taxonomy of term being modified.
772
	 * @return bool             Whether taxonomy is editable.
773
	 */
774
	public function taxonomy_can_save( $taxonomy ) {
775
		if ( empty( $this->taxonomies ) || ! in_array( $taxonomy, $this->taxonomies ) ) {
776
			return false;
777
		}
778
779
		$taxonomy_object = get_taxonomy( $taxonomy );
780
		// Can the user edit this term?
781
		if ( ! isset( $taxonomy_object->cap ) || ! current_user_can( $taxonomy_object->cap->edit_terms ) ) {
782
			return false;
783
		}
784
785
		return true;
786
	}
787
788
	/**
789
	 * Enqueues the 'cmb2-display-styles' if the conditions match (has columns, on the right page, etc).
790
	 *
791
	 * @since  2.2.2.1
792
	 */
793
	protected function maybe_enqueue_column_display_styles() {
794
		global $pagenow;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
795
		if (
796
			$pagenow
797
			&& $this->cmb->has_columns
0 ignored issues
show
Documentation introduced by
The property $has_columns is declared protected in CMB2. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
798
			&& $this->cmb->prop( 'cmb_styles' )
799
			&& in_array( $pagenow, array( 'edit.php', 'users.php', 'edit-comments.php', 'edit-tags.php' ), 1 )
800
			) {
801
			self::enqueue_cmb_css( 'cmb2-display-styles' );
802
		}
803
	}
804
805
	/**
806
	 * Includes CMB2 styles
807
	 *
808
	 * @since  2.0.0
809
	 */
810 1
	public static function enqueue_cmb_css( $handle = 'cmb2-styles' ) {
811 1
		if ( ! apply_filters( 'cmb2_enqueue_css', true ) ) {
812
			return false;
813
		}
814
815 1
		self::register_styles();
816
817
		/*
818
		 * White list the options as this method can be used as a hook callback
819
		 * and have a different argument passed.
820
		 */
821 1
		return wp_enqueue_style( 'cmb2-display-styles' === $handle ? $handle : 'cmb2-styles' );
822
	}
823
824
	/**
825
	 * Includes CMB2 JS
826
	 *
827
	 * @since  2.0.0
828
	 */
829 1
	public static function enqueue_cmb_js() {
830 1
		if ( ! apply_filters( 'cmb2_enqueue_js', true ) ) {
831
			return false;
832
		}
833
834 1
		self::register_js();
835 1
		return true;
836
	}
837
838
}
839