Completed
Pull Request — trunk (#541)
by Justin
11:12
created

CMB2_hookup::save_post()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42
Metric Value
dl 0
loc 19
ccs 0
cts 10
cp 0
rs 8.8571
cc 6
eloc 9
nc 16
nop 2
crap 42
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
	 * Array of all hooks done (to be run once)
18
	 * @var   array
19
	 * @since 2.0.0
20
	 */
21
	protected static $hooks_completed = array();
22
23
	/**
24
	 * Only allow JS registration once
25
	 * @var   bool
26
	 * @since 2.0.7
27
	 */
28
	protected static $js_registration_done = false;
29
30
	/**
31
	 * Only allow CSS registration once
32
	 * @var   bool
33
	 * @since 2.0.7
34
	 */
35
	protected static $css_registration_done = false;
36
37
	/**
38
	 * CMB taxonomies array for term meta
39
	 * @var   array
40
	 * @since 2.2.0
41
	 */
42
	protected $taxonomies = 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
56
		foreach ( get_class_methods( 'CMB2_Show_Filters' ) as $filter ) {
57
			add_filter( 'cmb2_show_on', array( 'CMB2_Show_Filters', $filter ), 10, 3 );
58
		}
59
60
		if ( is_admin() ) {
61
			// register our scripts and styles for cmb
62
			$this->once( 'admin_enqueue_scripts', array( __CLASS__, 'register_scripts' ), 8 );
63
64
			switch ( $this->object_type ) {
65
				case 'post':
66
					return $this->post_hooks();
67
				case 'comment':
68
					return $this->comment_hooks();
69
				case 'user':
70
					return $this->user_hooks();
71
				case 'term':
72
					return $this->term_hooks();
73
			}
74
75
		}
76
	}
77
78
	public function post_hooks() {
79
		add_action( 'add_meta_boxes', array( $this, 'add_metaboxes' ) );
80
		add_action( 'add_attachment', array( $this, 'save_post' ) );
81
		add_action( 'edit_attachment', array( $this, 'save_post' ) );
82
		add_action( 'save_post', array( $this, 'save_post' ), 10, 2 );
83
84
		$this->once( 'admin_enqueue_scripts', array( $this, 'do_scripts' ) );
85
	}
86
87
	public function comment_hooks() {
88
		add_action( 'add_meta_boxes_comment', array( $this, 'add_metaboxes' ) );
89
		add_action( 'edit_comment', array( $this, 'save_comment' ) );
90
91
		$this->once( 'admin_enqueue_scripts', array( $this, 'do_scripts' ) );
92
	}
93
94
	public function user_hooks() {
95
		$priority = $this->get_priority();
96
97
		add_action( 'show_user_profile', array( $this, 'user_metabox' ), $priority );
98
		add_action( 'edit_user_profile', array( $this, 'user_metabox' ), $priority );
99
		add_action( 'user_new_form', array( $this, 'user_new_metabox' ), $priority );
100
101
		add_action( 'personal_options_update', array( $this, 'save_user' ) );
102
		add_action( 'edit_user_profile_update', array( $this, 'save_user' ) );
103
		add_action( 'user_register', array( $this, 'save_user' ) );
104
	}
105
106
	public function term_hooks() {
107
		if ( ! function_exists( 'get_term_meta' ) ) {
108
			wp_die( __( 'Term Metadata is a WordPress > 4.4 feature. Please upgrade your WordPress install.', 'cmb2' ) );
109
		}
110
111
		if ( ! $this->cmb->prop( 'taxonomies' ) ) {
112
			wp_die( __( 'Term metaboxes configuration requires a \'taxonomies\' parameter', 'cmb2' ) );
113
		}
114
115
		$this->taxonomies = (array) $this->cmb->prop( 'taxonomies' );
116
		$show_on_term_add = $this->cmb->prop( 'new_term_section' );
117
		$priority         = $this->get_priority( 8 );
118
119
		foreach ( $this->taxonomies as $taxonomy ) {
120
			// Display our form data
121
			add_action( "{$taxonomy}_edit_form", array( $this, 'term_metabox' ), $priority, 2 );
122
123
			$show_on_add = is_array( $show_on_term_add )
124
				? in_array( $taxonomy, $show_on_term_add )
125
				: (bool) $show_on_term_add;
126
127
			$show_on_add = apply_filters( "cmb2_show_on_term_add_form_{$this->cmb->cmb_id}", $show_on_add, $this->cmb );
128
129
			// Display form in add-new section (unless specified not to)
130
			if ( $show_on_add ) {
131
				add_action( "{$taxonomy}_add_form_fields", array( $this, 'term_metabox' ), $priority, 2 );
132
			}
133
134
		}
135
136
		add_action( 'created_term', array( $this, 'save_term' ), 10, 3 );
137
		add_action( 'edited_terms', array( $this, 'save_term' ), 10, 2 );
138
139
		add_action( 'delete_term', array( $this, 'delete_term' ), 10, 3 );
140
	}
