Completed
Push — trunk ( e98059...7752bd )
by Justin
05:16
created

CMB2_hookup::can_save()   B

Complexity

Conditions 9
Paths 1

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 90

Importance

Changes 0
Metric Value
cc 9
eloc 8
nc 1
nop 1
dl 0
loc 14
ccs 0
cts 0
cp 0
crap 90
rs 7.756
c 0
b 0
f 0
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
	 * @var   bool
19
	 * @since 2.0.7
20
	 */
21
	protected static $js_registration_done = false;
22
23
	/**
24
	 * Only allow CSS registration once
25
	 * @var   bool
26
	 * @since 2.0.7
27
	 */
28
	protected static $css_registration_done = false;
29
30
	/**
31
	 * CMB taxonomies array for term meta
32
	 * @var   array
33
	 * @since 2.2.0
34
	 */
35
	protected $taxonomies = array();
36
37
	/**
38
	 * Custom field columns.
39
	 * @var   array
40
	 * @since 2.2.2
41
	 */
42
	protected $columns = array();
43
44
	/**
45
	 * Constructor
46
	 * @since 2.0.0
47
	 * @param CMB2 $cmb The CMB2 object to hookup
48
	 */
49
	public function __construct( CMB2 $cmb ) {
50
		$this->cmb = $cmb;
51
		$this->object_type = $this->cmb->mb_object_type();
52
	}
53
54
	public function universal_hooks() {
55
		foreach ( get_class_methods( 'CMB2_Show_Filters' ) as $filter ) {
56
			add_filter( 'cmb2_show_on', array( 'CMB2_Show_Filters', $filter ), 10, 3 );
57
		}
58
59
		if ( is_admin() ) {
60
			// register our scripts and styles for cmb
61
			$this->once( 'admin_enqueue_scripts', array( __CLASS__, 'register_scripts' ), 8 );
62
			$this->once( 'admin_enqueue_scripts', array( $this, 'do_scripts' ) );
63
64
			$this->maybe_enqueue_column_display_styles();
65
66
			switch ( $this->object_type ) {
67
				case 'post':
68
					return $this->post_hooks();
69
				case 'comment':
70
					return $this->comment_hooks();
71
				case 'user':
72
					return $this->user_hooks();
73
				case 'term':
74
					return $this->term_hooks();
75
			}
76
		}
77
	}
78
79
	public function post_hooks() {
80
		add_action( 'add_meta_boxes', array( $this, 'add_metaboxes' ) );
81
		add_action( 'add_attachment', array( $this, 'save_post' ) );
82
		add_action( 'edit_attachment', array( $this, 'save_post' ) );
83
		add_action( 'save_post', array( $this, 'save_post' ), 10, 2 );
84
85
		if ( $this->cmb->has_columns ) {
86
			foreach ( $this->cmb->prop( 'object_types' ) as $post_type ) {
87
				add_filter( "manage_{$post_type}_posts_columns", array( $this, 'register_column_headers' ) );
88
				add_action( "manage_{$post_type}_posts_custom_column", array( $this, 'column_display' ), 10, 2 );
89
			}
90
		}
91
	}
92
93
	public function comment_hooks() {
94
		add_action( 'add_meta_boxes_comment', array( $this, 'add_metaboxes' ) );
95
		add_action( 'edit_comment', array( $this, 'save_comment' ) );
96
97
		if ( $this->cmb->has_columns ) {
98
			add_filter( 'manage_edit-comments_columns', array( $this, 'register_column_headers' ) );
99
			add_action( 'manage_comments_custom_column', array( $this, 'column_display'  ), 10, 3 );
100
		}
101
	}
