Completed
Push — master ( 35966e...a20004 )
by Leon
02:49
created

CMB2_Meta_Box::afo()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 3
eloc 2
c 3
b 1
f 0
nc 3
nop 2
dl 0
loc 4
rs 10
1
<?php
2
/**
3
 * CMB2 Meta Box
4
 *
5
 * @since  0.1.0
6
 *
7
 * @category  WordPress_Plugin
8
 * @package   CMB2 Admin Extension
9
 * @author    twoelevenjay
10
 * @license   GPL-2.0+
11
 */
12
13
if ( ! class_exists( 'CMB2_Meta_Box' ) ) {
14
15
	/**
16
	 * Class CMB2_Meta_Box.
17
	 */
18
	class CMB2_Meta_Box {
19
20
		/**
21
		 * Field prefix.
22
		 *
23
		 * @var string
24
		 */
25
		private $prefix = '_cmb2_';
26
27
		/**
28
		 * Instance of this class.
29
		 *
30
		 * @var object
31
		 */
32
		protected static $instance;
33
34
		/**
35
		 * Initiate CMB2 Admin Extension object.
36
		 *
37
		 * @todo For now plugin will use one main object, will consider 3 seperate objects in the future.
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
38
		 * @todo Comment.
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
39
		 *
40
		 * @since 0.0.1
41
		 */
42
		public function __construct() {
43
44
			add_action( 'pre_current_active_plugins', array( $this, 'hide_cmb2_plugins' ) );
45
			add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
46
			add_action( 'cmb2_init', array( $this, 'init_user_defined_meta_boxes_and_fields' ) );
47
		}
48
49
		/**
50
		 * Return an instance of this class.
51
		 *
52
		 * @return object A single instance of this class.
53
		 */
54
		public static function get_instance() {
55
			// If the single instance hasn't been set, set it now.
56
			if ( self::$instance === null ) {
57
				self::$instance = new self;
58
			}
59
60
			return self::$instance;
61
		}
62
63
64
		/**
65
		 * Determine if current user has permission to CMB2 view plugins.
66
		 *
67
		 * @since  0.0.1
68
		 */
69 View Code Duplication
		public function is_cmb2_allowed() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
70
71
			$cmb2_settings = get_option( '_cmb2_settings' );
72
73
			if ( empty( $cmb2_settings ) ) {
74
				// No settings saved.
75
				return true;
76
			}
77
78
			$current_user  = wp_get_current_user();
79
			$allowed_users = isset( $cmb2_settings['_cmb2_user_multicheckbox'] ) ? $cmb2_settings['_cmb2_user_multicheckbox'] : array();
80
81
			if ( empty( $allowed_users ) || in_array( $current_user->ID, $allowed_users, true ) ) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return empty($allowed_us... $allowed_users, true);.
Loading history...
82
83
				return true;
84
			}
85
			return false;
86
		}
87
88
		/**
89
		 * Only show CMB2 plugins to users defined in settings.
90
		 *
91
		 * @since  0.0.1
92
		 */
93
		public function hide_cmb2_plugins() {
94
95
			global $wp_list_table;
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...
96
			if ( ! $this->is_cmb2_allowed() ) {
97
				$to_hide = array( CMB2AE_CMB2_PLUGIN_FILE, 'cmb2-admin-extension/cmb2-admin-extension.php' );
98
				$plugins = $wp_list_table->items;
99
				foreach ( array_keys( $plugins ) as $key ) {
100
					if ( in_array( $key, $to_hide, true ) ) {
101
						unset( $wp_list_table->items[ $key ] );
102
					}
103
				}
104
			}
105
		}
106
107
		/**
108
		 * Enqueue CMB2 Admin Extension scripts and styles.
109
		 *
110
		 * @since  0.0.8
111
		 */
112
		public function enqueue_scripts() {
113
114
			$screen = get_current_screen();
115
			if ( $screen->post_type === 'meta_box' ) {
0 ignored issues
show
introduced by
Found "=== '". Use Yoda Condition checks, you must
Loading history...
116
117
				wp_register_style( 'cmb2_admin_styles', CMB2AE_URI . '/css/meta-box-fields.css', false, '0.0.8' );
118
				wp_enqueue_style( 'cmb2_admin_styles' );
119
				wp_enqueue_script( 'cmb2_admin_scripts', CMB2AE_URI . '/js/meta-box-fields.js', true, array( 'jquery' ), '0.0.8' );
120
			}
121
		}
122
123
		/**
124
		 * Function is_repeatable().
125
		 *
126
		 * @todo Document properly.
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
127
		 * @since  0.0.6
128
		 *
129
		 * @param string $field_type A CMB2 field type.
130
		 */
131
		static function is_repeatable( $field_type ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
132
133
			$repeatable_fields = array(
134
				'text',
135
				'text_small',
136
				'text_medium',
137
				'text_email',
138
				'text_url',
139
				'text_money',
140
				'textarea',
141
				'textarea_small',
142
				'textarea_code',
143
				'text_date',
144
				'text_time',
145
				'select_timezone',
146
				'text_date_timestamp',
147
				'text_datetime_timestamp',
148
				'text_datetime_timestamp_timezone',
149
				'colorpicker',
150
				'select',
151
				'multicheck',
152
				'multicheck_inline',
153
				'file',
154
				'file_list',
155
			);
156
			return in_array( $field_type, $repeatable_fields, true );
157
		}