141
142
	/**
143
	 * Registers styles for CMB2
144
	 * @since 2.0.7
145
	 */
146 1
	protected static function register_styles() {
147 1
		if ( self::$css_registration_done ) {
148
			return;
149
		}
150
151
		// Only use minified files if SCRIPT_DEBUG is off
152 1
		$min   = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
153 1
		$front = is_admin() ? '' : '-front';
154 1
		$rtl = is_rtl() ? '-rtl' : '';
155
156
		// Filter required styles and register stylesheet
157 1
		$styles = apply_filters( 'cmb2_style_dependencies', array() );
158 1
		wp_register_style( 'cmb2-styles', cmb2_utils()->url( "css/cmb2{$front}{$rtl}{$min}.css" ), $styles );
159
160 1
		self::$css_registration_done = true;
161 1
	}
162
163
	/**
164
	 * Registers scripts for CMB2
165
	 * @since  2.0.7
166
	 */
167 1
	protected static function register_js() {
168 1
		if ( self::$js_registration_done ) {
169
			return;
170
		}
171
172 1
		$hook = is_admin() ? 'admin_footer' : 'wp_footer';
173 1
		add_action( $hook, array( 'CMB2_JS', 'enqueue' ), 8 );
174
175 1
		self::$js_registration_done = true;
176 1
	}
177
178
	/**
179
	 * Registers scripts and styles for CMB2
180
	 * @since  1.0.0
181
	 */
182
	public static function register_scripts() {
183
		self::register_styles();
184
		self::register_js();
185
	}
186
187
	/**
188
	 * Enqueues scripts and styles for CMB2
189
	 * @since  1.0.0
190
	 */
191
	public function do_scripts( $hook ) {
192
		// only enqueue our scripts/styles on the proper pages
193
		if ( in_array( $hook, array( 'post.php', 'post-new.php', 'page-new.php', 'page.php', 'comment.php' ), true ) ) {
194
			if ( $this->cmb->prop( 'cmb_styles' ) ) {
195
				self::enqueue_cmb_css();
196
			}
197
			if ( $this->cmb->prop( 'enqueue_js' ) ) {
198
				self::enqueue_cmb_js();
199
			}
200
		}
201
	}
202
203
	/**
204
	 * Add metaboxes (to 'post' or 'comment' object types)
205
	 * @since 1.0.0
206
	 */
207
	public function add_metaboxes() {
208
209
		if ( ! $this->show_on() ) {
210
			return;
211
		}
212
213
		foreach ( $this->cmb->prop( 'object_types' ) as $post_type ) {
214
			/**
215
			 * To keep from registering an actual post-screen metabox,
216
			 * omit the 'title' attribute from the metabox registration array.
217
			 *
218
			 * (WordPress will not display metaboxes without titles anyway)
219
			 *
220
			 * This is a good solution if you want to output your metaboxes
221
			 * Somewhere else in the post-screen
222
			 */
223
			if ( $this->cmb->prop( 'title' ) ) {
224
225
				if ( $this->cmb->prop( 'closed' ) ) {
226
					add_filter( "postbox_classes_{$post_type}_{$this->cmb->cmb_id}", array( $this, 'close_metabox_class' ) );
227
				}
228
229
				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' ) );
230
			}
231
		}
232
	}
233
234
	/**
235
	 * Add 'closed' class to metabox
236
	 * @since  2.0.0
237
	 * @param  array  $classes Array of classes
238
	 * @return array           Modified array of classes
239
	 */
240
	public function close_metabox_class( $classes ) {
241
		$classes[] = 'closed';
242
		return $classes;
243
	}
244
245
	/**
246
	 * Display metaboxes for a post or comment object
247
	 * @since  1.0.0
248
	 */
