CMB2_Field

CMB2 field objects.

Defined (2)

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

/includes/libraries/metabox/includes/CMB2_Field.php  
  1. class CMB2_Field { 
  2.  
  3. /** 
  4. * Metabox object id 
  5. * @var mixed 
  6. * @since 1.1.0 
  7. */ 
  8. public $object_id = null; 
  9.  
  10. /** 
  11. * Metabox object type 
  12. * @var string 
  13. * @since 1.1.0 
  14. */ 
  15. public $object_type = ''; 
  16.  
  17. /** 
  18. * Field arguments 
  19. * @var mixed 
  20. * @since 1.1.0 
  21. */ 
  22. public $args = array(); 
  23.  
  24. /** 
  25. * Field group object or false (if no group) 
  26. * @var mixed 
  27. * @since 1.1.0 
  28. */ 
  29. public $group = false; 
  30.  
  31. /** 
  32. * Field meta value 
  33. * @var mixed 
  34. * @since 1.1.0 
  35. */ 
  36. public $value = null; 
  37.  
  38. /** 
  39. * Field meta value 
  40. * @var mixed 
  41. * @since 1.1.0 
  42. */ 
  43. public $escaped_value = null; 
  44.  
  45. /** 
  46. * Grouped Field's current numeric index during the save process 
  47. * @var mixed 
  48. * @since 2.0.0 
  49. */ 
  50. public $index = 0; 
  51.  
  52. /** 
  53. * Array of field options 
  54. * @var array 
  55. * @since 2.0.0 
  56. */ 
  57. protected $field_options = array(); 
  58.  
  59. /** 
  60. * Array of field param callback results 
  61. * @var array 
  62. * @since 2.0.0 
  63. */ 
  64. protected $callback_results = array(); 
  65.  
  66. /** 
  67. * Constructs our field object 
  68. * @since 1.1.0 
  69. * @param array $args Field arguments 
  70. */ 
  71. public function __construct( $args ) { 
  72.  
  73. if ( ! empty( $args['group_field'] ) ) { 
  74. $this->group = $args['group_field']; 
  75. $this->object_id = $this->group->object_id; 
  76. $this->object_type = $this->group->object_type; 
  77. } else { 
  78. $this->object_id = isset( $args['object_id'] ) && '_' !== $args['object_id'] ? $args['object_id'] : 0; 
  79. $this->object_type = isset( $args['object_type'] ) ? $args['object_type'] : 'post'; 
  80.  
  81. $this->args = $this->_set_field_defaults( $args['field_args'] ); 
  82.  
  83. if ( $this->object_id ) { 
  84. $this->value = $this->get_data(); 
  85.  
  86. /** 
  87. * Non-existent methods fallback to checking for field arguments of the same name 
  88. * @since 1.1.0 
  89. * @param string $name Method name 
  90. * @param array $arguments Array of passed-in arguments 
  91. * @return mixed Value of field argument 
  92. */ 
  93. public function __call( $name, $arguments ) { 
  94. $key = isset( $arguments[0] ) ? $arguments[0] : false; 
  95. return $this->args( $name, $key ); 
  96.  
  97. /** 
  98. * Retrieves the field id 
  99. * @since 1.1.0 
  100. * @param boolean $raw Whether to retrieve pre-modidifed id 
  101. * @return string Field id 
  102. */ 
  103. public function id( $raw = false ) { 
  104. $id = $raw ? '_id' : 'id'; 
  105. return $this->args( $id ); 
  106.  
  107. /** 
  108. * Get a field argument 
  109. * @since 1.1.0 
  110. * @param string $key Argument to check 
  111. * @param string $key Sub argument to check 
  112. * @return mixed Argument value or false if non-existent 
  113. */ 
  114. public function args( $key = '', $_key = '' ) { 
  115. $arg = $this->_data( 'args', $key ); 
  116.  
  117. if ( 'default' == $key ) { 
  118.  
  119. $arg = $this->get_param_callback_result( 'default', false ); 
  120.  
  121. } elseif ( $_key ) { 
  122.  
  123. $arg = isset( $arg[ $_key ] ) ? $arg[ $_key ] : false; 
  124.  
  125. return $arg; 
  126.  
  127. /** 
  128. * Retrieve a portion of a field property 
  129. * @since 1.1.0 
  130. * @param string $var Field property to check 
  131. * @param string $key Field property array key to check 
  132. * @return mixed Queried property value or false 
  133. */ 
  134. public function _data( $var, $key = '' ) { 
  135. $vars = $this->$var; 
  136. if ( $key ) { 
  137. return isset( $vars[ $key ] ) ? $vars[ $key ] : false; 
  138. return $vars; 
  139.  
  140. /** 
  141. * Get Field's value 
  142. * @since 1.1.0 
  143. * @param string $key If value is an array, is used to get array key->value 
  144. * @return mixed Field value or false if non-existent 
  145. */ 
  146. public function value( $key = '' ) { 
  147. return $this->_data( 'value', $key ); 
  148.  
  149. /** 
  150. * Retrieves metadata/option data 
  151. * @since 1.0.1 
  152. * @param string $field_id Meta key/Option array key 
  153. * @return mixed Meta/Option value 
  154. */ 
  155. public function get_data( $field_id = '', $args = array() ) { 
  156. if ( $field_id ) { 
  157. $args['field_id'] = $field_id; 
  158. } else if ( $this->group ) { 
  159. $args['field_id'] = $this->group->id(); 
  160.  
  161. $a = $this->data_args( $args ); 
  162.  
  163. /** 
  164. * Filter whether to override getting of meta value. 
  165. * Returning a non 'cmb2_field_no_override_val' value 
  166. * will effectively short-circuit the value retrieval. 
  167. * @since 2.0.0 
  168. * @param mixed $value The value get_metadata() should 
  169. * return - a single metadata value,  
  170. * or an array of values. 
  171. * @param int $object_id Object ID. 
  172. * @param array $args { 
  173. * An array of arguments for retrieving data 
  174. * @type string $type The current object type 
  175. * @type int $id The current object ID 
  176. * @type string $field_id The ID of the field being requested 
  177. * @type bool $repeat Whether current field is repeatable 
  178. * @type bool $single Whether current field is a single database row 
  179. * } 
  180. * @param CMB2_Field object $field This field object 
  181. */ 
  182. $data = apply_filters( 'cmb2_override_meta_value', 'cmb2_field_no_override_val', $this->object_id, $a, $this ); 
  183.  
  184. /** 
  185. * Filter and parameters are documented for 'cmb2_override_meta_value' filter (above). 
  186. * The dynamic portion of the hook, $field_id, refers to the current 
  187. * field id paramater. Returning a non 'cmb2_field_no_override_val' value 
  188. * will effectively short-circuit the value retrieval. 
  189. * @since 2.0.0 
  190. */ 
  191. $data = apply_filters( "cmb2_override_{$a['field_id']}_meta_value", $data, $this->object_id, $a, $this ); 
  192.  
  193. // If no override, get value normally 
  194. if ( 'cmb2_field_no_override_val' === $data ) { 
  195. $data = 'options-page' === $a['type'] 
  196. ? cmb2_options( $a['id'] )->get( $a['field_id'] ) 
  197. : get_metadata( $a['type'], $a['id'], $a['field_id'], ( $a['single'] || $a['repeat'] ) ); 
  198.  
  199.  
  200. if ( $this->group && $data ) { 
  201. $data = isset( $data[ $this->group->index ][ $this->args( '_id' ) ] ) 
  202. ? $data[ $this->group->index ][ $this->args( '_id' ) ] 
  203. : false; 
  204.  
  205. return $data; 
  206.  
  207. /** 
  208. * Updates metadata/option data 
  209. * @since 1.0.1 
  210. * @param mixed $new_value Value to update data with 
  211. * @param bool $single Whether data is an array (add_metadata) 
  212. */ 
  213. public function update_data( $new_value, $single = true ) { 
  214. $a = $this->data_args( array( 'single' => $single ) ); 
  215.  
  216. $a[ 'value' ] = $a['repeat'] ? array_values( $new_value ) : $new_value; 
  217.  
  218. /** 
  219. * Filter whether to override saving of meta value. 
  220. * Returning a non-null value will effectively short-circuit the function. 
  221. * @since 2.0.0 
  222. * @param null|bool $check Whether to allow updating metadata for the given type. 
  223. * @param array $args { 
  224. * Array of data about current field including: 
  225. * @type string $value The value to set 
  226. * @type string $type The current object type 
  227. * @type int $id The current object ID 
  228. * @type string $field_id The ID of the field being updated 
  229. * @type bool $repeat Whether current field is repeatable 
  230. * @type bool $single Whether current field is a single database row 
  231. * } 
  232. * @param array $field_args All field arguments 
  233. * @param CMB2_Field object $field This field object 
  234. */ 
  235. $override = apply_filters( 'cmb2_override_meta_save', null, $a, $this->args(), $this ); 
  236.  
  237. /** 
  238. * Filter and parameters are documented for 'cmb2_override_meta_save' filter (above). 
  239. * The dynamic portion of the hook, $a['field_id'], refers to the current 
  240. * field id paramater. Returning a non-null value 
  241. * will effectively short-circuit the function. 
  242. * @since 2.0.0 
  243. */ 
  244. $override = apply_filters( "cmb2_override_{$a['field_id']}_meta_save", $override, $a, $this->args(), $this ); 
  245.  
  246. // If override, return that 
  247. if ( null !== $override ) { 
  248. return $override; 
  249.  
  250. // Options page handling (or temp data store) 
  251. if ( 'options-page' === $a['type'] || empty( $a['id'] ) ) { 
  252. return cmb2_options( $a['id'] )->update( $a['field_id'], $a[ 'value' ], false, $a['single'] ); 
  253.  
  254. // Add metadata if not single 
  255. if ( ! $a['single'] ) { 
  256. return add_metadata( $a['type'], $a['id'], $a['field_id'], $a[ 'value' ], false ); 
  257.  
  258. // Delete meta if we have an empty array 
  259. if ( is_array( $a[ 'value' ] ) && empty( $a[ 'value' ] ) ) { 
  260. return delete_metadata( $a['type'], $a['id'], $a['field_id'], $this->value ); 
  261.  
  262. // Update metadata 
  263. return update_metadata( $a['type'], $a['id'], $a['field_id'], $a[ 'value' ] ); 
  264.  
  265. /** 
  266. * Removes/updates metadata/option data 
  267. * @since 1.0.1 
  268. * @param string $old Old value 
  269. */ 
  270. public function remove_data( $old = '' ) { 
  271. $a = $this->data_args( array( 'old' => $old ) ); 
  272.  
  273. /** 
  274. * Filter whether to override removing of meta value. 
  275. * Returning a non-null value will effectively short-circuit the function. 
  276. * @since 2.0.0 
  277. * @param null|bool $delete Whether to allow metadata deletion of the given type. 
  278. * @param array $args Array of data about current field including: 
  279. * 'type' : Current object type 
  280. * 'id' : Current object ID 
  281. * 'field_id' : Current Field ID 
  282. * 'repeat' : Whether current field is repeatable 
  283. * 'single' : Whether to save as a 
  284. * single meta value 
  285. * @param array $field_args All field arguments 
  286. * @param CMB2_Field object $field This field object 
  287. */ 
  288. $override = apply_filters( 'cmb2_override_meta_remove', null, $a, $this->args(), $this ); 
  289.  
  290. /** 
  291. * Filter whether to override removing of meta value. 
  292. * The dynamic portion of the hook, $a['field_id'], refers to the current 
  293. * field id paramater. Returning a non-null value 
  294. * will effectively short-circuit the function. 
  295. * @since 2.0.0 
  296. * @param null|bool $delete Whether to allow metadata deletion of the given type. 
  297. * @param array $args Array of data about current field including: 
  298. * 'type' : Current object type 
  299. * 'id' : Current object ID 
  300. * 'field_id' : Current Field ID 
  301. * 'repeat' : Whether current field is repeatable 
  302. * 'single' : Whether to save as a 
  303. * single meta value 
  304. * @param array $field_args All field arguments 
  305. * @param CMB2_Field object $field This field object 
  306. */ 
  307. $override = apply_filters( "cmb2_override_{$a['field_id']}_meta_remove", $override, $a, $this->args(), $this ); 
  308.  
  309. // If no override, remove as usual 
  310. if ( null !== $override ) { 
  311. return $override; 
  312. // Option page handling 
  313. elseif ( 'options-page' === $a['type'] || empty( $a['id'] ) ) { 
  314. return cmb2_options( $a['id'] )->remove( $a['field_id'] ); 
  315.  
  316. // Remove metadata 
  317. return delete_metadata( $a['type'], $a['id'], $a['field_id'], $old ); 
  318.  
  319. /** 
  320. * data variables for get/set data methods 
  321. * @since 1.1.0 
  322. * @param array $args Override arguments 
  323. * @return array Updated arguments 
  324. */ 
  325. public function data_args( $args = array() ) { 
  326. $args = wp_parse_args( $args, array( 
  327. 'type' => $this->object_type,  
  328. 'id' => $this->object_id,  
  329. 'field_id' => $this->id( true ),  
  330. 'repeat' => $this->args( 'repeatable' ),  
  331. 'single' => ! $this->args( 'multiple' ),  
  332. ) ); 
  333. return $args; 
  334.  
  335. /** 
  336. * Checks if field has a registered sanitization callback 
  337. * @since 1.0.1 
  338. * @param mixed $meta_value Meta value 
  339. * @return mixed Possibly sanitized meta value 
  340. */ 
  341. public function sanitization_cb( $meta_value ) { 
  342.  
  343. if ( $this->args( 'repeatable' ) && is_array( $meta_value ) ) { 
  344. // Remove empties 
  345. $meta_value = array_filter( $meta_value ); 
  346.  
  347. // Check if the field has a registered validation callback 
  348. $cb = $this->maybe_callback( 'sanitization_cb' ); 
  349. if ( false === $cb ) { 
  350. // If requesting NO validation, return meta value 
  351. return $meta_value; 
  352. } elseif ( $cb ) { 
  353. // Ok, callback is good, let's run it. 
  354. return call_user_func( $cb, $meta_value, $this->args(), $this ); 
  355.  
  356. $clean = new CMB2_Sanitize( $this, $meta_value ); 
  357. // Validation via 'CMB2_Sanitize' (with fallback filter) 
  358. return $clean->{$this->type()}(); 
  359.  
  360. /** 
  361. * Process $_POST data to save this field's value 
  362. * @since 2.0.3 
  363. * @param array $data_to_save $_POST data to check 
  364. * @return bool Result of save 
  365. */ 
  366. public function save_field_from_data( $data_to_save ) { 
  367.  
  368. $meta_value = isset( $data_to_save[ $this->id( true ) ] ) 
  369. ? $data_to_save[ $this->id( true ) ] 
  370. : null; 
  371.  
  372. return $this->save_field( $meta_value ); 
  373.  
  374. /** 
  375. * Sanitize/store a value to this field 
  376. * @since 2.0.0 
  377. * @param array $meta_value Desired value to sanitize/store 
  378. * @return bool Result of save 
  379. */ 
  380. public function save_field( $meta_value ) { 
  381.  
  382. $new_value = $this->sanitization_cb( $meta_value ); 
  383. $old = $this->get_data(); 
  384. $updated = false; 
  385.  
  386. if ( $this->args( 'multiple' ) && ! $this->args( 'repeatable' ) && ! $this->group ) { 
  387.  
  388. $this->remove_data(); 
  389. $count = 0; 
  390.  
  391. if ( ! empty( $new_value ) ) { 
  392. foreach ( $new_value as $add_new ) { 
  393. if ( $this->update_data( $add_new, false ) ) { 
  394. $count++; 
  395.  
  396. $updated = $count ? $count : false; 
  397.  
  398.  
  399. } elseif ( ! cmb2_utils()->isempty( $new_value ) && $new_value !== $old ) { 
  400. $updated = $this->update_data( $new_value ); 
  401. } elseif ( cmb2_utils()->isempty( $new_value ) ) { 
  402. $updated = $this->remove_data(); 
  403.  
  404. return $updated; 
  405.  
  406. /** 
  407. * Checks if field has a callback value 
  408. * @since 1.0.1 
  409. * @param string $cb Callback string 
  410. * @return mixed NULL, false for NO validation, or $cb string if it exists. 
  411. */ 
  412. public function maybe_callback( $cb ) { 
  413. $field_args = $this->args(); 
  414. if ( ! isset( $field_args[ $cb ] ) ) { 
  415. return; 
  416.  
  417. // Check if metabox is requesting NO validation 
  418. $cb = false !== $field_args[ $cb ] && 'false' !== $field_args[ $cb ] ? $field_args[ $cb ] : false; 
  419.  
  420. // If requestion NO validation, return false 
  421. if ( ! $cb ) { 
  422. return false; 
  423.  
  424. if ( is_callable( $cb ) ) { 
  425. return $cb; 
  426.  
  427. /** 
  428. * Determine if current type is excempt from escaping 
  429. * @since 1.1.0 
  430. * @return bool True if exempt 
  431. */ 
  432. public function escaping_exception() { 
  433. // These types cannot be escaped 
  434. return in_array( $this->type(), array( 
  435. 'file_list',  
  436. 'multicheck',  
  437. 'text_datetime_timestamp_timezone',  
  438. ) ); 
  439.  
  440. /** 
  441. * Determine if current type cannot be repeatable 
  442. * @since 1.1.0 
  443. * @param string $type Field type to check 
  444. * @return bool True if type cannot be repeatable 
  445. */ 
  446. public function repeatable_exception( $type ) { 
  447. // These types cannot be escaped 
  448. return in_array( $type, array( 
  449. 'file', // Use file_list 
  450. 'radio',  
  451. 'title',  
  452. // @todo Ajax load wp_editor: http://wordpress.stackexchange.com/questions/51776/how-to-load-wp-editor-through-ajax-jquery 
  453. 'wysiwyg',  
  454. 'checkbox',  
  455. 'radio_inline',  
  456. 'taxonomy_radio',  
  457. 'taxonomy_select',  
  458. 'taxonomy_multicheck',  
  459. ) ); 
  460.  
  461. /** 
  462. * Escape the value before output. Defaults to 'esc_attr()' 
  463. * @since 1.0.1 
  464. * @param mixed $meta_value Meta value 
  465. * @param callable $func Escaping function (if not esc_attr()) 
  466. * @return mixed Final value 
  467. */ 
  468. public function escaped_value( $func = 'esc_attr', $meta_value = '' ) { 
  469.  
  470. if ( null !== $this->escaped_value ) { 
  471. return $this->escaped_value; 
  472.  
  473. $meta_value = $meta_value ? $meta_value : $this->value(); 
  474.  
  475. // Check if the field has a registered escaping callback 
  476. if ( $cb = $this->maybe_callback( 'escape_cb' ) ) { 
  477. // Ok, callback is good, let's run it. 
  478. return call_user_func( $cb, $meta_value, $this->args(), $this ); 
  479.  
  480. // Or custom escaping filter can be used 
  481. $esc = apply_filters( "cmb2_types_esc_{$this->type()}", null, $meta_value, $this->args(), $this ); 
  482. if ( null !== $esc ) { 
  483. return $esc; 
  484.  
  485. if ( false === $cb || $this->escaping_exception() ) { 
  486. // If requesting NO escaping, return meta value 
  487. return $this->val_or_default( $meta_value ); 
  488.  
  489. // escaping function passed in? 
  490. $func = $func ? $func : 'esc_attr'; 
  491. $meta_value = $this->val_or_default( $meta_value ); 
  492.  
  493. if ( is_array( $meta_value ) ) { 
  494. foreach ( $meta_value as $key => $value ) { 
  495. $meta_value[ $key ] = call_user_func( $func, $value ); 
  496. } else { 
  497. $meta_value = call_user_func( $func, $meta_value ); 
  498.  
  499. $this->escaped_value = $meta_value; 
  500. return $this->escaped_value; 
  501.  
  502. /** 
  503. * Return non-empty value or field default if value IS empty 
  504. * @since 2.0.0 
  505. * @param mixed $meta_value Field value 
  506. * @return mixed Field value, or default value 
  507. */ 
  508. public function val_or_default( $meta_value ) { 
  509. return ! cmb2_utils()->isempty( $meta_value ) ? $meta_value : $this->get_param_callback_result( 'default', false ); 
  510.  
  511. /** 
  512. * Offset a time value based on timezone 
  513. * @since 1.0.0 
  514. * @return string Offset time string 
  515. */ 
  516. public function field_timezone_offset() { 
  517. return cmb2_utils()->timezone_offset( $this->field_timezone() ); 
  518.  
  519. /** 
  520. * Return timezone string 
  521. * @since 1.0.0 
  522. * @return string Timezone string 
  523. */ 
  524. public function field_timezone() { 
  525.  
  526. // Is timezone arg set? 
  527. if ( $this->args( 'timezone' ) ) { 
  528. return $this->args( 'timezone' ); 
  529. // Is there another meta key with a timezone stored as its value we should use? 
  530. else if ( $this->args( 'timezone_meta_key' ) ) { 
  531. return $this->get_data( $this->args( 'timezone_meta_key' ) ); 
  532.  
  533. return ''; 
  534.  
  535. /** 
  536. * Format the timestamp field value based on the field date/time format arg 
  537. * @since 2.0.0 
  538. * @param int $meta_value Timestamp 
  539. * @param string $format Either date_format or time_format 
  540. * @return string Formatted date 
  541. */ 
  542. public function format_timestamp( $meta_value, $format = 'date_format' ) { 
  543. return date( stripslashes( $this->args( $format ) ), $meta_value ); 
  544.  
  545. /** 
  546. * Return a formatted timestamp for a field 
  547. * @since 2.0.0 
  548. * @param string $format Either date_format or time_format 
  549. * @return string Formatted date 
  550. */ 
  551. public function get_timestamp_format( $format = 'date_format', $meta_value = 0 ) { 
  552. $meta_value = $meta_value ? $meta_value : $this->escaped_value(); 
  553. $meta_value = cmb2_utils()->make_valid_time_stamp( $meta_value ); 
  554.  
  555. if ( empty( $meta_value ) ) { 
  556. return ''; 
  557.  
  558. return is_array( $meta_value ) 
  559. ? array_map( array( $this, 'format_timestamp' ), $meta_value, $format ) 
  560. : $this->format_timestamp( $meta_value, $format ); 
  561.  
  562. /** 
  563. * Render a field row 
  564. * @since 1.0.0 
  565. */ 
  566. public function render_field() { 
  567.  
  568. // If field is requesting to not be shown on the front-end 
  569. if ( ! is_admin() && ! $this->args( 'on_front' ) ) { 
  570. return; 
  571.  
  572. // If field is requesting to be conditionally shown 
  573. if ( is_callable( $this->args( 'show_on_cb' ) ) && ! call_user_func( $this->args( 'show_on_cb' ), $this ) ) { 
  574. return; 
  575.  
  576. $this->peform_param_callback( 'before_row' ); 
  577.  
  578. printf( "<div class=\"cmb-row %s\">\n", $this->row_classes() ); 
  579.  
  580. if ( 'title' == $this->type() || ! $this->args( 'show_names' ) ) { 
  581. echo "\t<div class=\"cmb-td\">\n"; 
  582.  
  583. if ( ! $this->args( 'show_names' ) ) { 
  584. $style = 'title' == $this->type() ? '' : ' style="display:none;"'; 
  585. printf( "\n<label%s for=\"%s\">%s</label>\n", $style, $this->id(), $this->args( 'name' ) ); 
  586. } else { 
  587.  
  588. if ( $this->args( 'name' ) ) { 
  589. printf( '<div class="cmb-th"><label for="%1$s">%2$s</label></div>', $this->id(), $this->args( 'name' ) ); 
  590.  
  591. echo "\n\t<div class=\"cmb-td\">\n"; 
  592.  
  593. $this->peform_param_callback( 'before' ); 
  594.  
  595. $this_type = new CMB2_Types( $this ); 
  596. $this_type->render(); 
  597.  
  598. $this->peform_param_callback( 'after' ); 
  599.  
  600. echo "\n\t</div>\n</div>"; 
  601.  
  602. $this->peform_param_callback( 'after_row' ); 
  603.  
  604. // For chaining 
  605. return $this; 
  606.  
  607. /** 
  608. * Defines the classes for the current CMB2 field row 
  609. * @since 2.0.0 
  610. * @return string Space concatenated list of classes 
  611. */ 
  612. public function row_classes() { 
  613.  
  614. $classes = array(); 
  615.  
  616. /** 
  617. * By default, 'text_url' and 'text' fields get table-like styling 
  618. * @since 2.0.0 
  619. * @param array $field_types The types of fields which should get the 'table-layout' class 
  620. */ 
  621. $repeat_table_rows_types = apply_filters( 'cmb2_repeat_table_row_types', array( 
  622. 'text_url', 'text',  
  623. ) ); 
  624.  
  625. $conditional_classes = array( 
  626. 'cmb-type-' . str_replace( '_', '-', sanitize_html_class( $this->type() ) ) => true,  
  627. 'cmb2-id-' . str_replace( '_', '-', sanitize_html_class( $this->id() ) ) => true,  
  628. 'cmb-repeat' => $this->args( 'repeatable' ),  
  629. 'cmb-repeat-group-field' => $this->group,  
  630. 'cmb-inline' => $this->args( 'inline' ),  
  631. 'table-layout' => in_array( $this->type(), $repeat_table_rows_types ),  
  632. ); 
  633.  
  634. foreach ( $conditional_classes as $class => $condition ) { 
  635. if ( $condition ) { 
  636. $classes[] = $class; 
  637.  
  638. if ( $added_classes = $this->get_param_callback_result( 'row_classes', false ) ) { 
  639. $added_classes = is_array( $added_classes ) ? implode( ' ', $added_classes ) : (string) $added_classes; 
  640.  
  641. if ( $added_classes ) { 
  642. $classes[] = esc_attr( $added_classes ); 
  643.  
  644. /** 
  645. * Globally filter row classes 
  646. * @since 2.0.0 
  647. * @param string $classes Space-separated list of row classes 
  648. * @param CMB2_Field object $field This field object 
  649. */ 
  650. return apply_filters( 'cmb2_row_classes', implode( ' ', $classes ), $this ); 
  651.  
  652. /** 
  653. * Displays the results of the param callbacks. 
  654. * @since 2.0.0 
  655. * @param string $param Field parameter 
  656. */ 
  657. public function peform_param_callback( $param ) { 
  658. echo $this->get_param_callback_result( $param ); 
  659.  
  660. /** 
  661. * Store results of the param callbacks for continual access 
  662. * @since 2.0.0 
  663. * @param string $param Field parameter 
  664. * @param bool $echo Whether field should be 'echoed' 
  665. * @return mixed Results of param/param callback 
  666. */ 
  667. public function get_param_callback_result( $param, $echo = true ) { 
  668.  
  669. // If we've already retrieved this param's value,  
  670. if ( array_key_exists( $param, $this->callback_results ) ) { 
  671. // send it back 
  672. return $this->callback_results[ $param ]; 
  673.  
  674. if ( $cb = $this->maybe_callback( $param ) ) { 
  675. if ( $echo ) { 
  676. // Ok, callback is good, let's run it and store the result 
  677. ob_start(); 
  678. echo call_user_func( $cb, $this->args(), $this ); 
  679. // grab the result from the output buffer and store it 
  680. $this->callback_results[ $param ] = ob_get_contents(); 
  681. ob_end_clean(); 
  682. } else { 
  683. $this->callback_results[ $param ] = call_user_func( $cb, $this->args(), $this ); 
  684.  
  685. return $this->callback_results[ $param ]; 
  686.  
  687. // Otherwise just get whatever is there 
  688. $this->callback_results[ $param ] = isset( $this->args[ $param ] ) ? $this->args[ $param ] : false; 
  689.  
  690. return $this->callback_results[ $param ]; 
  691.  
  692. /** 
  693. * Replaces a hash key - {#} - with the repeatable index 
  694. * @since 1.2.0 
  695. * @param string $value Value to update 
  696. * @return string Updated value 
  697. */ 
  698. public function replace_hash( $value ) { 
  699. // Replace hash with 1 based count 
  700. return str_ireplace( '{#}', ( $this->index + 1 ), $value ); 
  701.  
  702. /** 
  703. * Retrieve options args. Calls options_cb if it exists. 
  704. * @since 2.0.0 
  705. * @param string $key Specific option to retrieve 
  706. * @return array Array of options 
  707. */ 
  708. public function options( $key = '' ) { 
  709. if ( ! empty( $this->field_options ) ) { 
  710. if ( $key ) { 
  711. return array_key_exists( $key, $this->field_options ) ? $this->field_options[ $key ] : false; 
  712.  
  713. return $this->field_options; 
  714.  
  715. $this->field_options = (array) $this->args['options']; 
  716.  
  717. if ( is_callable( $this->args['options_cb'] ) ) { 
  718. $options = call_user_func( $this->args['options_cb'], $this ); 
  719.  
  720. if ( $options && is_array( $options ) ) { 
  721. $this->field_options += $options; 
  722.  
  723. if ( $key ) { 
  724. return array_key_exists( $key, $this->field_options ) ? $this->field_options[ $key ] : false; 
  725.  
  726. return $this->field_options; 
  727.  
  728. /** 
  729. * Fills in empty field parameters with defaults 
  730. * @since 1.1.0 
  731. * @param array $args Metabox field config array 
  732. */ 
  733. public function _set_field_defaults( $args ) { 
  734.  
  735. // Set up blank or default values for empty ones 
  736. $args = wp_parse_args( $args, array( 
  737. 'type' => '',  
  738. 'name' => '',  
  739. 'desc' => '',  
  740. 'before' => '',  
  741. 'after' => '',  
  742. 'options_cb' => '',  
  743. 'options' => array(),  
  744. 'attributes' => array(),  
  745. 'protocols' => null,  
  746. 'default' => null,  
  747. 'select_all_button' => true,  
  748. 'multiple' => false,  
  749. 'repeatable' => isset( $args['type'] ) && 'group' == $args['type'],  
  750. 'inline' => false,  
  751. 'on_front' => true,  
  752. 'show_names' => true,  
  753. 'date_format' => 'm\/d\/Y',  
  754. 'time_format' => 'h:i A',  
  755. 'description' => isset( $args['desc'] ) ? $args['desc'] : '',  
  756. 'preview_size' => 'file' == $args['type'] ? array( 350, 350 ) : array( 50, 50 ),  
  757. ) ); 
  758.  
  759. // Allow a filter override of the default value 
  760. $args['default'] = apply_filters( 'cmb2_default_filter', $args['default'], $this ); 
  761. // $args['multiple'] = isset( $args['multiple'] ) ? $args['multiple'] : ( 'multicheck' == $args['type'] ? true : false ); 
  762. $args['repeatable'] = $args['repeatable'] && ! $this->repeatable_exception( $args['type'] ); 
  763. $args['inline'] = $args['inline'] || false !== stripos( $args['type'], '_inline' ); 
  764.  
  765. // options param can be passed a callback as well 
  766. if ( is_callable( $args['options'] ) ) { 
  767. $args['options_cb'] = $args['options']; 
  768. $args['options'] = array(); 
  769.  
  770. $args['options'] = 'group' == $args['type'] ? wp_parse_args( $args['options'], array( 
  771. 'add_button' => __( 'Add Group', 'cmb2' ),  
  772. 'remove_button' => __( 'Remove Group', 'cmb2' ),  
  773. ) ) : $args['options']; 
  774.  
  775. $args['_id'] = $args['id']; 
  776. $args['_name'] = $args['id']; 
  777.  
  778. if ( $this->group ) { 
  779.  
  780. $args['id'] = $this->group->args( 'id' ) . '_' . $this->group->index . '_' . $args['id']; 
  781. $args['_name'] = $this->group->args( 'id' ) . '[' . $this->group->index . '][' . $args['_name'] . ']'; 
  782.  
  783. if ( 'wysiwyg' == $args['type'] ) { 
  784. $args['id'] = strtolower( str_ireplace( '-', '_', $args['id'] ) ); 
  785. $args['options']['textarea_name'] = $args['_name']; 
  786.  
  787. $option_types = apply_filters( 'cmb2_all_or_nothing_types', array( 'select', 'radio', 'radio_inline', 'taxonomy_select', 'taxonomy_radio', 'taxonomy_radio_inline' ), $this ); 
  788.  
  789. if ( in_array( $args['type'], $option_types, true ) ) { 
  790.  
  791. $args['show_option_none'] = isset( $args['show_option_none'] ) ? $args['show_option_none'] : false; 
  792. $args['show_option_none'] = true === $args['show_option_none'] ? __( 'None', 'cmb2' ) : $args['show_option_none']; 
  793.  
  794. if ( ! $args['show_option_none'] ) { 
  795. $off_by_default = in_array( $args['type'], array( 'select', 'radio', 'radio_inline' ), true ); 
  796. $args['show_option_none'] = $off_by_default ? false : __( 'None', 'cmb2' ); 
  797.  
  798.  
  799. return $args; 
  800.  
  801. /** 
  802. * Updates attributes array values unless they exist from the field config array 
  803. * @since 1.1.0 
  804. * @param array $attrs Array of attributes to update 
  805. */ 
  806. public function maybe_set_attributes( $attrs = array() ) { 
  807. return wp_parse_args( $this->args['attributes'], $attrs ); 
  808.  
/vendor/wordimpress/maps-builder-core/includes/libraries/metabox/includes/CMB2_Field.php  
  1. class CMB2_Field { 
  2.  
  3. /** 
  4. * Metabox object id 
  5. * @var mixed 
  6. * @since 1.1.0 
  7. */ 
  8. public $object_id = null; 
  9.  
  10. /** 
  11. * Metabox object type 
  12. * @var string 
  13. * @since 1.1.0 
  14. */ 
  15. public $object_type = ''; 
  16.  
  17. /** 
  18. * Field arguments 
  19. * @var mixed 
  20. * @since 1.1.0 
  21. */ 
  22. public $args = array(); 
  23.  
  24. /** 
  25. * Field group object or false (if no group) 
  26. * @var mixed 
  27. * @since 1.1.0 
  28. */ 
  29. public $group = false; 
  30.  
  31. /** 
  32. * Field meta value 
  33. * @var mixed 
  34. * @since 1.1.0 
  35. */ 
  36. public $value = null; 
  37.  
  38. /** 
  39. * Field meta value 
  40. * @var mixed 
  41. * @since 1.1.0 
  42. */ 
  43. public $escaped_value = null; 
  44.  
  45. /** 
  46. * Grouped Field's current numeric index during the save process 
  47. * @var mixed 
  48. * @since 2.0.0 
  49. */ 
  50. public $index = 0; 
  51.  
  52. /** 
  53. * Array of field options 
  54. * @var array 
  55. * @since 2.0.0 
  56. */ 
  57. protected $field_options = array(); 
  58.  
  59. /** 
  60. * Array of provided field text strings 
  61. * @var array 
  62. * @since 2.0.0 
  63. */ 
  64. protected $strings; 
  65.  
  66. /** 
  67. * Array of field param callback results 
  68. * @var array 
  69. * @since 2.0.0 
  70. */ 
  71. protected $callback_results = array(); 
  72.  
  73. /** 
  74. * Array of key => value data for saving. Likely $_POST data. 
  75. * @var array 
  76. * @since 2.0.0 
  77. */ 
  78. public $data_to_save = array(); 
  79.  
  80. /** 
  81. * Current field's CMB2 instance ID 
  82. * @var string 
  83. * @since 2.2.2 
  84. */ 
  85. public $cmb_id = ''; 
  86.  
  87. /** 
  88. * The field's render context. In most cases, 'edit', but can be 'display'. 
  89. * @var string 
  90. * @since 2.2.2 
  91. */ 
  92. public $render_context = 'edit'; 
  93.  
  94. /** 
  95. * Constructs our field object 
  96. * @since 1.1.0 
  97. * @param array $args Field arguments 
  98. */ 
  99. public function __construct( $args ) { 
  100.  
  101. if ( ! empty( $args['group_field'] ) ) { 
  102. $this->group = $args['group_field']; 
  103. $this->object_id = $this->group->object_id; 
  104. $this->object_type = $this->group->object_type; 
  105. $this->cmb_id = $this->group->cmb_id; 
  106. } else { 
  107. $this->object_id = isset( $args['object_id'] ) && '_' !== $args['object_id'] ? $args['object_id'] : 0; 
  108. $this->object_type = isset( $args['object_type'] ) ? $args['object_type'] : 'post'; 
  109.  
  110. if ( isset( $args['cmb_id'] ) ) { 
  111. $this->cmb_id = $args['cmb_id']; 
  112.  
  113. $this->args = $this->_set_field_defaults( $args['field_args'] ); 
  114.  
  115. if ( $this->object_id ) { 
  116. $this->value = $this->get_data(); 
  117.  
  118. /** 
  119. * Non-existent methods fallback to checking for field arguments of the same name 
  120. * @since 1.1.0 
  121. * @param string $name Method name 
  122. * @param array $arguments Array of passed-in arguments 
  123. * @return mixed Value of field argument 
  124. */ 
  125. public function __call( $name, $arguments ) { 
  126. $key = isset( $arguments[0] ) ? $arguments[0] : false; 
  127. return $this->args( $name, $key ); 
  128.  
  129. /** 
  130. * Retrieves the field id 
  131. * @since 1.1.0 
  132. * @param boolean $raw Whether to retrieve pre-modidifed id 
  133. * @return string Field id 
  134. */ 
  135. public function id( $raw = false ) { 
  136. $id = $raw ? '_id' : 'id'; 
  137. return $this->args( $id ); 
  138.  
  139. /** 
  140. * Get a field argument 
  141. * @since 1.1.0 
  142. * @param string $key Argument to check 
  143. * @param string $_key Sub argument to check 
  144. * @return mixed Argument value or false if non-existent 
  145. */ 
  146. public function args( $key = '', $_key = '' ) { 
  147. $arg = $this->_data( 'args', $key ); 
  148.  
  149. if ( in_array( $key, array( 'default', 'default_cb' ), true ) ) { 
  150.  
  151. $arg = $this->get_default(); 
  152.  
  153. } elseif ( $_key ) { 
  154.  
  155. $arg = isset( $arg[ $_key ] ) ? $arg[ $_key ] : false; 
  156.  
  157. return $arg; 
  158.  
  159. /** 
  160. * Retrieve a portion of a field property 
  161. * @since 1.1.0 
  162. * @param string $var Field property to check 
  163. * @param string $key Field property array key to check 
  164. * @return mixed Queried property value or false 
  165. */ 
  166. public function _data( $var, $key = '' ) { 
  167. $vars = $this->$var; 
  168. if ( $key ) { 
  169. return isset( $vars[ $key ] ) ? $vars[ $key ] : false; 
  170. return $vars; 
  171.  
  172. /** 
  173. * Get Field's value 
  174. * @since 1.1.0 
  175. * @param string $key If value is an array, is used to get array key->value 
  176. * @return mixed Field value or false if non-existent 
  177. */ 
  178. public function value( $key = '' ) { 
  179. return $this->_data( 'value', $key ); 
  180.  
  181. /** 
  182. * Retrieves metadata/option data 
  183. * @since 1.0.1 
  184. * @param string $field_id Meta key/Option array key 
  185. * @param array $args Override arguments 
  186. * @return mixed Meta/Option value 
  187. */ 
  188. public function get_data( $field_id = '', $args = array() ) { 
  189. if ( $field_id ) { 
  190. $args['field_id'] = $field_id; 
  191. } else if ( $this->group ) { 
  192. $args['field_id'] = $this->group->id(); 
  193.  
  194. $a = $this->data_args( $args ); 
  195.  
  196. /** 
  197. * Filter whether to override getting of meta value. 
  198. * Returning a non 'cmb2_field_no_override_val' value 
  199. * will effectively short-circuit the value retrieval. 
  200. * @since 2.0.0 
  201. * @param mixed $value The value get_metadata() should 
  202. * return - a single metadata value,  
  203. * or an array of values. 
  204. * @param int $object_id Object ID. 
  205. * @param array $args { 
  206. * An array of arguments for retrieving data 
  207. * @type string $type The current object type 
  208. * @type int $id The current object ID 
  209. * @type string $field_id The ID of the field being requested 
  210. * @type bool $repeat Whether current field is repeatable 
  211. * @type bool $single Whether current field is a single database row 
  212. * } 
  213. * @param CMB2_Field object $field This field object 
  214. */ 
  215. $data = apply_filters( 'cmb2_override_meta_value', 'cmb2_field_no_override_val', $this->object_id, $a, $this ); 
  216.  
  217. /** 
  218. * Filter and parameters are documented for 'cmb2_override_meta_value' filter (above). 
  219. * The dynamic portion of the hook, $field_id, refers to the current 
  220. * field id paramater. Returning a non 'cmb2_field_no_override_val' value 
  221. * will effectively short-circuit the value retrieval. 
  222. * @since 2.0.0 
  223. */ 
  224. $data = apply_filters( "cmb2_override_{$a['field_id']}_meta_value", $data, $this->object_id, $a, $this ); 
  225.  
  226. // If no override, get value normally 
  227. if ( 'cmb2_field_no_override_val' === $data ) { 
  228. $data = 'options-page' === $a['type'] 
  229. ? cmb2_options( $a['id'] )->get( $a['field_id'] ) 
  230. : get_metadata( $a['type'], $a['id'], $a['field_id'], ( $a['single'] || $a['repeat'] ) ); 
  231.  
  232. if ( $this->group ) { 
  233.  
  234. $data = is_array( $data ) && isset( $data[ $this->group->index ][ $this->args( '_id' ) ] ) 
  235. ? $data[ $this->group->index ][ $this->args( '_id' ) ] 
  236. : false; 
  237.  
  238. return $data; 
  239.  
  240. /** 
  241. * Updates metadata/option data 
  242. * @since 1.0.1 
  243. * @param mixed $new_value Value to update data with 
  244. * @param bool $single Whether data is an array (add_metadata) 
  245. */ 
  246. public function update_data( $new_value, $single = true ) { 
  247. $a = $this->data_args( array( 'single' => $single ) ); 
  248.  
  249. $a['value'] = $a['repeat'] ? array_values( $new_value ) : $new_value; 
  250.  
  251. /** 
  252. * Filter whether to override saving of meta value. 
  253. * Returning a non-null value will effectively short-circuit the function. 
  254. * @since 2.0.0 
  255. * @param null|bool $check Whether to allow updating metadata for the given type. 
  256. * @param array $args { 
  257. * Array of data about current field including: 
  258. * @type string $value The value to set 
  259. * @type string $type The current object type 
  260. * @type int $id The current object ID 
  261. * @type string $field_id The ID of the field being updated 
  262. * @type bool $repeat Whether current field is repeatable 
  263. * @type bool $single Whether current field is a single database row 
  264. * } 
  265. * @param array $field_args All field arguments 
  266. * @param CMB2_Field object $field This field object 
  267. */ 
  268. $override = apply_filters( 'cmb2_override_meta_save', null, $a, $this->args(), $this ); 
  269.  
  270. /** 
  271. * Filter and parameters are documented for 'cmb2_override_meta_save' filter (above). 
  272. * The dynamic portion of the hook, $a['field_id'], refers to the current 
  273. * field id paramater. Returning a non-null value 
  274. * will effectively short-circuit the function. 
  275. * @since 2.0.0 
  276. */ 
  277. $override = apply_filters( "cmb2_override_{$a['field_id']}_meta_save", $override, $a, $this->args(), $this ); 
  278.  
  279. // If override, return that 
  280. if ( null !== $override ) { 
  281. return $override; 
  282.  
  283. // Options page handling (or temp data store) 
  284. if ( 'options-page' === $a['type'] || empty( $a['id'] ) ) { 
  285. return cmb2_options( $a['id'] )->update( $a['field_id'], $a['value'], false, $a['single'] ); 
  286.  
  287. // Add metadata if not single 
  288. if ( ! $a['single'] ) { 
  289. return add_metadata( $a['type'], $a['id'], $a['field_id'], $a['value'], false ); 
  290.  
  291. // Delete meta if we have an empty array 
  292. if ( is_array( $a['value'] ) && empty( $a['value'] ) ) { 
  293. return delete_metadata( $a['type'], $a['id'], $a['field_id'], $this->value ); 
  294.  
  295. // Update metadata 
  296. return update_metadata( $a['type'], $a['id'], $a['field_id'], $a['value'] ); 
  297.  
  298. /** 
  299. * Removes/updates metadata/option data 
  300. * @since 1.0.1 
  301. * @param string $old Old value 
  302. */ 
  303. public function remove_data( $old = '' ) { 
  304. $a = $this->data_args( array( 'old' => $old ) ); 
  305.  
  306. /** 
  307. * Filter whether to override removing of meta value. 
  308. * Returning a non-null value will effectively short-circuit the function. 
  309. * @since 2.0.0 
  310. * @param null|bool $delete Whether to allow metadata deletion of the given type. 
  311. * @param array $args Array of data about current field including: 
  312. * 'type' : Current object type 
  313. * 'id' : Current object ID 
  314. * 'field_id' : Current Field ID 
  315. * 'repeat' : Whether current field is repeatable 
  316. * 'single' : Whether to save as a 
  317. * single meta value 
  318. * @param array $field_args All field arguments 
  319. * @param CMB2_Field object $field This field object 
  320. */ 
  321. $override = apply_filters( 'cmb2_override_meta_remove', null, $a, $this->args(), $this ); 
  322.  
  323. /** 
  324. * Filter whether to override removing of meta value. 
  325. * The dynamic portion of the hook, $a['field_id'], refers to the current 
  326. * field id paramater. Returning a non-null value 
  327. * will effectively short-circuit the function. 
  328. * @since 2.0.0 
  329. * @param null|bool $delete Whether to allow metadata deletion of the given type. 
  330. * @param array $args Array of data about current field including: 
  331. * 'type' : Current object type 
  332. * 'id' : Current object ID 
  333. * 'field_id' : Current Field ID 
  334. * 'repeat' : Whether current field is repeatable 
  335. * 'single' : Whether to save as a 
  336. * single meta value 
  337. * @param array $field_args All field arguments 
  338. * @param CMB2_Field object $field This field object 
  339. */ 
  340. $override = apply_filters( "cmb2_override_{$a['field_id']}_meta_remove", $override, $a, $this->args(), $this ); 
  341.  
  342. // If no override, remove as usual 
  343. if ( null !== $override ) { 
  344. return $override; 
  345. // Option page handling 
  346. elseif ( 'options-page' === $a['type'] || empty( $a['id'] ) ) { 
  347. return cmb2_options( $a['id'] )->remove( $a['field_id'] ); 
  348.  
  349. // Remove metadata 
  350. return delete_metadata( $a['type'], $a['id'], $a['field_id'], $old ); 
  351.  
  352. /** 
  353. * Data variables for get/set data methods 
  354. * @since 1.1.0 
  355. * @param array $args Override arguments 
  356. * @return array Updated arguments 
  357. */ 
  358. public function data_args( $args = array() ) { 
  359. $args = wp_parse_args( $args, array( 
  360. 'type' => $this->object_type,  
  361. 'id' => $this->object_id,  
  362. 'field_id' => $this->id( true ),  
  363. 'repeat' => $this->args( 'repeatable' ),  
  364. 'single' => ! $this->args( 'multiple' ),  
  365. ) ); 
  366. return $args; 
  367.  
  368. /** 
  369. * Checks if field has a registered sanitization callback 
  370. * @since 1.0.1 
  371. * @param mixed $meta_value Meta value 
  372. * @return mixed Possibly sanitized meta value 
  373. */ 
  374. public function sanitization_cb( $meta_value ) { 
  375.  
  376. if ( $this->args( 'repeatable' ) && is_array( $meta_value ) ) { 
  377. // Remove empties 
  378. $meta_value = array_filter( $meta_value ); 
  379.  
  380. // Check if the field has a registered validation callback 
  381. $cb = $this->maybe_callback( 'sanitization_cb' ); 
  382. if ( false === $cb ) { 
  383. // If requesting NO validation, return meta value 
  384. return $meta_value; 
  385. } elseif ( $cb ) { 
  386. // Ok, callback is good, let's run it. 
  387. return call_user_func( $cb, $meta_value, $this->args(), $this ); 
  388.  
  389. $sanitizer = new CMB2_Sanitize( $this, $meta_value ); 
  390.  
  391. /** 
  392. * Filter the value before it is saved. 
  393. * The dynamic portion of the hook name, $this->type(), refers to the field type. 
  394. * Passing a non-null value to the filter will short-circuit saving 
  395. * the field value, saving the passed value instead. 
  396. * @param bool|mixed $override_value Sanitization/Validation override value to return. 
  397. * Default false to skip it. 
  398. * @param mixed $value The value to be saved to this field. 
  399. * @param int $object_id The ID of the object where the value will be saved 
  400. * @param array $field_args The current field's arguments 
  401. * @param object $sanitizer This `CMB2_Sanitize` object 
  402. */ 
  403. $override_value = apply_filters( "cmb2_sanitize_{$this->type()}", null, $sanitizer->value, $this->object_id, $this->args(), $sanitizer ); 
  404.  
  405. if ( null !== $override_value ) { 
  406. return $override_value; 
  407.  
  408. // Sanitization via 'CMB2_Sanitize' 
  409. return $sanitizer->{$this->type()}(); 
  410.  
  411. /** 
  412. * Process $_POST data to save this field's value 
  413. * @since 2.0.3 
  414. * @param array $data_to_save $_POST data to check 
  415. * @return bool Result of save 
  416. */ 
  417. public function save_field_from_data( array $data_to_save ) { 
  418. $this->data_to_save = $data_to_save; 
  419.  
  420. $meta_value = isset( $this->data_to_save[ $this->id( true ) ] ) 
  421. ? $this->data_to_save[ $this->id( true ) ] 
  422. : null; 
  423.  
  424. return $this->save_field( $meta_value ); 
  425.  
  426. /** 
  427. * Sanitize/store a value to this field 
  428. * @since 2.0.0 
  429. * @param array $meta_value Desired value to sanitize/store 
  430. * @return bool Result of save 
  431. */ 
  432. public function save_field( $meta_value ) { 
  433.  
  434. $new_value = $this->sanitization_cb( $meta_value ); 
  435. $old = $this->get_data(); 
  436. $updated = false; 
  437. $action = ''; 
  438.  
  439. if ( $this->args( 'multiple' ) && ! $this->args( 'repeatable' ) && ! $this->group ) { 
  440.  
  441. $this->remove_data(); 
  442. $count = 0; 
  443.  
  444. if ( ! empty( $new_value ) ) { 
  445. foreach ( $new_value as $add_new ) { 
  446. if ( $this->update_data( $add_new, false ) ) { 
  447. $count++; 
  448.  
  449. $updated = $count ? $count : false; 
  450. $action = 'repeatable'; 
  451.  
  452. } elseif ( ! cmb2_utils()->isempty( $new_value ) && $new_value !== $old ) { 
  453. $updated = $this->update_data( $new_value ); 
  454. $action = 'updated'; 
  455. } elseif ( cmb2_utils()->isempty( $new_value ) ) { 
  456. $updated = $this->remove_data(); 
  457. $action = 'removed'; 
  458.  
  459. if ( $updated ) { 
  460. $this->value = $this->get_data(); 
  461.  
  462. $field_id = $this->id( true ); 
  463.  
  464. /** 
  465. * Hooks after save field action. 
  466. * @since 2.2.0 
  467. * @param string $field_id the current field id paramater. 
  468. * @param bool $updated Whether the metadata update action occurred. 
  469. * @param string $action Action performed. Could be "repeatable", "updated", or "removed". 
  470. * @param CMB2_Field object $field This field object 
  471. */ 
  472. do_action( 'cmb2_save_field', $field_id, $updated, $action, $this ); 
  473.  
  474. /** 
  475. * Hooks after save field action. 
  476. * The dynamic portion of the hook, $field_id, refers to the 
  477. * current field id paramater. 
  478. * @since 2.2.0 
  479. * @param bool $updated Whether the metadata update action occurred. 
  480. * @param string $action Action performed. Could be "repeatable", "updated", or "removed". 
  481. * @param CMB2_Field object $field This field object 
  482. */ 
  483. do_action( "cmb2_save_field_{$field_id}", $updated, $action, $this ); 
  484.  
  485. return $updated; 
  486.  
  487. /** 
  488. * Checks if field has a callback value 
  489. * @since 1.0.1 
  490. * @param string $cb Callback string 
  491. * @return mixed NULL, false for NO validation, or $cb string if it exists. 
  492. */ 
  493. public function maybe_callback( $cb ) { 
  494. $field_args = $this->args(); 
  495. if ( ! isset( $field_args[ $cb ] ) ) { 
  496. return; 
  497.  
  498. // Check if metabox is requesting NO validation 
  499. $cb = false !== $field_args[ $cb ] && 'false' !== $field_args[ $cb ] ? $field_args[ $cb ] : false; 
  500.  
  501. // If requesting NO validation, return false 
  502. if ( ! $cb ) { 
  503. return false; 
  504.  
  505. if ( is_callable( $cb ) ) { 
  506. return $cb; 
  507.  
  508. /** 
  509. * Determine if current type is exempt from escaping 
  510. * @since 1.1.0 
  511. * @return bool True if exempt 
  512. */ 
  513. public function escaping_exception() { 
  514. // These types cannot be escaped 
  515. return in_array( $this->type(), array( 
  516. 'file_list',  
  517. 'multicheck',  
  518. 'text_datetime_timestamp_timezone',  
  519. ) ); 
  520.  
  521. /** 
  522. * Determine if current type cannot be repeatable 
  523. * @since 1.1.0 
  524. * @param string $type Field type to check 
  525. * @return bool True if type cannot be repeatable 
  526. */ 
  527. public function repeatable_exception( $type ) { 
  528. // These types cannot be escaped 
  529. $internal_fields = array( 
  530. // Use file_list instead 
  531. 'file' => 1,  
  532. 'radio' => 1,  
  533. 'title' => 1,  
  534. // @todo Ajax load wp_editor: http://wordpress.stackexchange.com/questions/51776/how-to-load-wp-editor-through-ajax-jquery 
  535. 'wysiwyg' => 1,  
  536. 'checkbox' => 1,  
  537. 'radio_inline' => 1,  
  538. 'taxonomy_radio' => 1,  
  539. 'taxonomy_select' => 1,  
  540. 'taxonomy_multicheck' => 1,  
  541. ); 
  542.  
  543. /** 
  544. * Filter field types that are non-repeatable. 
  545. * Note that this does *not* allow overriding the default non-repeatable types. 
  546. * @since 2.1.1 
  547. * @param array $fields Array of fields designated as non-repeatable. Note that the field names are *keys*,  
  548. * and not values. The value can be anything, because it is meaningless. Example: 
  549. * array( 'my_custom_field' => 1 ) 
  550. */ 
  551. $all_fields = array_merge( apply_filters( 'cmb2_non_repeatable_fields', array() ), $internal_fields ); 
  552. return isset( $all_fields[ $type ] ); 
  553.  
  554. /** 
  555. * Escape the value before output. Defaults to 'esc_attr()' 
  556. * @since 1.0.1 
  557. * @param callable $func Escaping function (if not esc_attr()) 
  558. * @param mixed $meta_value Meta value 
  559. * @return mixed Final value 
  560. */ 
  561. public function escaped_value( $func = 'esc_attr', $meta_value = '' ) { 
  562.  
  563. if ( null !== $this->escaped_value ) { 
  564. return $this->escaped_value; 
  565.  
  566. $meta_value = $meta_value ? $meta_value : $this->value(); 
  567.  
  568. // Check if the field has a registered escaping callback 
  569. if ( $cb = $this->maybe_callback( 'escape_cb' ) ) { 
  570. // Ok, callback is good, let's run it. 
  571. return call_user_func( $cb, $meta_value, $this->args(), $this ); 
  572.  
  573. // Or custom escaping filter can be used 
  574. $esc = apply_filters( "cmb2_types_esc_{$this->type()}", null, $meta_value, $this->args(), $this ); 
  575. if ( null !== $esc ) { 
  576. return $esc; 
  577.  
  578. if ( false === $cb || $this->escaping_exception() ) { 
  579. // If requesting NO escaping, return meta value 
  580. return $this->val_or_default( $meta_value ); 
  581.  
  582. // escaping function passed in? 
  583. $func = $func ? $func : 'esc_attr'; 
  584. $meta_value = $this->val_or_default( $meta_value ); 
  585.  
  586. if ( is_array( $meta_value ) ) { 
  587. foreach ( $meta_value as $key => $value ) { 
  588. $meta_value[ $key ] = call_user_func( $func, $value ); 
  589. } else { 
  590. $meta_value = call_user_func( $func, $meta_value ); 
  591.  
  592. $this->escaped_value = $meta_value; 
  593. return $this->escaped_value; 
  594.  
  595. /** 
  596. * Return non-empty value or field default if value IS empty 
  597. * @since 2.0.0 
  598. * @param mixed $meta_value Field value 
  599. * @return mixed Field value, or default value 
  600. */ 
  601. public function val_or_default( $meta_value ) { 
  602. return ! cmb2_utils()->isempty( $meta_value ) ? $meta_value : $this->get_default(); 
  603.  
  604. /** 
  605. * Offset a time value based on timezone 
  606. * @since 1.0.0 
  607. * @return string Offset time string 
  608. */ 
  609. public function field_timezone_offset() { 
  610. return cmb2_utils()->timezone_offset( $this->field_timezone() ); 
  611.  
  612. /** 
  613. * Return timezone string 
  614. * @since 1.0.0 
  615. * @return string Timezone string 
  616. */ 
  617. public function field_timezone() { 
  618. $value = ''; 
  619.  
  620. // Is timezone arg set? 
  621. if ( $this->args( 'timezone' ) ) { 
  622. $value = $this->args( 'timezone' ); 
  623. // Is there another meta key with a timezone stored as its value we should use? 
  624. else if ( $this->args( 'timezone_meta_key' ) ) { 
  625. $value = $this->get_data( $this->args( 'timezone_meta_key' ) ); 
  626.  
  627. return $value; 
  628.  
  629. /** 
  630. * Format the timestamp field value based on the field date/time format arg 
  631. * @since 2.0.0 
  632. * @param int $meta_value Timestamp 
  633. * @param string $format Either date_format or time_format 
  634. * @return string Formatted date 
  635. */ 
  636. public function format_timestamp( $meta_value, $format = 'date_format' ) { 
  637. return date( stripslashes( $this->args( $format ) ), $meta_value ); 
  638.  
  639. /** 
  640. * Return a formatted timestamp for a field 
  641. * @since 2.0.0 
  642. * @param string $format Either date_format or time_format 
  643. * @param string $meta_value Optional meta value to check 
  644. * @return string Formatted date 
  645. */ 
  646. public function get_timestamp_format( $format = 'date_format', $meta_value = 0 ) { 
  647. $meta_value = $meta_value ? $meta_value : $this->escaped_value(); 
  648. $meta_value = cmb2_utils()->make_valid_time_stamp( $meta_value ); 
  649.  
  650. if ( empty( $meta_value ) ) { 
  651. return ''; 
  652.  
  653. return is_array( $meta_value ) 
  654. ? array_map( array( $this, 'format_timestamp' ), $meta_value, $format ) 
  655. : $this->format_timestamp( $meta_value, $format ); 
  656.  
  657. /** 
  658. * Get timestamp from text date 
  659. * @since 2.2.0 
  660. * @param string $value Date value 
  661. * @return mixed Unix timestamp representing the date. 
  662. */ 
  663. public function get_timestamp_from_value( $value ) { 
  664. return cmb2_utils()->get_timestamp_from_value( $value, $this->args( 'date_format' ) ); 
  665.  
  666. /** 
  667. * Get field render callback and Render the field row 
  668. * @since 1.0.0 
  669. */ 
  670. public function render_field() { 
  671. $this->render_context = 'edit'; 
  672.  
  673. $this->peform_param_callback( 'render_row_cb' ); 
  674.  
  675. // For chaining 
  676. return $this; 
  677.  
  678. /** 
  679. * Default field render callback 
  680. * @since 2.1.1 
  681. */ 
  682. public function render_field_callback() { 
  683.  
  684. // If field is requesting to not be shown on the front-end 
  685. if ( ! is_admin() && ! $this->args( 'on_front' ) ) { 
  686. return; 
  687.  
  688. // If field is requesting to be conditionally shown 
  689. if ( ! $this->should_show() ) { 
  690. return; 
  691.  
  692. $this->peform_param_callback( 'before_row' ); 
  693.  
  694. printf( "<div class=\"cmb-row %s\" data-fieldtype=\"%s\">\n", $this->row_classes(), $this->type() ); 
  695.  
  696. if ( ! $this->args( 'show_names' ) ) { 
  697. echo "\n\t<div class=\"cmb-td\">\n"; 
  698.  
  699. $this->peform_param_callback( 'label_cb' ); 
  700.  
  701. } else { 
  702.  
  703. if ( $this->get_param_callback_result( 'label_cb' ) ) { 
  704. echo '<div class="cmb-th">', $this->peform_param_callback( 'label_cb' ), '</div>'; 
  705.  
  706. echo "\n\t<div class=\"cmb-td\">\n"; 
  707.  
  708. $this->peform_param_callback( 'before' ); 
  709.  
  710. $field_type = new CMB2_Types( $this ); 
  711. $field_type->render(); 
  712.  
  713. $this->peform_param_callback( 'after' ); 
  714.  
  715. echo "\n\t</div>\n</div>"; 
  716.  
  717. $this->peform_param_callback( 'after_row' ); 
  718.  
  719. // For chaining 
  720. return $this; 
  721.  
  722. /** 
  723. * The default label_cb callback (if not a title field) 
  724. * @since 2.1.1 
  725. * @return string Label html markup 
  726. */ 
  727. public function label() { 
  728. if ( ! $this->args( 'name' ) ) { 
  729. return ''; 
  730.  
  731. $style = ! $this->args( 'show_names' ) ? ' style="display:none;"' : ''; 
  732.  
  733. return sprintf( "\n" . '<label%1$s for="%2$s">%3$s</label>' . "\n", $style, $this->id(), $this->args( 'name' ) ); 
  734.  
  735. /** 
  736. * Defines the classes for the current CMB2 field row 
  737. * @since 2.0.0 
  738. * @return string Space concatenated list of classes 
  739. */ 
  740. public function row_classes() { 
  741.  
  742. $classes = array(); 
  743.  
  744. /** 
  745. * By default, 'text_url' and 'text' fields get table-like styling 
  746. * @since 2.0.0 
  747. * @param array $field_types The types of fields which should get the 'table-layout' class 
  748. */ 
  749. $repeat_table_rows_types = apply_filters( 'cmb2_repeat_table_row_types', array( 
  750. 'text_url', 'text',  
  751. ) ); 
  752.  
  753. $conditional_classes = array( 
  754. 'cmb-type-' . str_replace( '_', '-', sanitize_html_class( $this->type() ) ) => true,  
  755. 'cmb2-id-' . str_replace( '_', '-', sanitize_html_class( $this->id() ) ) => true,  
  756. 'cmb-repeat' => $this->args( 'repeatable' ),  
  757. 'cmb-repeat-group-field' => $this->group,  
  758. 'cmb-inline' => $this->args( 'inline' ),  
  759. 'table-layout' => 'edit' === $this->render_context && in_array( $this->type(), $repeat_table_rows_types ),  
  760. ); 
  761.  
  762. foreach ( $conditional_classes as $class => $condition ) { 
  763. if ( $condition ) { 
  764. $classes[] = $class; 
  765.  
  766. if ( $added_classes = $this->get_param_callback_result( 'row_classes' ) ) { 
  767. $added_classes = is_array( $added_classes ) ? implode( ' ', $added_classes ) : (string) $added_classes; 
  768.  
  769. if ( $added_classes ) { 
  770. $classes[] = esc_attr( $added_classes ); 
  771.  
  772. /** 
  773. * Globally filter row classes 
  774. * @since 2.0.0 
  775. * @param string $classes Space-separated list of row classes 
  776. * @param CMB2_Field object $field This field object 
  777. */ 
  778. return apply_filters( 'cmb2_row_classes', implode( ' ', $classes ), $this ); 
  779.  
  780.  
  781.  
  782. /** 
  783. * Get field display callback and render the display value in the column. 
  784. * @since 2.2.2 
  785. */ 
  786. public function render_column() { 
  787. $this->render_context = 'display'; 
  788.  
  789. $this->peform_param_callback( 'display_cb' ); 
  790.  
  791. // For chaining 
  792. return $this; 
  793.  
  794. /** 
  795. * Default callback to outputs field value in a display format. 
  796. * @since 2.2.2 
  797. */ 
  798. public function display_value_callback() { 
  799. // If field is requesting to be conditionally shown 
  800. if ( ! $this->should_show() ) { 
  801. return; 
  802.  
  803. $display = new CMB2_Field_Display( $this ); 
  804.  
  805. /** 
  806. * A filter to bypass the default display. 
  807. * The dynamic portion of the hook name, $this->type(), refers to the field type. 
  808. * Passing a non-null value to the filter will short-circuit the default display. 
  809. * @param bool|mixed $pre_output Default null value. 
  810. * @param CMB2_Field $field This field object. 
  811. * @param CMB2_Field_Display $display The `CMB2_Field_Display` object. 
  812. */ 
  813. $pre_output = apply_filters( "cmb2_pre_field_display_{$this->type()}", null, $this, $display ); 
  814.  
  815. if ( null !== $pre_output ) { 
  816. echo $pre_output; 
  817. return; 
  818.  
  819. $this->peform_param_callback( 'before_display_wrap' ); 
  820.  
  821. printf( "<div class=\"cmb-column %s\" data-fieldtype=\"%s\">\n", $this->row_classes( 'display' ), $this->type() ); 
  822.  
  823. $this->peform_param_callback( 'before_display' ); 
  824.  
  825. CMB2_Field_Display::get( $this )->display(); 
  826.  
  827. $this->peform_param_callback( 'after_display' ); 
  828.  
  829. echo "\n</div>"; 
  830.  
  831. $this->peform_param_callback( 'after_display_wrap' ); 
  832.  
  833. // For chaining 
  834. return $this; 
  835.  
  836. /** 
  837. * Determine whether this field should show, based on the 'show_on_cb' callback. 
  838. * @since 2.0.9 
  839. * @return bool Whether the field should be shown. 
  840. */ 
  841. public function should_show() { 
  842. // Default to showing the field 
  843. $show = true; 
  844.  
  845. // Use the callback to determine showing the field, if it exists 
  846. if ( is_callable( $this->args( 'show_on_cb' ) ) ) { 
  847. $show = call_user_func( $this->args( 'show_on_cb' ), $this ); 
  848.  
  849. return $show; 
  850.  
  851. /** 
  852. * Displays the results of the param callbacks. 
  853. * @since 2.0.0 
  854. * @param string $param Field parameter 
  855. */ 
  856. public function peform_param_callback( $param ) { 
  857. echo $this->get_param_callback_result( $param ); 
  858.  
  859. /** 
  860. * Store results of the param callbacks for continual access 
  861. * @since 2.0.0 
  862. * @param string $param Field parameter 
  863. * @return mixed Results of param/param callback 
  864. */ 
  865. public function get_param_callback_result( $param ) { 
  866.  
  867. // If we've already retrieved this param's value,  
  868. if ( array_key_exists( $param, $this->callback_results ) ) { 
  869.  
  870. // send it back 
  871. return $this->callback_results[ $param ]; 
  872.  
  873. // Check if parameter has registered a callback. 
  874. if ( $cb = $this->maybe_callback( $param ) ) { 
  875.  
  876. // Ok, callback is good, let's run it and store the result. 
  877. ob_start(); 
  878. $returned = call_user_func( $cb, $this->args(), $this ); 
  879.  
  880. // Grab the result from the output buffer and store it. 
  881. $echoed = ob_get_clean(); 
  882.  
  883. // This checks if the user returned or echoed their callback. 
  884. // Defaults to using the echoed value. 
  885. $this->callback_results[ $param ] = $echoed ? $echoed : $returned; 
  886.  
  887. } else { 
  888.  
  889. // Otherwise just get whatever is there. 
  890. $this->callback_results[ $param ] = isset( $this->args[ $param ] ) ? $this->args[ $param ] : false; 
  891.  
  892. return $this->callback_results[ $param ]; 
  893.  
  894. /** 
  895. * Replaces a hash key - {#} - with the repeatable index 
  896. * @since 1.2.0 
  897. * @param string $value Value to update 
  898. * @return string Updated value 
  899. */ 
  900. public function replace_hash( $value ) { 
  901. // Replace hash with 1 based count 
  902. return str_ireplace( '{#}', ( $this->index + 1 ), $value ); 
  903.  
  904. /** 
  905. * Retrieve text parameter from field's text array (if it has one), or use fallback text 
  906. * For back-compatibility, falls back to checking the options array. 
  907. * @since 2.2.2 
  908. * @param string $text_key Key in field's text array 
  909. * @param string $fallback Fallback text 
  910. * @return string Text 
  911. */ 
  912. public function string( $text_key, $fallback ) { 
  913. // If null, populate with our field strings values. 
  914. if ( null === $this->strings ) { 
  915. $this->strings = (array) $this->args['text']; 
  916.  
  917. if ( is_callable( $this->args['text_cb'] ) ) { 
  918. $strings = call_user_func( $this->args['text_cb'], $this ); 
  919.  
  920. if ( $strings && is_array( $strings ) ) { 
  921. $this->strings += $strings; 
  922.  
  923. // If we have that string value, send it back. 
  924. if ( isset( $this->strings[ $text_key ] ) ) { 
  925. return $this->strings[ $text_key ]; 
  926.  
  927. // Check options for back-compat. 
  928. $string = $this->options( $text_key ); 
  929.  
  930. return $string ? $string : $fallback; 
  931.  
  932. /** 
  933. * Retrieve options args. Calls options_cb if it exists. 
  934. * @since 2.0.0 
  935. * @param string $key Specific option to retrieve 
  936. * @return array Array of options 
  937. */ 
  938. public function options( $key = '' ) { 
  939. if ( ! empty( $this->field_options ) ) { 
  940. if ( $key ) { 
  941. return array_key_exists( $key, $this->field_options ) ? $this->field_options[ $key ] : false; 
  942.  
  943. return $this->field_options; 
  944.  
  945. $this->field_options = (array) $this->args['options']; 
  946.  
  947. if ( is_callable( $this->args['options_cb'] ) ) { 
  948. $options = call_user_func( $this->args['options_cb'], $this ); 
  949.  
  950. if ( $options && is_array( $options ) ) { 
  951. $this->field_options = $options + $this->field_options; 
  952.  
  953. if ( $key ) { 
  954. return array_key_exists( $key, $this->field_options ) ? $this->field_options[ $key ] : false; 
  955.  
  956. return $this->field_options; 
  957.  
  958. /** 
  959. * Get CMB2_Field default value, either from default param or default_cb param. 
  960. * @since 0.2.2 
  961. * @return mixed Default field value 
  962. */ 
  963. public function get_default() { 
  964. if ( null !== $this->args['default'] ) { 
  965. return $this->args['default']; 
  966.  
  967. $param = is_callable( $this->args['default_cb'] ) ? 'default_cb' : 'default'; 
  968. $default = $this->get_param_callback_result( $param ); 
  969.  
  970. // Allow a filter override of the default value 
  971. $this->args['default'] = apply_filters( 'cmb2_default_filter', $default, $this ); 
  972.  
  973. return $this->args['default']; 
  974.  
  975. /** 
  976. * Fills in empty field parameters with defaults 
  977. * @since 1.1.0 
  978. * @param array $args Metabox field config array 
  979. */ 
  980. public function _set_field_defaults( $args ) { 
  981.  
  982. // Set up blank or default values for empty ones 
  983. $args = wp_parse_args( $args, array( 
  984. 'type' => '',  
  985. 'name' => '',  
  986. 'desc' => '',  
  987. 'before' => '',  
  988. 'after' => '',  
  989. 'options' => array(),  
  990. 'options_cb' => '',  
  991. 'text' => array(),  
  992. 'text_cb' => '',  
  993. 'attributes' => array(),  
  994. 'protocols' => null,  
  995. 'default' => null,  
  996. 'default_cb' => '',  
  997. 'select_all_button' => true,  
  998. 'multiple' => false,  
  999. 'repeatable' => isset( $args['type'] ) && 'group' == $args['type'],  
  1000. 'inline' => false,  
  1001. 'on_front' => true,  
  1002. 'show_names' => true,  
  1003. 'date_format' => 'm\/d\/Y',  
  1004. 'time_format' => 'h:i A',  
  1005. 'description' => isset( $args['desc'] ) ? $args['desc'] : '',  
  1006. 'preview_size' => 'file' == $args['type'] ? array( 350, 350 ) : array( 50, 50 ),  
  1007. 'render_row_cb' => array( $this, 'render_field_callback' ),  
  1008. 'display_cb' => array( $this, 'display_value_callback' ),  
  1009. 'label_cb' => 'title' != $args['type'] ? array( $this, 'label' ) : '',  
  1010. 'column' => false,  
  1011. ) ); 
  1012.  
  1013. // default param can be passed a callback as well 
  1014. if ( is_callable( $args['default'] ) ) { 
  1015. $args['default_cb'] = $args['default']; 
  1016. $args['default'] = null; 
  1017.  
  1018. $args['repeatable'] = $args['repeatable'] && ! $this->repeatable_exception( $args['type'] ); 
  1019. $args['inline'] = $args['inline'] || false !== stripos( $args['type'], '_inline' ); 
  1020.  
  1021. // options param can be passed a callback as well 
  1022. if ( is_callable( $args['options'] ) ) { 
  1023. $args['options_cb'] = $args['options']; 
  1024. $args['options'] = array(); 
  1025.  
  1026. $args['options'] = 'group' == $args['type'] ? wp_parse_args( $args['options'], array( 
  1027. 'add_button' => __( 'Add Group', 'cmb2' ),  
  1028. 'remove_button' => __( 'Remove Group', 'cmb2' ),  
  1029. ) ) : $args['options']; 
  1030.  
  1031. $args['_id'] = $args['id']; 
  1032. $args['_name'] = $args['id']; 
  1033.  
  1034. if ( $this->group ) { 
  1035.  
  1036. $args['id'] = $this->group->args( 'id' ) . '_' . $this->group->index . '_' . $args['id']; 
  1037. $args['_name'] = $this->group->args( 'id' ) . '[' . $this->group->index . '][' . $args['_name'] . ']'; 
  1038.  
  1039. if ( 'wysiwyg' == $args['type'] ) { 
  1040. $args['id'] = strtolower( str_ireplace( '-', '_', $args['id'] ) ); 
  1041. $args['options']['textarea_name'] = $args['_name']; 
  1042.  
  1043. $option_types = apply_filters( 'cmb2_all_or_nothing_types', array( 'select', 'radio', 'radio_inline', 'taxonomy_select', 'taxonomy_radio', 'taxonomy_radio_inline' ), $this ); 
  1044.  
  1045. if ( in_array( $args['type'], $option_types, true ) ) { 
  1046.  
  1047. $args['show_option_none'] = isset( $args['show_option_none'] ) ? $args['show_option_none'] : null; 
  1048. $args['show_option_none'] = true === $args['show_option_none'] ? __( 'None', 'cmb2' ) : $args['show_option_none']; 
  1049.  
  1050. if ( null === $args['show_option_none'] ) { 
  1051. $off_by_default = in_array( $args['type'], array( 'select', 'radio', 'radio_inline' ), true ); 
  1052. $args['show_option_none'] = $off_by_default ? false : __( 'None', 'cmb2' ); 
  1053.  
  1054.  
  1055. $args['has_supporting_data'] = in_array( 
  1056. $args['type'],  
  1057. array( 
  1058. // CMB2_Sanitize::_save_file_id_value()/CMB2_Sanitize::_get_group_file_value_array() 
  1059. 'file',  
  1060. // See CMB2_Sanitize::_save_utc_value() 
  1061. 'text_datetime_timestamp_timezone',  
  1062. ),  
  1063. true 
  1064. ); 
  1065.  
  1066. return $args; 
  1067.  
  1068. /** 
  1069. * Returns a cloned version of this field object with, but with 
  1070. * modified/overridden field arguments. 
  1071. * @since 2.2.2 
  1072. * @param array $field_args Array of field arguments, or entire array of 
  1073. * arguments for CMB2_Field 
  1074. * @return CMB2_Field The new CMB2_Field instance. 
  1075. */ 
  1076. public function get_field_clone( $field_args ) { 
  1077. $args = array( 
  1078. 'field_args' => array(),  
  1079. 'group_field' => $this->group,  
  1080. 'object_id' => $this->object_id,  
  1081. 'object_type' => $this->object_type,  
  1082. 'cmb_id' => $this->cmb_id,  
  1083. ); 
  1084.  
  1085. if ( isset( $field_args['field_args'] ) ) { 
  1086. $args = wp_parse_args( $field_args, $args ); 
  1087. } else { 
  1088. $args['field_args'] = wp_parse_args( $field_args, $this->args ); 
  1089.  
  1090. return new CMB2_Field( $args ); 
  1091.  
  1092. /** 
  1093. * Returns the CMB2 instance this field is registered to. 
  1094. * @since 2.2.2 
  1095. * @return CMB2|WP_Error If new CMB2_Field is called without cmb_id arg, returns error. 
  1096. */ 
  1097. public function get_cmb() { 
  1098. if ( ! $this->cmb_id ) { 
  1099. return new WP_Error( 'no_cmb_id', __( 'Sorry, this field does not have a cmb_id specified.', 'cmb2' ) ); 
  1100.  
  1101. return cmb2_get_metabox( $this->cmb_id, $this->object_id, $this->object_type ); 
  1102.