158
159
		/**
160
		 * Function has_options().
161
		 *
162
		 * @todo Document properly.
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
163
		 * @since  0.0.6
164
		 *
165
		 * @param string $field_type A CMB2 field type.
166
		 */
167
		static function has_options( $field_type ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
168
169
			$options_fields = array(
170
				'radio',
171
				'radio_inline',
172
				'taxonomy_radio',
173
				'taxonomy_radio_inline',
174
				'select',
175
				'taxonomy_select',
176
				'multicheck',
177
				'multicheck_inline',
178
				'taxonomy_multicheck',
179
				'taxonomy_multicheck_inline',
180
			);
181
			return in_array( $field_type, $options_fields, true );
182
		}
183
184
		/**
185
		 * Function afo().
186
		 *
187
		 * @todo Document properly.
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
188
		 * @since  0.0.6
189
		 *
190
		 * @param array  $field      Field definition.
191
		 * @param string $field_type A CMB2 field type.
192
		 */
193
		static function afo( $field, $field_type ) {
0 ignored issues
show
Coding Style introduced by
function afo() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Coding Style introduced by
This method's name is shorter than the configured minimum length of 4 characters.

Even though PHP does not care about the name of your methods, it is generally a good practice to choose method names which can be easily understood by other human readers.

Loading history...
194
195
			return ( in_array( $field['_cmb2_field_type_select'], $field_type, true ) && ( ! empty( $field['_cmb2_add_upload_file_text'] ) && is_string( $field['_cmb2_add_upload_file_text'] ) ) );
196
		}
197
198
		/**
199
		 * Loop through user defined meta_box and creates the custom meta boxes and fields.
200
		 *
201
		 * @since  0.0.1
202
		 */