249
	public function metabox_callback() {
250
		$object_id = 'comment' == $this->object_type ? get_comment_ID() : get_the_ID();
251
		$this->cmb->show_form( $object_id, $this->object_type );
252
	}
253
254
	/**
255
	 * Display metaboxes for new user page
256
	 * @since  1.0.0
257
	 */
258
	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...
259
		if ( $section == $this->cmb->prop( 'new_user_section' ) ) {
260
			$object_id = $this->cmb->object_id();
261
			$this->cmb->object_id( isset( $_REQUEST['user_id'] ) ? $_REQUEST['user_id'] : $object_id );
262
			$this->user_metabox();
263
		}
264
	}
265
266
	/**
267
	 * Display metaboxes for a user object
268
	 * @since  1.0.0
269
	 */
270
	public function user_metabox() {
271
		$this->show_form_for_type( 'user' );
272
	}
273
274
	/**
275
	 * Display metaboxes for a taxonomy term object
276
	 * @since  2.2.0
277
	 */
278
	public function term_metabox() {
279
		$this->show_form_for_type( 'term' );
280
	}
281
282
	/**
283
	 * Display metaboxes for an object type
284
	 * @since  2.2.0
285
	 * @param  string $type Object type
286
	 * @return void
287
	 */
288
	public function show_form_for_type( $type ) {
289
		if ( $type != $this->cmb->mb_object_type() ) {
290
			return;
291
		}
292
293
		if ( ! $this->show_on() ) {
294
			return;
295
		}
296
297
		if ( $this->cmb->prop( 'cmb_styles' ) ) {
298
			self::enqueue_cmb_css();
299
		}
300
		if ( $this->cmb->prop( 'enqueue_js' ) ) {
301
			self::enqueue_cmb_js();
302
		}
303
304
		$this->cmb->show_form( 0, $type );
305
	}
306
307
	/**
308
	 * Determines if metabox should be shown in current context
309
	 * @since  2.0.0
310
	 * @return bool Whether metabox should be added/shown
311
	 */
312
	public function show_on() {
313
		// If metabox is requesting to be conditionally shown
314
		$show = $this->cmb->should_show();
315
316
		/**
317
		 * Filter to determine if metabox should show. Default is true
318
		 *
319
		 * @param array  $show          Default is true, show the metabox
320
		 * @param mixed  $meta_box_args Array of the metabox arguments
321
		 * @param mixed  $cmb           The CMB2 instance
322
		 */
323
		$show = (bool) apply_filters( 'cmb2_show_on', $show, $this->cmb->meta_box, $this->cmb );
324
325
		return $show;
326
	}
327
328
	/**
329
	 * Get the CMB priority property set to numeric hook priority.
330
	 * @since  2.2.0
331
	 * @param  integer $default Default display hook priority.
332
	 * @return integer          Hook priority.
333
	 */
334
	public function get_priority( $default = 10 ) {
335
		$priority = $this->cmb->prop( 'priority' );
336
337
		if ( ! is_numeric( $priority ) ) {
338
			switch ( $priority ) {
339
340
				case 'high':
341
					$priority = 5;
342
					break;
343
344
				case 'low':
345
					$priority = 20;
346
					break;
347
348
				default:
349
					$priority = $default;
350
					break;
351
			}
352
		}
353
354
		return $priority;
355
	}
356
357
	/**
358
	 * Save data from post metabox
359
	 * @since  1.0.0
360
	 * @param  int    $post_id Post ID
361
	 * @param  mixed  $post    Post object
362
	 * @return null
363
	 */
364
	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...
365
366
		$post_type = $post ? $post->post_type : get_post_type( $post_id );
367
368
		$do_not_pass_go = (
369
			! $this->can_save( $post_type )
370
			// check user editing permissions
371
			|| ( 'page' == $post_type && ! current_user_can( 'edit_page', $post_id ) )
372
			|| ! current_user_can( 'edit_post', $post_id )
373
		);
374
375
		if ( $do_not_pass_go ) {
376
			// do not collect $200
377
			return;
378
		}
379
380
		// take a trip to reading railroad – if you pass go collect $200
381
		$this->cmb->save_fields( $post_id, 'post', $_POST );
382
	}
383
384
	/**
385
	 * Save data from comment metabox
386
	 * @since  2.0.9
387
	 * @param  int    $comment_id Comment ID
388
	 * @return null
389
	 */
390
	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...
391
392
		$can_edit = current_user_can( 'moderate_comments', $comment_id );