102
103
	public function user_hooks() {
104
		$priority = $this->get_priority();
105
106
		add_action( 'show_user_profile', array( $this, 'user_metabox' ), $priority );
107
		add_action( 'edit_user_profile', array( $this, 'user_metabox' ), $priority );
108
		add_action( 'user_new_form', array( $this, 'user_new_metabox' ), $priority );
109
110 1
		add_action( 'personal_options_update', array( $this, 'save_user' ) );
111 1
		add_action( 'edit_user_profile_update', array( $this, 'save_user' ) );
112 1
		add_action( 'user_register', array( $this, 'save_user' ) );
113
114 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...
115
			add_filter( 'manage_users_columns', array( $this, 'register_column_headers' ) );
116 1
			add_filter( 'manage_users_custom_column', array( $this, 'return_column_display'  ), 10, 3 );
117
		}
118 1
	}
119
120 1
	public function term_hooks() {
121 1
		if ( ! function_exists( 'get_term_meta' ) ) {
122 1
			wp_die( esc_html__( 'Term Metadata is a WordPress 4.4+ feature. Please upgrade your WordPress install.', 'cmb2' ) );
123 1
		}
124 1
125 1
		if ( ! $this->cmb->prop( 'taxonomies' ) ) {
126 1
			wp_die( esc_html__( 'Term metaboxes configuration requires a "taxonomies" parameter.', 'cmb2' ) );
127 1
		}
128 1
129
		$this->taxonomies = (array) $this->cmb->prop( 'taxonomies' );
130 1
		$show_on_term_add = $this->cmb->prop( 'new_term_section' );
131
		$priority         = $this->get_priority( 8 );
132
133 1
		foreach ( $this->taxonomies as $taxonomy ) {
134
			// Display our form data
135 1
			add_action( "{$taxonomy}_edit_form", array( $this, 'term_metabox' ), $priority, 2 );
136
137 1
			$show_on_add = is_array( $show_on_term_add )
138
				? in_array( $taxonomy, $show_on_term_add )
139 1
				: (bool) $show_on_term_add;
140 1
141 1
			$show_on_add = apply_filters( "cmb2_show_on_term_add_form_{$this->cmb->cmb_id}", $show_on_add, $this->cmb );
142 1
143 1
			// Display form in add-new section (unless specified not to)
144 1
			if ( $show_on_add ) {
145
				add_action( "{$taxonomy}_add_form_fields", array( $this, 'term_metabox' ), $priority, 2 );
146 1
			}
147
148 1 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...
149 1
				add_filter( "manage_edit-{$taxonomy}_columns", array( $this, 'register_column_headers' ) );
150 1
				add_filter( "manage_{$taxonomy}_custom_column", array( $this, 'return_column_display'  ), 10, 3 );
151 1
			}
152 1
		}
153 1
154 1
		add_action( 'created_term', array( $this, 'save_term' ), 10, 3 );
155 1
		add_action( 'edited_terms', array( $this, 'save_term' ), 10, 2 );
156 1
		add_action( 'delete_term', array( $this, 'delete_term' ), 10, 3 );
157 1
158 1
	}
159 1
160 1
	/**
161 1
	 * Registers styles for CMB2
162
	 * @since 2.0.7
163 1
	 */
164 1
	protected static function register_styles() {
165 1
		if ( self::$css_registration_done ) {
166 1
			return;
167
		}
168 1
169 1
		// Only use minified files if SCRIPT_DEBUG is off
170
		$min   = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
171 1
		$front = is_admin() ? '' : '-front';
172 1
		$rtl   = is_rtl() ? '-rtl' : '';
173 1
174 1
		// Filter required styles and register stylesheet
175 1
		$dependencies = apply_filters( 'cmb2_style_dependencies', array() );
176 1
		wp_register_style( 'cmb2-styles', CMB2_Utils::url( "css/cmb2{$front}{$rtl}{$min}.css" ), $dependencies );
177 1
		wp_register_style( 'cmb2-display-styles', CMB2_Utils::url( "css/cmb2-display{$rtl}{$min}.css" ), $dependencies );
178 1
179
		self::$css_registration_done = true;
180 1
	}
181
182 1
	/**
183 1
	 * Registers scripts for CMB2
184
	 * @since  2.0.7
185
	 */
