Completed
Pull Request — trunk (#593)
by
unknown
13:03
created

CMB2_hookup::term_hooks()   B

Complexity

Conditions 6
Paths 20

Size

Total Lines 35
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

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

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
504
505
		if ( empty( $this->taxonomies ) || ! in_array( $taxonomy, $this->taxonomies ) ) {
506
			return false;
507
		}
508
509
		$taxonomy_object = get_taxonomy( $taxonomy );
510
		// Can the user edit this term?
511
		if ( ! isset( $taxonomy_object->cap ) || ! current_user_can( $taxonomy_object->cap->edit_terms ) ) {
512
			return false;
513
		}
514
515
		return true;
516
	}
517
518
	/**
519
	 * Ensures WordPress hook only gets fired once
520
	 * @since  2.0.0
521
	 * @param string   $action        The name of the filter to hook the $hook callback to.
522
	 * @param callback $hook          The callback to be run when the filter is applied.
523
	 * @param integer  $priority      Order the functions are executed
524
	 * @param int      $accepted_args The number of arguments the function accepts.
525
	 */
526
	public function once( $action, $hook, $priority = 10, $accepted_args = 1 ) {
527
		$key = md5( serialize( func_get_args() ) );
528
529
		if ( in_array( $key, self::$hooks_completed ) ) {
530
			return;
531
		}
532
533
		self::$hooks_completed[] = $key;
534
		add_filter( $action, $hook, $priority, $accepted_args );
535
	}
536
537
	/**
538
	 * Includes CMB2 styles
539
	 * @since  2.0.0
540
	 */
541 1
	public static function enqueue_cmb_css() {
542 1
		if ( ! apply_filters( 'cmb2_enqueue_css', true ) ) {
543
			return false;
544
		}
545
546 1
		self::register_styles();
547 1
		return wp_enqueue_style( 'cmb2-styles' );
548
	}
549
550
	/**
551
	 * Includes CMB2 JS
552
	 * @since  2.0.0
553
	 */
554 1
	public static function enqueue_cmb_js() {
555 1
		if ( ! apply_filters( 'cmb2_enqueue_js', true ) ) {
556
			return false;
557
		}
558
559 1
		self::register_js();
560 1
		return true;
561
	}
562
563
}
564