393
394
		if ( $this->can_save( get_comment_type( $comment_id ) ) && $can_edit ) {
395
			$this->cmb->save_fields( $comment_id, 'comment', $_POST );
396
		}
397
	}
398
399
	/**
400
	 * Save data from user fields
401
	 * @since  1.0.x
402
	 * @param  int   $user_id  User ID
403
	 * @return null
404
	 */
405
	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...
406
		// check permissions
407
		if ( $this->can_save( 'user' ) ) {
408
			$this->cmb->save_fields( $user_id, 'user', $_POST );
409
		}
410
	}
411
412
	/**
413
	 * Save data from term fields
414
	 * @since  2.2.0
415
	 * @param  int    $term_id  Term ID
416
	 * @param  int    $tt_id    Term Taxonomy ID
417
	 * @param  string $taxonomy Taxonomy
418
	 * @return null
419
	 */
420
	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...
421
		$taxonomy = $taxonomy ? $taxonomy : $tt_id;
422
423
		// check permissions
424
		if ( $this->taxonomy_can_save( $taxonomy ) && $this->can_save( 'term' ) ) {
425
			$this->cmb->save_fields( $term_id, 'term', $_POST );
426
		}
427
	}
428
429
	/**
430
	 * Delete term meta when a term is deleted.
431
	 * @since  2.2.0
432
	 * @param  int    $term_id  Term ID
433
	 * @param  int    $tt_id    Term Taxonomy ID
434
	 * @param  string $taxonomy Taxonomy
435
	 * @return null
436
	 */
437
	public function delete_term( $term_id, $tt_id, $taxonomy = '' ) {
438
		if ( $this->taxonomy_can_save( $taxonomy ) ) {
439
440
			foreach ( $this->cmb->prop( 'fields' ) as $field ) {
441
				$data_to_delete[ $field['id'] ] = '';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$data_to_delete was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data_to_delete = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
442
			}
443
444
			$this->cmb->save_fields( $term_id, 'term', $data_to_delete );
0 ignored issues
show
Bug introduced by
The variable $data_to_delete does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
445
		}
446
	}
447
448
	/**
449
	 * Determines if the current object is able to be saved
450
	 * @since  2.0.9
451
	 * @param  string  $type Current post_type or comment_type
452
	 * @return bool          Whether object can be saved
453
	 */
454
	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...
455
		return (
456
			$this->cmb->prop( 'save_fields' )
457
			// check nonce
458
			&& isset( $_POST[ $this->cmb->nonce() ] )
459
			&& wp_verify_nonce( $_POST[ $this->cmb->nonce() ], $this->cmb->nonce() )
460
			// check if autosave
461
			&& ! ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
462
			// get the metabox types & compare it to this type
463
			&& ( $type && in_array( $type, $this->cmb->prop( 'object_types' ) ) )
464
		);
465
	}
466
467
	/**
468
	 * Determine if taxonomy of term being modified is cmb2-editable.
469
	 * @since  2.2.0
470
	 * @param  string $taxonomy Taxonomy of term being modified.
471
	 * @return bool             Whether taxonomy is editable.
472
	 */
473
	public function taxonomy_can_save( $taxonomy ) {
474
		if ( empty( $this->taxonomies ) || ! in_array( $taxonomy, $this->taxonomies ) ) {
475
			return false;
476
		}
477
478
		$taxonomy_object = get_taxonomy( $taxonomy );
479
		// Can the user edit this term?
480
		if ( ! isset( $taxonomy_object->cap ) || ! current_user_can( $taxonomy_object->cap->edit_terms ) ) {
481
			return false;
482
		}
483
484
		return true;
485
	}
486
487
	/**
488
	 * Includes CMB2 styles
489
	 * @since  2.0.0
490
	 */
491 1
	public static function enqueue_cmb_css() {
492 1
		if ( ! apply_filters( 'cmb2_enqueue_css', true ) ) {
493
			return false;
494
		}
495
496 1
		self::register_styles();
497 1
		return wp_enqueue_style( 'cmb2-styles' );
498
	}
499
500
	/**
501
	 * Includes CMB2 JS
502
	 * @since  2.0.0
503
	 */
504 1
	public static function enqueue_cmb_js() {
505 1
		if ( ! apply_filters( 'cmb2_enqueue_js', true ) ) {
506
			return false;
507
		}
508
509 1
		self::register_js();
510 1
		return true;
511
	}
512
513
}
514