PluginProbe
Cool Flipbox – Shortcode & Gutenberg Block / 1.4
Cool Flipbox – Shortcode & Gutenberg Block v1.4
trunk 1.4 1.5 1.6 1.6.2 1.7.1 1.8.3 1.9.0 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1
flip-boxes / CMB2 / includes / CMB2_Base.php

CMB2_Base.php in Cool Flipbox – Shortcode & Gutenberg Block 1.4, at CMB2/includes/CMB2_Base.php

534 lines 15.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * CMB2 Base - Base object functionality.
4 *
5 * @category WordPress_Plugin
6 * @package CMB2
7 * @author CMB2 team
8 * @license GPL-2.0+
9 * @link https://cmb2.io
10 *
11 * @property-read $args The objects array of properties/arguments.
12 * @property-read $meta_box The objects array of properties/arguments.
13 * @property-read $properties The objects array of properties/arguments.
14 * @property-read $cmb_id Current CMB2 instance ID
15 * @property-read $object_id Object ID
16 * @property-read $object_type Type of object being handled. (e.g., post, user, comment, or term)
17 */
18 abstract class CMB2_Base {
19
20 /**
21 * Current CMB2 instance ID
22 *
23 * @var string
24 * @since 2.2.3
25 */
26 protected $cmb_id = '';
27
28 /**
29 * The object properties name.
30 *
31 * @var string
32 * @since 2.2.3
33 */
34 protected $properties_name = 'meta_box';
35
36 /**
37 * Object ID
38 *
39 * @var mixed
40 * @since 2.2.3
41 */
42 protected $object_id = 0;
43
44 /**
45 * Type of object being handled. (e.g., post, user, comment, or term)
46 *
47 * @var string
48 * @since 2.2.3
49 */
50 protected $object_type = '';
51
52 /**
53 * Array of key => value data for saving. Likely $_POST data.
54 *
55 * @var array
56 * @since 2.2.3
57 */
58 public $data_to_save = array();
59
60 /**
61 * Array of field param callback results
62 *
63 * @var array
64 * @since 2.0.0
65 */
66 protected $callback_results = array();
67
68 /**
69 * The deprecated_param method deprecated param message signature.
70 */
71 const DEPRECATED_PARAM = 1;
72
73 /**
74 * The deprecated_param method deprecated callback param message signature.
75 */
76 const DEPRECATED_CB_PARAM = 2;
77
78 /**
79 * Get started
80 *
81 * @since 2.2.3
82 * @param array $args Object properties array.
83 */
84 public function __construct( $args = array() ) {
85 if ( ! empty( $args ) ) {
86 foreach ( array(
87 'cmb_id',
88 'properties_name',
89 'object_id',
90 'object_type',
91 'data_to_save',
92 ) as $object_prop ) {
93 if ( isset( $args[ $object_prop ] ) ) {
94 $this->{$object_prop} = $args[ $object_prop ];
95 }
96 }
97 }
98 }
99
100 /**
101 * Returns the object ID
102 *
103 * @since 2.2.3
104 * @param integer $object_id Object ID.
105 * @return integer Object ID
106 */
107 public function object_id( $object_id = 0 ) {
108 if ( $object_id ) {
109 $this->object_id = $object_id;
110 }
111
112 return $this->object_id;
113 }
114
115 /**
116 * Returns the object type
117 *
118 * @since 2.2.3
119 * @param string $object_type Object Type.
120 * @return string Object type
121 */
122 public function object_type( $object_type = '' ) {
123 if ( $object_type ) {
124 $this->object_type = $object_type;
125 }
126
127 return $this->object_type;
128 }
129
130 /**
131 * Get the object type for the current page, based on the $pagenow global.
132 *
133 * @since 2.2.2
134 * @return string Page object type name.
135 */
136 public function current_object_type() {
137 global $pagenow;
138 $type = 'post';
139
140 if ( in_array( $pagenow, array( 'user-edit.php', 'profile.php', 'user-new.php' ), true ) ) {
141 $type = 'user';
142 }
143
144 if ( in_array( $pagenow, array( 'edit-comments.php', 'comment.php' ), true ) ) {
145 $type = 'comment';
146 }
147
148 if ( in_array( $pagenow, array( 'edit-tags.php', 'term.php' ), true ) ) {
149 $type = 'term';
150 }
151
152 return $type;
153 }
154
155 /**
156 * Set object property.
157 *
158 * @since 2.2.2
159 * @param string $property Metabox config property to retrieve.
160 * @param mixed $value Value to set if no value found.
161 * @return mixed Metabox config property value or false.
162 */
163 public function set_prop( $property, $value ) {
164 $this->{$this->properties_name}[ $property ] = $value;
165
166 return $this->prop( $property );
167 }
168
169 /**
170 * Get object property and optionally set a fallback
171 *
172 * @since 2.0.0
173 * @param string $property Metabox config property to retrieve.
174 * @param mixed $fallback Fallback value to set if no value found.
175 * @return mixed Metabox config property value or false
176 */
177 public function prop( $property, $fallback = null ) {
178 if ( array_key_exists( $property, $this->{$this->properties_name} ) ) {
179 return $this->{$this->properties_name}[ $property ];
180 } elseif ( $fallback ) {
181 return $this->{$this->properties_name}[ $property ] = $fallback;
182 }
183 }
184
185 /**
186 * Get default field arguments specific to this CMB2 object.
187 *
188 * @since 2.2.0
189 * @param array $field_args Metabox field config array.
190 * @param CMB2_Field $field_group (optional) CMB2_Field object (group parent).
191 * @return array Array of field arguments.
192 */
193 protected function get_default_args( $field_args, $field_group = null ) {
194 if ( $field_group ) {
195 $args = array(
196 'field_args' => $field_args,
197 'group_field' => $field_group,
198 );
199 } else {
200 $args = array(
201 'field_args' => $field_args,
202 'object_type' => $this->object_type(),
203 'object_id' => $this->object_id(),
204 'cmb_id' => $this->cmb_id,
205 );
206 }
207
208 return $args;
209 }
210
211 /**
212 * Get a new field object specific to this CMB2 object.
213 *
214 * @since 2.2.0
215 * @param array $field_args Metabox field config array.
216 * @param CMB2_Field $field_group (optional) CMB2_Field object (group parent).
217 * @return CMB2_Field CMB2_Field object
218 */
219 protected function get_new_field( $field_args, $field_group = null ) {
220 return new CMB2_Field( $this->get_default_args( $field_args, $field_group ) );
221 }
222
223 /**
224 * Determine whether this cmb object should show, based on the 'show_on_cb' callback.
225 *
226 * @since 2.0.9
227 *
228 * @return bool Whether this cmb should be shown.
229 */
230 public function should_show() {
231 // Default to showing this cmb
232 $show = true;
233
234 // Use the callback to determine showing the cmb, if it exists.
235 if ( is_callable( $this->prop( 'show_on_cb' ) ) ) {
236 $show = (bool) call_user_func( $this->prop( 'show_on_cb' ), $this );
237 }
238
239 return $show;
240 }
241
242 /**
243 * Displays the results of the param callbacks.
244 *
245 * @since 2.0.0
246 * @param string $param Field parameter.
247 */
248 public function peform_param_callback( $param ) {
249 echo $this->get_param_callback_result( $param );
250 }
251
252 /**
253 * Store results of the param callbacks for continual access
254 *
255 * @since 2.0.0
256 * @param string $param Field parameter.
257 * @return mixed Results of param/param callback
258 */
259 public function get_param_callback_result( $param ) {
260
261 // If we've already retrieved this param's value.
262 if ( array_key_exists( $param, $this->callback_results ) ) {
263
264 // Send it back.
265 return $this->callback_results[ $param ];
266 }
267
268 // Check if parameter has registered a callback.
269 if ( $cb = $this->maybe_callback( $param ) ) {
270
271 // Ok, callback is good, let's run it and store the result.
272 ob_start();
273 $returned = $this->do_callback( $cb );
274
275 // Grab the result from the output buffer and store it.
276 $echoed = ob_get_clean();
277
278 // This checks if the user returned or echoed their callback.
279 // Defaults to using the echoed value.
280 $this->callback_results[ $param ] = $echoed ? $echoed : $returned;
281
282 } else {
283
284 // Otherwise just get whatever is there.
285 $this->callback_results[ $param ] = isset( $this->{$this->properties_name}[ $param ] ) ? $this->{$this->properties_name}[ $param ] : false;
286 }
287
288 return $this->callback_results[ $param ];
289 }
290
291 /**
292 * Unset the cached results of the param callback.
293 *
294 * @since 2.2.6
295 * @param string $param Field parameter.
296 * @return CMB2_Base
297 */
298 public function unset_param_callback_cache( $param ) {
299 if ( isset( $this->callback_results[ $param ] ) ) {
300 unset( $this->callback_results[ $param ] );
301 }
302
303 return $this;
304 }
305
306 /**
307 * Handles the parameter callbacks, and passes this object as parameter.
308 *
309 * @since 2.2.3
310 * @param callable $cb The callback method/function/closure.
311 * @param mixed $additional_params Any additoinal parameters which should be passed to the callback.
312 * @return mixed Return of the callback function.
313 */
314 protected function do_callback( $cb, $additional_params = null ) {
315 return call_user_func( $cb, $this->{$this->properties_name}, $this, $additional_params );
316 }
317
318 /**
319 * Checks if field has a callback value
320 *
321 * @since 1.0.1
322 * @param string $cb Callback string.
323 * @return mixed NULL, false for NO validation, or $cb string if it exists.
324 */
325 public function maybe_callback( $cb ) {
326 $args = $this->{$this->properties_name};
327 if ( ! isset( $args[ $cb ] ) ) {
328 return null;
329 }
330
331 // Check if requesting explicitly false.
332 $cb = false !== $args[ $cb ] && 'false' !== $args[ $cb ] ? $args[ $cb ] : false;
333
334 // If requesting NO validation, return false.
335 if ( ! $cb ) {
336 return false;
337 }
338
339 if ( is_callable( $cb ) ) {
340 return $cb;
341 }
342
343 return null;
344 }
345
346 /**
347 * Checks if this object has parameter corresponding to the given filter
348 * which is callable. If so, it registers the callback, and if not,
349 * converts the maybe-modified $val to a boolean for return.
350 *
351 * The registered handlers will have a parameter name which matches the filter, except:
352 * - The 'cmb2_api' prefix will be removed
353 * - A '_cb' suffix will be added (to stay inline with other '*_cb' parameters).
354 *
355 * @since 2.2.3
356 *
357 * @param string $hook_name The hook name.
358 * @param bool $val The default value.
359 * @param string $hook_function The hook function. Default: 'add_filter'.
360 *
361 * @return null|bool Null if hook is registered, or bool for value.
362 */
363 public function maybe_hook_parameter( $hook_name, $val = null, $hook_function = 'add_filter' ) {
364
365 // Remove filter prefix, add param suffix.
366 $parameter = substr( $hook_name, strlen( 'cmb2_api_' ) ) . '_cb';
367
368 return self::maybe_hook(
369 $this->prop( $parameter, $val ),
370 $hook_name,
371 $hook_function
372 );
373 }
374
375 /**
376 * Checks if given value is callable, and registers the callback.
377 * If is non-callable, converts the $val to a boolean for return.
378 *
379 * @since 2.2.3
380 *
381 * @param bool $val The default value.
382 * @param string $hook_name The hook name.
383 * @param string $hook_function The hook function.
384 *
385 * @return null|bool Null if hook is registered, or bool for value.
386 */
387 public static function maybe_hook( $val, $hook_name, $hook_function ) {
388 if ( is_callable( $val ) ) {
389 call_user_func( $hook_function, $hook_name, $val, 10, 2 );
390 return null;
391 }
392
393 // Cast to bool.
394 return ! ! $val;
395 }
396
397 /**
398 * Mark a param as deprecated and inform when it has been used.
399 *
400 * There is a default WordPress hook deprecated_argument_run that will be called
401 * that can be used to get the backtrace up to what file and function used the
402 * deprecated argument.
403 *
404 * The current behavior is to trigger a user error if WP_DEBUG is true.
405 *
406 * @since 2.2.3
407 *
408 * @param string $function The function that was called.
409 * @param string $version The version of CMB2 that deprecated the argument used.
410 * @param string $message Optional. A message regarding the change, or numeric
411 * key to generate message from additional arguments.
412 * Default null.
413 */
414 protected function deprecated_param( $function, $version, $message = null ) {
415
416 if ( is_numeric( $message ) ) {
417 $args = func_get_args();
418
419 switch ( $message ) {
420
421 case self::DEPRECATED_PARAM:
422 $message = sprintf( __( 'The "%1$s" field parameter has been deprecated in favor of the "%2$s" parameter.', 'cmb2' ), $args[3], $args[4] );
423 break;
424
425 case self::DEPRECATED_CB_PARAM:
426 $message = sprintf( __( 'Using the "%1$s" field parameter as a callback has been deprecated in favor of the "%2$s" parameter.', 'cmb2' ), $args[3], $args[4] );
427 break;
428
429 default:
430 $message = null;
431 break;
432 }
433 }
434
435 /**
436 * Fires when a deprecated argument is called. This is a WP core action.
437 *
438 * @since 2.2.3
439 *
440 * @param string $function The function that was called.
441 * @param string $message A message regarding the change.
442 * @param string $version The version of CMB2 that deprecated the argument used.
443 */
444 do_action( 'deprecated_argument_run', $function, $message, $version );
445
446 /**
447 * Filters whether to trigger an error for deprecated arguments. This is a WP core filter.
448 *
449 * @since 2.2.3
450 *
451 * @param bool $trigger Whether to trigger the error for deprecated arguments. Default true.
452 */
453 if ( defined( 'WP_DEBUG' ) && WP_DEBUG && apply_filters( 'deprecated_argument_trigger_error', true ) ) {
454 if ( function_exists( '__' ) ) {
455 if ( ! is_null( $message ) ) {
456 trigger_error( sprintf( __( '%1$s was called with a parameter that is <strong>deprecated</strong> since version %2$s! %3$s', 'cmb2' ), $function, $version, $message ) );
457 } else {
458 trigger_error( sprintf( __( '%1$s was called with a parameter that is <strong>deprecated</strong> since version %2$s with no alternative available.', 'cmb2' ), $function, $version ) );
459 }
460 } else {
461 if ( ! is_null( $message ) ) {
462 trigger_error( sprintf( '%1$s was called with a parameter that is <strong>deprecated</strong> since version %2$s! %3$s', $function, $version, $message ) );
463 } else {
464 trigger_error( sprintf( '%1$s was called with a parameter that is <strong>deprecated</strong> since version %2$s with no alternative available.', $function, $version ) );
465 }
466 }
467 }
468 }
469
470 /**
471 * Magic getter for our object.
472 *
473 * @param string $field Requested property.
474 * @throws Exception Throws an exception if the field is invalid.
475 * @return mixed
476 */
477 public function __get( $field ) {
478 switch ( $field ) {
479 case 'args':
480 case 'meta_box':
481 if ( $field === $this->properties_name ) {
482 return $this->{$this->properties_name};
483 }
484 case 'properties':
485 return $this->{$this->properties_name};
486 case 'cmb_id':
487 case 'object_id':
488 case 'object_type':
489 return $this->{$field};
490 default:
491 throw new Exception( sprintf( esc_html__( 'Invalid %1$s property: %2$s', 'cmb2' ), __CLASS__, $field ) );
492 }
493 }
494
495 /**
496 * Allows overloading the object with methods... Whooaaa oooh it's magic, y'knoooow.
497 *
498 * @since 1.0.0
499 * @throws Exception Invalid method exception.
500 *
501 * @param string $method Non-existent method.
502 * @param array $args All arguments passed to the method.
503 * @return mixed
504 */
505 public function __call( $method, $args ) {
506 $object_class = strtolower( get_class( $this ) );
507
508 if ( ! has_filter( "{$object_class}_inherit_{$method}" ) ) {
509 throw new Exception( sprintf( esc_html__( 'Invalid %1$s method: %2$s', 'cmb2' ), get_class( $this ), $method ) );
510 }
511
512 array_unshift( $args, $this );
513
514 /**
515 * Allows overloading the object (CMB2 or CMB2_Field) with additional capabilities
516 * by registering hook callbacks.
517 *
518 * The first dynamic portion of the hook name, $object_class, refers to the object class,
519 * either cmb2 or cmb2_field.
520 *
521 * The second dynamic portion of the hook name, $method, is the non-existent method being
522 * called on the object. To avoid possible future methods encroaching on your hooks,
523 * use a unique method (aka, $cmb->prefix_my_method()).
524 *
525 * When registering your callback, you will need to ensure that you register the correct
526 * number of `$accepted_args`, accounting for this object instance being the first argument.
527 *
528 * @param array $args The arguments to be passed to the hook.
529 * The first argument will always be this object instance.
530 */
531 return apply_filters_ref_array( "{$object_class}_inherit_{$method}", $args );
532 }
533 }
534