186
	protected static function register_js() {
187
		if ( self::$js_registration_done ) {
188
			return;
189
		}
190
191
		$hook = is_admin() ? 'admin_footer' : 'wp_footer';
192
		add_action( $hook, array( 'CMB2_JS', 'enqueue' ), 8 );
193
194
		self::$js_registration_done = true;
195
	}
196
197
	/**
198
	 * Registers scripts and styles for CMB2
199
	 * @since  1.0.0
200
	 */
201
	public static function register_scripts() {
202
		self::register_styles();
203
		self::register_js();
204
	}
205
206
	/**
207
	 * Enqueues scripts and styles for CMB2 in admin_head.
208
	 * @since  1.0.0
209
	 */
210
	public function do_scripts( $hook ) {
211
		$hooks = array(
212
			'post.php',
213
			'post-new.php',
214
			'page-new.php',
215
			'page.php',
216
			'comment.php',
217
			'edit-tags.php',
218
			'term.php',
219
			'user-new.php',
220
			'profile.php',
221
			'user-edit.php',
222
		);
223
		// only pre-enqueue our scripts/styles on the proper pages
224
		// show_form_for_type will have us covered if we miss something here.
225
		if ( in_array( $hook, $hooks, true ) ) {
226
			if ( $this->cmb->prop( 'cmb_styles' ) ) {
227
				self::enqueue_cmb_css();
228
			}
229
			if ( $this->cmb->prop( 'enqueue_js' ) ) {
230
				self::enqueue_cmb_js();
231
			}
232
		}
233
	}
234
235
	/**
236
	 * Register the CMB2 field column headers.
237
	 * @since 2.2.2
238
	 */
239
	public function register_column_headers( $columns ) {
240
		$fields = $this->cmb->prop( 'fields' );
241
242
		foreach ( $fields as $key => $field ) {
243
			if ( ! isset( $field['column'] ) ) {
244
				continue;
245
			}
246
247
			$column = $field['column'];
248
249
			if ( false === $column['position'] ) {
250
251
				$columns[ $field['id'] ] = $column['name'];
252
253
			} else {
254
255
				$before = array_slice( $columns, 0, absint( $column['position'] ) );
256
				$before[ $field['id'] ] = $column['name'];
257
				$columns = $before + $columns;
258
			}
259
260
			$column['field'] = $field;
261
			$this->columns[ $field['id'] ] = $column;
262
		}
263
264
		return $columns;
265
	}
266
267
	/**
268
	 * The CMB2 field column display output.
269
	 * @since 2.2.2
270
	 */
271
	public function column_display( $column_name, $object_id ) {
272
		if ( isset( $this->columns[ $column_name ] ) ) {
273
 			$field = new CMB2_Field( array(
274
				'field_args'  => $this->columns[ $column_name ]['field'],
275
				'object_type' => $this->object_type,
276
				'object_id'   => $this->cmb->object_id( $object_id ),
277
				'cmb_id'      => $this->cmb->cmb_id,
278
			) );
279
280
			$this->cmb->get_field( $field )->render_column();
281
		}
282
	}
283
284
	/**
285
	 * Returns the column display.
286
	 * @since 2.2.2
287
	 */
288
	public function return_column_display( $empty, $custom_column, $object_id ) {
289
		ob_start();
290
		$this->column_display( $custom_column, $object_id );
291
		$column = ob_get_clean();
292
293
		return $column ? $column : $empty;
294
	}
295
296
	/**
297
	 * Add metaboxes (to 'post' or 'comment' object types)
298
	 * @since 1.0.0
299
	 */