203
		public function init_user_defined_meta_boxes_and_fields() {
204
205
			$args = array(
206
				'post_type'        => 'meta_box',
207
				'post_status'      => 'publish',
208
				'posts_per_page'   => -1,
0 ignored issues
show
introduced by
Disabling pagination is prohibited in VIP context, do not set posts_per_page to -1 ever.
Loading history...
209
				'suppress_filters' => false,
210
			);
211
212
			$prefix = $this->prefix;
213
214
			$user_meta_boxes = get_posts( $args );
215
216
			foreach ( $user_meta_boxes as $user_meta_box ) {
217
218
				$metabox_id = $user_meta_box->ID;
219
220
				$title          = get_the_title( $metabox_id );
221
				$id             = str_replace( '-', '_', $user_meta_box->post_name );
222
				$post_type      = cmbf( $metabox_id, $prefix . 'post_type_multicheckbox' );
223
				$context        = cmbf( $metabox_id, $prefix . 'context_radio' );
224
				$priority       = cmbf( $metabox_id, $prefix . 'priority_radio' );
225
				$show_names     = cmbf( $metabox_id, $prefix . 'show_names' ) === 'on' ? true : false;
226
				$disable_styles = cmbf( $metabox_id, $prefix . 'disable_styles' ) === 'on' ? true : false;
227
				$closed         = cmbf( $metabox_id, $prefix . 'closed' ) === 'on' ? true : false;
228
				$fields         = cmbf( $metabox_id, $prefix . 'custom_field' );
229
230
				/**
231
				 * Initiate the metabox.
232
				 */
233
				${ 'cmb_' . $id } = new_cmb2_box( array(
234
					'id'           => $id,
235
					'title'        => $title,
236
					'object_types' => $post_type, // Post type.
237
					'context'      => $context,
238
					'priority'     => $priority,
239
					'show_names'   => $show_names,
240
					'cmb_styles'   => $disable_styles,
241
					'closed'       => $closed,
242
				) );
243
244
				foreach ( $fields as $field ) {
245
246
					$field_id = '_' . strtolower( str_replace( ' ', '_', $field['_cmb2_name_text'] ) );
247
248
					$field_args = array(
249
						'name' => $field['_cmb2_name_text'],
250
						'desc' => $field['_cmb2_decription_textarea'],
251
						'id'   => $field_id,
252
						'type' => $field['_cmb2_field_type_select'],
253
					);
254
255
					$options = isset( $field['_cmb2_options_textarea'] ) ? $field['_cmb2_options_textarea'] : false;
256
					if ( $options ) {
257
						$options = explode( PHP_EOL, $options );
258
						foreach ( $options as $option ) {
259
							$opt_arr = explode( ',', $option );
260
							if ( ! isset( $opt_arr[1] ) ) {
261
								continue;
262
							}
263
							$field_options[ $opt_arr[0] ] = $opt_arr[1];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$field_options was never initialized. Although not strictly required by PHP, it is generally a good practice to add $field_options = 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...
264
						}
265
						$field_args['options'] = $field_options;
0 ignored issues
show
Bug introduced by
The variable $field_options 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...
266
					}
267
					if ( strpos( $field['_cmb2_field_type_select'], 'tax' ) !== false  && $field['_cmb2_tax_options_radio_inline'] !== '' ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
268
						$field_args['taxonomy'] = $field['_cmb2_tax_options_radio_inline'];
269
					}
270
					if ( strpos( $field['_cmb2_field_type_select'], 'tax' ) !== false && isset( $field['_cmb2_no_terms_text'] ) && $field['_cmb2_no_terms_text'] !== '' ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
271
						$field_args['options']['no_terms_text'] = $field['_cmb2_no_terms_text'];
272
					}
273
					if ( isset( $field['_cmb2_repeatable_checkbox'] ) && $field['_cmb2_repeatable_checkbox'] === 'on' && $this->is_repeatable( $field['_cmb2_field_type_select'] ) ) {
0 ignored issues
show
introduced by
Found "=== '". Use Yoda Condition checks, you must
Loading history...
274
						$field_args['repeatable'] = true;
275
					}
276
					if ( $field['_cmb2_field_type_select'] === 'url' && isset( $field['_cmb2_protocols_checkbox'] ) && ! empty( $field['_cmb2_protocols_checkbox'] ) ) {
0 ignored issues
show
introduced by
Found "=== '". Use Yoda Condition checks, you must
Loading history...
277
						$field_args['protocols'] = $field['_cmb2_protocols_checkbox'];
278
					}
279
					if ( $this->afo( $field, array( 'text_money' ), '_cmb2_currency_text' ) ) {
0 ignored issues
show
Documentation introduced by
array('text_money') is of type array<integer,string,{"0":"string"}>, but the function expects a string.

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...
Unused Code introduced by
The call to CMB2_Meta_Box::afo() has too many arguments starting with '_cmb2_currency_text'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
280
						$field_args['before_field'] = $field['_cmb2_currency_text'];
281
					}
282
					if ( $this->afo( $field, array( 'text_time' ), '_cmb2_time_format' ) ) {
0 ignored issues
show
Documentation introduced by
array('text_time') is of type array<integer,string,{"0":"string"}>, but the function expects a string.

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...
Unused Code introduced by
The call to CMB2_Meta_Box::afo() has too many arguments starting with '_cmb2_time_format'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
283
						$field_args['time_format'] = $field['_cmb2_time_format'];
284
					}
285
					if ( $this->afo( $field, array( 'text_date', 'text_date_timestamp' ), '_cmb2_date_format' ) ) {
0 ignored issues
show
Documentation introduced by
array('text_date', 'text_date_timestamp') is of type array<integer,string,{"0":"string","1":"string"}>, but the function expects a string.

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...
Unused Code introduced by
The call to CMB2_Meta_Box::afo() has too many arguments starting with '_cmb2_date_format'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
286
						$field_args['date_format'] = $field['_cmb2_date_format'];
287
					}
288
					if ( $this->afo( $field, array( 'text_date_timestamp' ), '_cmb2_time_zone_key_select' ) ) {
0 ignored issues
show
Documentation introduced by
array('text_date_timestamp') is of type array<integer,string,{"0":"string"}>, but the function expects a string.

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...
Unused Code introduced by
The call to CMB2_Meta_Box::afo() has too many arguments starting with '_cmb2_time_zone_key_select'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
289
						$field_args['timezone_meta_key'] = $field['_cmb2_time_zone_key_select'];
290
					}
291
					if ( isset( $field['_cmb2_none_checkbox'] ) && $field['_cmb2_none_checkbox'] === 'on' && $this->has_options( $field['_cmb2_field_type_select'] ) ) {
0 ignored issues
show
introduced by
Found "=== '". Use Yoda Condition checks, you must
Loading history...
292
						$field_args['show_option_none'] = true;
293
					}
294
					if ( strpos( $field['_cmb2_field_type_select'], 'multicheck' ) !== false  && isset( $field['_cmb2_select_all_checkbox'] ) && $field['_cmb2_select_all_checkbox'] === 'on' ) {
0 ignored issues
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
introduced by
Found "=== '". Use Yoda Condition checks, you must
Loading history...
295
						$field_args['select_all_button'] = false;
296
					}
297
					if ( $this->afo( $field, array( 'file' ), '_cmb2_add_upload_file_text' ) ) {
0 ignored issues
show
Documentation introduced by
array('file') is of type array<integer,string,{"0":"string"}>, but the function expects a string.

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...
Unused Code introduced by
The call to CMB2_Meta_Box::afo() has too many arguments starting with '_cmb2_add_upload_file_text'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
298
						$field_args['options']['add_upload_file_text'] = $field['_cmb2_add_upload_file_text'];
299
					}
300
					${ 'cmb_' . $id }->add_field( $field_args );
301
302
				}
303
			}
304
		}
305
	}
306
}
307
308
if ( ! function_exists( 'cmb2ae_metabox' ) ) {
309
	/**
310
	 * Main instance of CMB2_Meta_Box.
311
	 *
312
	 * @since  0.1.0
313
	 */
314
	function cmb2ae_metabox() {
315
		return CMB2_Meta_Box::get_instance();
316
	}
317
}
318