Completed
Push — trunk ( ddc286...f54c26 )
by Justin
07:14
created

CMB2_Base::maybe_callback()   B

Complexity

Conditions 6
Paths 13

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 10
c 1
b 0
f 0
nc 13
nop 1
dl 0
loc 20
rs 8.8571
ccs 10
cts 10
cp 1
crap 6
1
<?php
2
/**
3
 * CMB2 Base - Base object functionality.
4
 *
5
 * @category  WordPress_Plugin
6
 * @package   CMB2
7
 * @author    WebDevStudios
8
 * @license   GPL-2.0+
9
 * @link      http://webdevstudios.com
10
 */
11
abstract class CMB2_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...
12
13
	/**
14
	 * Current CMB2 instance ID
15
	 * @var   string
16
	 * @since 2.2.3
17
	 */
18
	protected $cmb_id = '';
19
20
	/**
21
	 * The deprecated object properties name.
22
	 * @var   string
23
	 * @since 2.2.3
24
	 */
25
	protected $properties_name = 'meta_box';
26
27
	/**
28
	 * Object ID
29
	 * @var   mixed
30
	 * @since 2.2.3
31
	 */
32
	protected $object_id = 0;
33
34
	/**
35
	 * Type of object being handled. (e.g., post, user, comment, or term)
36
	 * @var   string
37
	 * @since 2.2.3
38
	 */
39
	protected $object_type = 'post';
40
41
	/**
42
	 * Array of key => value data for saving. Likely $_POST data.
43
	 * @var   array
44
	 * @since 2.2.3
45
	 */
46
	public $data_to_save = array();
47
48
	/**
49
	 * Array of field param callback results
50
	 * @var   array
51
	 * @since 2.0.0
52
	 */
53
	protected $callback_results = array();
54
55
	/**
56
	 * Get started
57
	 * @since 2.2.3
58
	 * @param array $args Object properties array
59
	 */
60
	public function __construct( $args = array() ) {
61
		if ( ! empty( $args ) ) {
62
			foreach ( array(
63
				'cmb_id',
64
				'properties_name',
65
				'object_id',
66
				'object_type',
67
				'data_to_save',
68
			) as $object_prop ) {
69
				if ( isset( $args[ $object_prop ] ) ) {
70
					$this->{$object_prop} = $args[ $object_prop ];
71
				}
72
			}
73
		}
74
	}
75
76
	/**
77
	 * Returns the object ID
78
	 * @since  2.2.3
79
	 * @param  integer $object_id Object ID
80
	 * @return integer Object ID
81
	 */
82 5
	public function object_id( $object_id = 0 ) {
83 5
		if ( $object_id ) {
84
			$this->object_id = $object_id;
85
		}
86
87 5
		return $this->object_id;
88
	}
89
90
	/**
91
	 * Returns the object type
92
	 * @since  2.2.3
93
	 * @param  string $object_type Object Type
94
	 * @return string Object type
95
	 */
96 5
	public function object_type( $object_type = '' ) {
97 5
		if ( $object_type ) {
98
			$this->object_type = $object_type;
99
		}
100
101 5
		return $this->object_type;
102
	}
103
104
	/**
105
	 * Get the object type for the current page, based on the $pagenow global.
106
	 * @since  2.2.2
107
	 * @return string  Page object type name.
108
	 */
109 View Code Duplication
	public function current_object_type() {
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...
110
		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...
111
		$type = 'post';
112
113
		if ( in_array( $pagenow, array( 'user-edit.php', 'profile.php', 'user-new.php' ), true ) ) {
114
			$type = 'user';
115
		}
116
117
		if ( in_array( $pagenow, array( 'edit-comments.php', 'comment.php' ), true ) ) {
118
			$type = 'comment';
119
		}
120
121
		if ( in_array( $pagenow, array( 'edit-tags.php', 'term.php' ), true ) ) {
122
			$type = 'term';
123
		}
124
125
		return $type;
126
	}
127
128
	/**
129
	 * Set object property.
130
	 * @since  2.2.2
131
	 * @param  string $property Metabox config property to retrieve
132
	 * @param  mixed  $value    Value to set if no value found
133
	 * @return mixed            Metabox config property value or false
134
	 */
135
	public function set_prop( $property, $value ) {
136
		$this->{$this->properties_name}[ $property ] = $value;
137
138
		return $this->prop( $property );
139
	}
140
141
	/**
142
	 * Get object property and optionally set a fallback
143
	 * @since  2.0.0
144
	 * @param  string $property Metabox config property to retrieve
145
	 * @param  mixed  $fallback Fallback value to set if no value found
146
	 * @return mixed            Metabox config property value or false
147
	 */
148 43
	public function prop( $property, $fallback = null ) {
149 43
		if ( array_key_exists( $property, $this->{$this->properties_name} ) ) {
150 1
			return $this->{$this->properties_name}[ $property ];
151 42
		} elseif ( $fallback ) {
152
			return $this->{$this->properties_name}[ $property ] = $fallback;
153
		}
154 42
	}
155
156
	/**
157
	 * Get default field arguments specific to this CMB2 object.
158
	 * @since  2.2.0
159
	 * @param  array      $field_args  Metabox field config array.
160
	 * @param  CMB2_Field $field_group (optional) CMB2_Field object (group parent)
161
	 * @return array                   Array of field arguments.
162
	 */