300
	public function add_metaboxes() {
301
302
		if ( ! $this->show_on() ) {
303
			return;
304
		}
305
306
		/**
307
		 * To keep from registering an actual post-screen metabox,
308
		 * omit the 'title' attribute from the metabox registration array.
309
		 *
310
		 * (WordPress will not display metaboxes without titles anyway)
311
		 *
312
		 * This is a good solution if you want to output your metaboxes
313
		 * Somewhere else in the post-screen
314
		 */
315
		if ( ! $this->cmb->prop( 'title' ) ) {
316
			return;
317
		}
318
319
		foreach ( $this->cmb->prop( 'object_types' ) as $post_type ) {
320
			if ( $this->cmb->prop( 'closed' ) ) {
321
				add_filter( "postbox_classes_{$post_type}_{$this->cmb->cmb_id}", array( $this, 'close_metabox_class' ) );
322
			}
323
324
			if ( count( $this->cmb->tax_metaboxes_to_remove ) ) {
325
				$this->remove_default_tax_metaboxes( $post_type );
326
			}
327
328
			add_meta_box( $this->cmb->cmb_id, $this->cmb->prop( 'title' ), array( $this, 'metabox_callback' ), $post_type, $this->cmb->prop( 'context' ), $this->cmb->prop( 'priority' ) );
329
		}
330
	}
331
332
	/**
333
	 * Remove the specified default taxonomy metaboxes for a post-type.
334
	 * @since 2.2.3
335
	 * @param string $post_type Post type to remove the metabox for.
336
	 */
337
	protected function remove_default_tax_metaboxes( $post_type ) {
338
		foreach ( $this->cmb->tax_metaboxes_to_remove as $taxonomy ) {
339
			if ( ! taxonomy_exists( $taxonomy ) ) {
340
				continue;
341
			}
342
343
			$mb_id = is_taxonomy_hierarchical( $taxonomy ) ? "{$taxonomy}div" : "tagsdiv-{$taxonomy}";
344
			remove_meta_box( $mb_id, $post_type, 'side' );
345
		}
346
	}
347
348
	/**
349
	 * Add 'closed' class to metabox
350 1
	 * @since  2.0.0
351 1
	 * @param  array  $classes Array of classes
352
	 * @return array           Modified array of classes
353 1
	 */
354
	public function close_metabox_class( $classes ) {
355
		$classes[] = 'closed';
356
		return $classes;
357
	}
358
359
	/**
360 1
	 * Display metaboxes for a post or comment object
361 1
	 * @since  1.0.0
362 1
	 */
363 1
	public function metabox_callback() {
364
		$object_id = 'comment' == $this->object_type ? get_comment_ID() : get_the_ID();
365
		$this->cmb->show_form( $object_id, $this->object_type );
366
	}
367 1
368
	/**
369
	 * Display metaboxes for new user page
370
	 * @since  1.0.0
371
	 */
372
	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...
373
		if ( $section == $this->cmb->prop( 'new_user_section' ) ) {
374
			$object_id = $this->cmb->object_id();
375
			$this->cmb->object_id( isset( $_REQUEST['user_id'] ) ? $_REQUEST['user_id'] : $object_id );
376
			$this->user_metabox();
377
		}
378
	}
379
380
	/**
381
	 * Display metaboxes for a user object
382
	 * @since  1.0.0
383
	 */
384
	public function user_metabox() {
385
		$this->show_form_for_type( 'user' );
386
	}
387
388
	/**
389
	 * Display metaboxes for a taxonomy term object
390
	 * @since  2.2.0
391
	 */
392
	public function term_metabox() {
393
		$this->show_form_for_type( 'term' );
394
	}
395
396
	/**
397
	 * Display metaboxes for an object type
398
	 * @since  2.2.0
399
	 * @param  string $type Object type
400
	 * @return void
401
	 */
402
	public function show_form_for_type( $type ) {
403
		if ( $type != $this->cmb->mb_object_type() ) {
404
			return;
405
		}
406
407
		if ( ! $this->show_on() ) {
408
			return;
409
		}
410
411
		if ( $this->cmb->prop( 'cmb_styles' ) ) {
412
			self::enqueue_cmb_css();
413
		}
414
		if ( $this->cmb->prop( 'enqueue_js' ) ) {
415
			self::enqueue_cmb_js();
416
		}
417
418
		$this->cmb->show_form( 0, $type );
419
	}
