CMB2_Base

CMB2 Base - Base object functionality.

Defined (1)

The class is defined in the following location(s).

/includes/CMB2_Base.php  
  1. abstract class CMB2_Base { 
  2.  
  3. /** 
  4. * Current CMB2 instance ID 
  5. * @var string 
  6. * @since 2.2.3 
  7. */ 
  8. protected $cmb_id = ''; 
  9.  
  10. /** 
  11. * The object properties name. 
  12. * @var string 
  13. * @since 2.2.3 
  14. */ 
  15. protected $properties_name = 'meta_box'; 
  16.  
  17. /** 
  18. * Object ID 
  19. * @var mixed 
  20. * @since 2.2.3 
  21. */ 
  22. protected $object_id = 0; 
  23.  
  24. /** 
  25. * Type of object being handled. (e.g., post, user, comment, or term) 
  26. * @var string 
  27. * @since 2.2.3 
  28. */ 
  29. protected $object_type = 'post'; 
  30.  
  31. /** 
  32. * Array of key => value data for saving. Likely $_POST data. 
  33. * @var array 
  34. * @since 2.2.3 
  35. */ 
  36. public $data_to_save = array(); 
  37.  
  38. /** 
  39. * Array of field param callback results 
  40. * @var array 
  41. * @since 2.0.0 
  42. */ 
  43. protected $callback_results = array(); 
  44.  
  45. /** 
  46. * The deprecated_param method deprecated param message signature. 
  47. */ 
  48. const DEPRECATED_PARAM = 1; 
  49.  
  50. /** 
  51. * The deprecated_param method deprecated callback param message signature. 
  52. */ 
  53. const DEPRECATED_CB_PARAM = 2; 
  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. * Returns the object ID 
  74. * @since 2.2.3 
  75. * @param integer $object_id Object ID 
  76. * @return integer Object ID 
  77. */ 
  78. public function object_id( $object_id = 0 ) { 
  79. if ( $object_id ) { 
  80. $this->object_id = $object_id; 
  81.  
  82. return $this->object_id; 
  83.  
  84. /** 
  85. * Returns the object type 
  86. * @since 2.2.3 
  87. * @param string $object_type Object Type 
  88. * @return string Object type 
  89. */ 
  90. public function object_type( $object_type = '' ) { 
  91. if ( $object_type ) { 
  92. $this->object_type = $object_type; 
  93.  
  94. return $this->object_type; 
  95.  
  96. /** 
  97. * Get the object type for the current page, based on the $pagenow global. 
  98. * @since 2.2.2 
  99. * @return string Page object type name. 
  100. */ 
  101. public function current_object_type() { 
  102. global $pagenow; 
  103. $type = 'post'; 
  104.  
  105. if ( in_array( $pagenow, array( 'user-edit.php', 'profile.php', 'user-new.php' ), true ) ) { 
  106. $type = 'user'; 
  107.  
  108. if ( in_array( $pagenow, array( 'edit-comments.php', 'comment.php' ), true ) ) { 
  109. $type = 'comment'; 
  110.  
  111. if ( in_array( $pagenow, array( 'edit-tags.php', 'term.php' ), true ) ) { 
  112. $type = 'term'; 
  113.  
  114. return $type; 
  115.  
  116. /** 
  117. * Set object property. 
  118. * @since 2.2.2 
  119. * @param string $property Metabox config property to retrieve 
  120. * @param mixed $value Value to set if no value found 
  121. * @return mixed Metabox config property value or false 
  122. */ 
  123. public function set_prop( $property, $value ) { 
  124. $this->{$this->properties_name}[ $property ] = $value; 
  125.  
  126. return $this->prop( $property ); 
  127.  
  128. /** 
  129. * Get object property and optionally set a fallback 
  130. * @since 2.0.0 
  131. * @param string $property Metabox config property to retrieve 
  132. * @param mixed $fallback Fallback value to set if no value found 
  133. * @return mixed Metabox config property value or false 
  134. */ 
  135. public function prop( $property, $fallback = null ) { 
  136. if ( array_key_exists( $property, $this->{$this->properties_name} ) ) { 
  137. return $this->{$this->properties_name}[ $property ]; 
  138. } elseif ( $fallback ) { 
  139. return $this->{$this->properties_name}[ $property ] = $fallback; 
  140.  
  141. /** 
  142. * Get default field arguments specific to this CMB2 object. 
  143. * @since 2.2.0 
  144. * @param array $field_args Metabox field config array. 
  145. * @param CMB2_Field $field_group (optional) CMB2_Field object (group parent) 
  146. * @return array Array of field arguments. 
  147. */ 
  148. protected function get_default_args( $field_args, $field_group = null ) { 
  149. if ( $field_group ) { 
  150. $args = array( 
  151. 'field_args' => $field_args,  
  152. 'group_field' => $field_group,  
  153. ); 
  154. } else { 
  155. $args = array( 
  156. 'field_args' => $field_args,  
  157. 'object_type' => $this->object_type(),  
  158. 'object_id' => $this->object_id(),  
  159. 'cmb_id' => $this->cmb_id,  
  160. ); 
  161.  
  162. return $args; 
  163.  
  164. /** 
  165. * Get a new field object specific to this CMB2 object. 
  166. * @since 2.2.0 
  167. * @param array $field_args Metabox field config array. 
  168. * @param CMB2_Field $field_group (optional) CMB2_Field object (group parent) 
  169. * @return CMB2_Field CMB2_Field object 
  170. */ 
  171. protected function get_new_field( $field_args, $field_group = null ) { 
  172. return new CMB2_Field( $this->get_default_args( $field_args, $field_group ) ); 
  173.  
  174. /** 
  175. * Determine whether this cmb object should show, based on the 'show_on_cb' callback. 
  176. * @since 2.0.9 
  177. * @return bool Whether this cmb should be shown. 
  178. */ 
  179. public function should_show() { 
  180. // Default to showing this cmb 
  181. $show = true; 
  182.  
  183. // Use the callback to determine showing the cmb, if it exists 
  184. if ( is_callable( $this->prop( 'show_on_cb' ) ) ) { 
  185. $show = (bool) call_user_func( $this->prop( 'show_on_cb' ), $this ); 
  186.  
  187. return $show; 
  188.  
  189. /** 
  190. * Displays the results of the param callbacks. 
  191. * @since 2.0.0 
  192. * @param string $param Field parameter 
  193. */ 
  194. public function peform_param_callback( $param ) { 
  195. echo $this->get_param_callback_result( $param ); 
  196.  
  197. /** 
  198. * Store results of the param callbacks for continual access 
  199. * @since 2.0.0 
  200. * @param string $param Field parameter 
  201. * @return mixed Results of param/param callback 
  202. */ 
  203. public function get_param_callback_result( $param ) { 
  204.  
  205. // If we've already retrieved this param's value,  
  206. if ( array_key_exists( $param, $this->callback_results ) ) { 
  207.  
  208. // send it back 
  209. return $this->callback_results[ $param ]; 
  210.  
  211. // Check if parameter has registered a callback. 
  212. if ( $cb = $this->maybe_callback( $param ) ) { 
  213.  
  214. // Ok, callback is good, let's run it and store the result. 
  215. ob_start(); 
  216. $returned = $this->do_callback( $cb ); 
  217.  
  218. // Grab the result from the output buffer and store it. 
  219. $echoed = ob_get_clean(); 
  220.  
  221. // This checks if the user returned or echoed their callback. 
  222. // Defaults to using the echoed value. 
  223. $this->callback_results[ $param ] = $echoed ? $echoed : $returned; 
  224.  
  225. } else { 
  226.  
  227. // Otherwise just get whatever is there. 
  228. $this->callback_results[ $param ] = isset( $this->{$this->properties_name}[ $param ] ) ? $this->{$this->properties_name}[ $param ] : false; 
  229.  
  230. return $this->callback_results[ $param ]; 
  231.  
  232. /** 
  233. * Handles the property callbacks, and passes this object as property. 
  234. * @since 2.2.3 
  235. * @param callable $cb The callback method/function/closure 
  236. * @return mixed Return of the callback function. 
  237. */ 
  238. protected function do_callback( $cb ) { 
  239. return call_user_func( $cb, $this->{$this->properties_name}, $this ); 
  240.  
  241. /** 
  242. * Checks if field has a callback value 
  243. * @since 1.0.1 
  244. * @param string $cb Callback string 
  245. * @return mixed NULL, false for NO validation, or $cb string if it exists. 
  246. */ 
  247. public function maybe_callback( $cb ) { 
  248. $args = $this->{$this->properties_name}; 
  249. if ( ! isset( $args[ $cb ] ) ) { 
  250. return null; 
  251.  
  252. // Check if requesting explicitly false 
  253. $cb = false !== $args[ $cb ] && 'false' !== $args[ $cb ] ? $args[ $cb ] : false; 
  254.  
  255. // If requesting NO validation, return false 
  256. if ( ! $cb ) { 
  257. return false; 
  258.  
  259. if ( is_callable( $cb ) ) { 
  260. return $cb; 
  261.  
  262. return null; 
  263.  
  264. /** 
  265. * Mark a param as deprecated and inform when it has been used. 
  266. * There is a default WordPress hook deprecated_argument_run that will be called 
  267. * that can be used to get the backtrace up to what file and function used the 
  268. * deprecated argument. 
  269. * The current behavior is to trigger a user error if WP_DEBUG is true. 
  270. * @since 2.2.3 
  271. * @param string $function The function that was called. 
  272. * @param string $version The version of CMB2 that deprecated the argument used. 
  273. * @param string $message Optional. A message regarding the change, or numeric 
  274. * key to generate message from additional arguments. 
  275. * Default null. 
  276. */ 
  277. protected function deprecated_param( $function, $version, $message = null ) { 
  278.  
  279. if ( is_numeric( $message ) ) { 
  280. $args = func_get_args(); 
  281.  
  282. switch ( $message ) { 
  283.  
  284. case self::DEPRECATED_PARAM: 
  285. $message = sprintf( __( 'The "%s" field parameter has been deprecated in favor of the "%s" parameter.', 'cmb2' ), $args[3], $args[4] ); 
  286. break; 
  287.  
  288. case self::DEPRECATED_CB_PARAM: 
  289. $message = sprintf( __( 'Using the "%s" field parameter as a callback has been deprecated in favor of the "%s" parameter.', 'cmb2' ), $args[3], $args[4] ); 
  290. break; 
  291.  
  292. default: 
  293. $message = null; 
  294. break; 
  295.  
  296. /** 
  297. * Fires when a deprecated argument is called. This is a WP core action. 
  298. * @since 2.2.3 
  299. * @param string $function The function that was called. 
  300. * @param string $message A message regarding the change. 
  301. * @param string $version The version of CMB2 that deprecated the argument used. 
  302. */ 
  303. do_action( 'deprecated_argument_run', $function, $message, $version ); 
  304.  
  305. /** 
  306. * Filters whether to trigger an error for deprecated arguments. This is a WP core filter. 
  307. * @since 2.2.3 
  308. * @param bool $trigger Whether to trigger the error for deprecated arguments. Default true. 
  309. */ 
  310. if ( defined( 'WP_DEBUG' ) && WP_DEBUG && apply_filters( 'deprecated_argument_trigger_error', true ) ) { 
  311. if ( function_exists( '__' ) ) { 
  312. if ( ! is_null( $message ) ) { 
  313. 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 ) ); 
  314. else { 
  315. 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 ) ); 
  316. } else { 
  317. if ( ! is_null( $message ) ) { 
  318. trigger_error( sprintf( '%1$s was called with a parameter that is <strong>deprecated</strong> since version %2$s! %3$s', $function, $version, $message ) ); 
  319. else { 
  320. 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 ) ); 
  321.  
  322. /** 
  323. * Magic getter for our object. 
  324. * @param string $field 
  325. * @throws Exception Throws an exception if the field is invalid. 
  326. * @return mixed 
  327. */ 
  328. public function __get( $field ) { 
  329. switch ( $field ) { 
  330. case 'args': 
  331. case 'meta_box': 
  332. if ( $field === $this->properties_name ) { 
  333. return $this->{$this->properties_name}; 
  334. case 'properties': 
  335. return $this->{$this->properties_name}; 
  336. case 'cmb_id': 
  337. case 'object_id': 
  338. case 'object_type': 
  339. return $this->{$field}; 
  340. default: 
  341. throw new Exception( sprintf( esc_html__( 'Invalid %1$s property: %2$s', 'give' ), __CLASS__, $field ) ); 
  342.  
  343. /** 
  344. * Allows overloading the object with methods... Whooaaa oooh it's magic, y'knoooow. 
  345. * @since 1.0.0 
  346. * @param string $method Non-existent method. 
  347. * @param array $arguments All arguments passed to the method 
  348. */ 
  349. public function __call( $method, $args ) { 
  350. $object_class = strtolower( get_class( $this ) ); 
  351.  
  352. if ( ! has_filter( "{$object_class}_inherit_{$method}" ) ) { 
  353. throw new Exception( sprintf( esc_html__( 'Invalid %1$s method: %2$s', 'give' ), get_class( $this ), $method ) ); 
  354.  
  355. array_unshift( $args, $this ); 
  356.  
  357. /** 
  358. * Allows overloading the object (CMB2 or CMB2_Field) with additional capabilities 
  359. * by registering hook callbacks. 
  360. * The first dynamic portion of the hook name, $object_class, refers to the object class,  
  361. * either cmb2 or cmb2_field. 
  362. * The second dynamic portion of the hook name, $method, is the non-existent method being 
  363. * called on the object. To avoid possible future methods encroaching on your hooks,  
  364. * use a unique method (aka, $cmb->prefix_my_method()). 
  365. * When registering your callback, you will need to ensure that you register the correct 
  366. * number of `$accepted_args`, accounting for this object instance being the first argument. 
  367. * @param array $args The arguments to be passed to the hook. 
  368. * The first argument will always be this object instance. 
  369. */ 
  370. return apply_filters_ref_array( "{$object_class}_inherit_{$method}", $args );