163 5 View Code Duplication
	protected function get_default_args( $field_args, $field_group = null ) {
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...
164 5
		if ( $field_group ) {
165
			$args = array(
166
				'field_args'  => $field_args,
167
				'group_field' => $field_group,
168
			);
169
		} else {
170
			$args = array(
171 5
				'field_args'  => $field_args,
172 5
				'object_type' => $this->object_type(),
173 5
				'object_id'   => $this->object_id(),
174 5
				'cmb_id'      => $this->cmb_id,
175 5
			);
176
		}
177
178 5
		return $args;
179
	}
180
181
	/**
182
	 * Get a new field object specific to this CMB2 object.
183
	 * @since  2.2.0
184
	 * @param  array      $field_args  Metabox field config array.
185
	 * @param  CMB2_Field $field_group (optional) CMB2_Field object (group parent)
186
	 * @return CMB2_Field CMB2_Field object
187
	 */
188 5
	protected function get_new_field( $field_args, $field_group = null ) {
189 5
		return new CMB2_Field( $this->get_default_args( $field_args, $field_group ) );
190
	}
191
192
	/**
193
	 * Determine whether this cmb object should show, based on the 'show_on_cb' callback.
194
	 *
195
	 * @since 2.0.9
196
	 *
197
	 * @return bool Whether this cmb should be shown.
198
	 */
199 43
	public function should_show() {
200
		// Default to showing this cmb
201 43
		$show = true;
202
203
		// Use the callback to determine showing the cmb, if it exists
204 43
		if ( is_callable( $this->prop( 'show_on_cb' ) ) ) {
205 1
			$show = (bool) call_user_func( $this->prop( 'show_on_cb' ), $this );
206 1
		}
207
208 43
		return $show;
209
	}
210
211
	/**
212
	 * Displays the results of the param callbacks.
213
	 *
214
	 * @since 2.0.0
215
	 * @param string $param Field parameter
216
	 */
217 80
	public function peform_param_callback( $param ) {
218 80
		echo $this->get_param_callback_result( $param );
219 80
	}
220
221
	/**
222
	 * Store results of the param callbacks for continual access
223
	 * @since  2.0.0
224
	 * @param  string $param Field parameter
225
	 * @return mixed         Results of param/param callback
226
	 */
227 85
	public function get_param_callback_result( $param ) {
228
229
		// If we've already retrieved this param's value,
230 85
		if ( array_key_exists( $param, $this->callback_results ) ) {
231
232
			// send it back
233 10
			return $this->callback_results[ $param ];
234
		}
235
236
		// Check if parameter has registered a callback.
237 85
		if ( $cb = $this->maybe_callback( $param ) ) {
238
239
			// Ok, callback is good, let's run it and store the result.
240 49
			ob_start();
241 49
			$returned = $this->do_callback( $cb );
242
243
			// Grab the result from the output buffer and store it.
244 49
			$echoed = ob_get_clean();
245
246
			// This checks if the user returned or echoed their callback.
247
			// Defaults to using the echoed value.
248 49
			$this->callback_results[ $param ] = $echoed ? $echoed : $returned;
249
250 49
		} else {
251
252
			// Otherwise just get whatever is there.
253 80
			$this->callback_results[ $param ] = isset( $this->{$this->properties_name}[ $param ] ) ? $this->{$this->properties_name}[ $param ] : false;
254
		}
255
256 85
		return $this->callback_results[ $param ];
257
	}
258
259
	/**
260
	 * Handles the property callbacks, and passes this object as property.
261
	 * @since  2.2.3
262
	 * @param  callable $cb The callback method/function/closure
263
	 * @return mixed        Return of the callback function.
264
	 */
265 49
	protected function do_callback( $cb ) {
266 49
		return call_user_func( $cb, $this->{$this->properties_name}, $this );
267
	}
268
269
	/**
270
	 * Checks if field has a callback value
271
	 * @since  1.0.1
272
	 * @param  string $cb Callback string
273
	 * @return mixed      NULL, false for NO validation, or $cb string if it exists.
274
	 */
275 96
	public function maybe_callback( $cb ) {
276 96
		$args = $this->{$this->properties_name};
277 96
		if ( ! isset( $args[ $cb ] ) ) {
278 89
			return;
279
		}
280
281
		// Check if requesting explicitly false
282 50
		$cb = false !== $args[ $cb ] && 'false' !== $args[ $cb ] ? $args[ $cb ] : false;
283
284
		// If requesting NO validation, return false
285 50
		if ( ! $cb ) {
286 9
			return false;
287
		}
288
289 50
		if ( is_callable( $cb ) ) {
290 49
			return $cb;
291
		}
292
293 5
		return false;
294
	}
295
296
	/**
297
	 * Magic getter for our object.
298
	 * @param string $field
299
	 * @throws Exception Throws an exception if the field is invalid.
300
	 * @return mixed
301
	 */
302 63
	public function __get( $field ) {
303
		switch ( $field ) {
304 63
			case 'args':
305 63
			case 'meta_box':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
306 3
				if ( $field === $this->properties_name ) {
307 3
					return $this->{$this->properties_name};
308
				}
309 63
			case 'properties':
310
				return $this->{$this->properties_name};
311 63
			case 'cmb_id':
312 63
			case 'object_id':
313 63
			case 'object_type':
314 63
				return $this->{$field};
315 2
			default:
316 2
				throw new Exception( 'Invalid ' . __CLASS__ . ' property: ' . $field );
317 2
		}
318
	}
319
320
}
321