420
421
	/**
422
	 * Determines if metabox should be shown in current context
423
	 * @since  2.0.0
424
	 * @return bool Whether metabox should be added/shown
425
	 */
426
	public function show_on() {
427
		// If metabox is requesting to be conditionally shown
428
		$show = $this->cmb->should_show();
429
430
		/**
431
		 * Filter to determine if metabox should show. Default is true
432
		 *
433
		 * @param array  $show          Default is true, show the metabox
434
		 * @param mixed  $meta_box_args Array of the metabox arguments
435
		 * @param mixed  $cmb           The CMB2 instance
436
		 */
437
		$show = (bool) apply_filters( 'cmb2_show_on', $show, $this->cmb->meta_box, $this->cmb );
438
439
		return $show;
440
	}
441
442
	/**
443
	 * Get the CMB priority property set to numeric hook priority.
444
	 * @since  2.2.0
445
	 * @param  integer $default Default display hook priority.
446
	 * @return integer          Hook priority.
447
	 */
448
	public function get_priority( $default = 10 ) {
449
		$priority = $this->cmb->prop( 'priority' );
450
451
		if ( ! is_numeric( $priority ) ) {
452
			switch ( $priority ) {
453
454
				case 'high':
455
					$priority = 5;
456
					break;
457
458
				case 'low':
459
					$priority = 20;
460
					break;
461
462
				default:
463
					$priority = $default;
464
					break;
465
			}
466
		}
467
468
		return $priority;
469
	}
470
471
	/**
472
	 * Save data from post metabox
473
	 * @since  1.0.0
474
	 * @param  int    $post_id Post ID
475
	 * @param  mixed  $post    Post object
476
	 * @return null
477
	 */
478
	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...
479
480
		$post_type = $post ? $post->post_type : get_post_type( $post_id );
481
482
		$do_not_pass_go = (
483
			! $this->can_save( $post_type )
484
			// check user editing permissions
485
			|| ( 'page' == $post_type && ! current_user_can( 'edit_page', $post_id ) )
486
			|| ! current_user_can( 'edit_post', $post_id )
487
		);
488
489
		if ( $do_not_pass_go ) {
490
			// do not collect $200
491
			return;
492
		}
493
494
		// take a trip to reading railroad – if you pass go collect $200
495
		$this->cmb->save_fields( $post_id, 'post', $_POST );
496
	}
497
498
	/**
499
	 * Save data from comment metabox
500
	 * @since  2.0.9
501
	 * @param  int    $comment_id Comment ID
502
	 * @return null
503
	 */
504
	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...
505
506
		$can_edit = current_user_can( 'moderate_comments', $comment_id );
507
508
		if ( $this->can_save( get_comment_type( $comment_id ) ) && $can_edit ) {
509
			$this->cmb->save_fields( $comment_id, 'comment', $_POST );
510
		}
511
	}
512
513
	/**
514
	 * Save data from user fields
515
	 * @since  1.0.x
516
	 * @param  int   $user_id  User ID
517
	 * @return null
518
	 */
519
	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...
520
		// check permissions
521
		if ( $this->can_save( 'user' ) ) {
522
			$this->cmb->save_fields( $user_id, 'user', $_POST );
523
		}
524
	}
525
526
	/**
527
	 * Save data from term fields
528
	 * @since  2.2.0
529
	 * @param  int    $term_id  Term ID
530
	 * @param  int    $tt_id    Term Taxonomy ID
531
	 * @param  string $taxonomy Taxonomy
532
	 * @return null
533
	 */
534
	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...
535
		$taxonomy = $taxonomy ? $taxonomy : $tt_id;
536
537
		// check permissions
538
		if ( $this->taxonomy_can_save( $taxonomy ) && $this->can_save( 'term' ) ) {
539
			$this->cmb->save_fields( $term_id, 'term', $_POST );
540
		}
541
	}
