PageRenderTime 87ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/cmb/includes/CMB2_Base.php

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