542
543
	/**
544
	 * Delete term meta when a term is deleted.
545
	 * @since  2.2.0
546
	 * @param  int    $term_id  Term ID
547
	 * @param  int    $tt_id    Term Taxonomy ID
548
	 * @param  string $taxonomy Taxonomy
549
	 * @return null
550
	 */
551
	public function delete_term( $term_id, $tt_id, $taxonomy = '' ) {
552
		if ( $this->taxonomy_can_save( $taxonomy ) ) {
553
554
			$data_to_delete = array();
555
			foreach ( $this->cmb->prop( 'fields' ) as $field ) {
556
				$data_to_delete[ $field['id'] ] = '';
557
			}
558
559
			$this->cmb->save_fields( $term_id, 'term', $data_to_delete );
560
		}
561
	}
562
563
	/**
564
	 * Determines if the current object is able to be saved
565
	 * @since  2.0.9
566
	 * @param  string  $type Current post_type or comment_type
567
	 * @return bool          Whether object can be saved
568
	 */
569
	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...
570
		return apply_filters( 'cmb2_can_save', (
571
			$this->cmb->prop( 'save_fields' )
572
			// check nonce
573
			&& isset( $_POST[ $this->cmb->nonce() ] )
574
			&& wp_verify_nonce( $_POST[ $this->cmb->nonce() ], $this->cmb->nonce() )
575
			// check if autosave
576
			&& ! ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
577
			// get the metabox types & compare it to this type
578
			&& ( $type && in_array( $type, $this->cmb->prop( 'object_types' ) ) )
579
			// Don't do updates during a switch-to-blog instance.
580
			&& ! ( is_multisite() && ms_is_switched() )
581
		) );
582
	}
583
584
	/**
585
	 * Determine if taxonomy of term being modified is cmb2-editable.
586
	 * @since  2.2.0
587
	 * @param  string $taxonomy Taxonomy of term being modified.
588
	 * @return bool             Whether taxonomy is editable.
589
	 */
590
	public function taxonomy_can_save( $taxonomy ) {
591
		if ( empty( $this->taxonomies ) || ! in_array( $taxonomy, $this->taxonomies ) ) {
592
			return false;
593
		}
594
595
		$taxonomy_object = get_taxonomy( $taxonomy );
596
		// Can the user edit this term?
597
		if ( ! isset( $taxonomy_object->cap ) || ! current_user_can( $taxonomy_object->cap->edit_terms ) ) {
598
			return false;
599
		}
600
601
		return true;
602
	}
603
604
	/**
605
	 * Enqueues the 'cmb2-display-styles' if the conditions match (has columns, on the right page, etc).
606
	 * @since  2.2.2.1
607
	 */
608
	protected function maybe_enqueue_column_display_styles() {
609
		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...
610
		if (
611
			$pagenow
612
			&& $this->cmb->has_columns
613
			&& $this->cmb->prop( 'cmb_styles' )
614
			&& in_array( $pagenow, array( 'edit.php', 'users.php', 'edit-comments.php', 'edit-tags.php' ), 1 )
615
			) {
616
			self::enqueue_cmb_css( 'cmb2-display-styles' );
617
		}
618
	}
619
620
	/**
621
	 * Includes CMB2 styles
622
	 * @since  2.0.0
623
	 */
624
	public static function enqueue_cmb_css( $handle = 'cmb2-styles' ) {
625
		if ( ! apply_filters( 'cmb2_enqueue_css', true ) ) {
626
			return false;
627
		}
628
629
		self::register_styles();
630
631
		/*
632
		 * White list the options as this method can be used as a hook callback
633
		 * and have a different argument passed.
634
		 */
635
		return wp_enqueue_style( 'cmb2-display-styles' === $handle ? $handle : 'cmb2-styles' );
636
	}
637
638
	/**
639
	 * Includes CMB2 JS
640
	 * @since  2.0.0
641
	 */
642
	public static function enqueue_cmb_js() {
643
		if ( ! apply_filters( 'cmb2_enqueue_js', true ) ) {
644
			return false;
645
		}
646
647
		self::register_js();
648
		return true;
649
	}
650
651
}
652