CMB2_Types

CMB field type objects.

Defined (1)

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

/includes/CMB2_Types.php  
  1. class CMB2_Types { 
  2.  
  3. /** 
  4. * An iterator value for repeatable fields 
  5. * @var integer 
  6. * @since 1.0.0 
  7. */ 
  8. public $iterator = 0; 
  9.  
  10. /** 
  11. * Current CMB2_Field field object 
  12. * @var CMB2_Field object 
  13. * @since 1.0.0 
  14. */ 
  15. public $field; 
  16.  
  17. /** 
  18. * Current CMB2_Type_Base object 
  19. * @var CMB2_Type_Base object 
  20. * @since 2.2.2 
  21. */ 
  22. public $type; 
  23.  
  24. public function __construct( CMB2_Field $field ) { 
  25. $this->field = $field; 
  26.  
  27. /** 
  28. * Default fallback. Allows rendering fields via "cmb2_render_$fieldtype" hook 
  29. * @since 1.0.0 
  30. * @param string $fieldtype Non-existent field type name 
  31. * @param array $arguments All arguments passed to the method 
  32. */ 
  33. public function __call( $fieldtype, $arguments ) { 
  34. $proxied = array( 
  35. 'get_object_terms' => array(),  
  36. 'is_valid_img_ext' => false,  
  37. 'parse_args' => array(),  
  38. 'concat_items' => '',  
  39. 'select_option' => '',  
  40. 'list_input' => '',  
  41. 'list_input_checkbox' => '',  
  42. 'img_status_output' => '',  
  43. 'file_status_output' => '',  
  44. 'parse_picker_options' => array(),  
  45. ); 
  46. if ( isset( $proxied[ $fieldtype ] ) ) { 
  47. // Proxies the method call to the CMB2_Type_Base object 
  48. return $this->proxy_method( $fieldtype, $proxied[ $fieldtype ], $arguments ); 
  49.  
  50. /** 
  51. * Pass non-existent field types through an action 
  52. * The dynamic portion of the hook name, $fieldtype, refers to the field type. 
  53. * @param array $field The passed in `CMB2_Field` object 
  54. * @param mixed $escaped_value The value of this field escaped. 
  55. * It defaults to `sanitize_text_field`. 
  56. * If you need the unescaped value, you can access it 
  57. * via `$field->value()` 
  58. * @param int $object_id The ID of the current object 
  59. * @param string $object_type The type of object you are working with. 
  60. * Most commonly, `post` (this applies to all post-types),  
  61. * but could also be `comment`, `user` or `options-page`. 
  62. * @param object $field_type_object This `CMB2_Types` object 
  63. */ 
  64. do_action( "cmb2_render_{$fieldtype}", $this->field, $this->field->escaped_value(), $this->field->object_id, $this->field->object_type, $this ); 
  65.  
  66. /** 
  67. * Render a field (and handle repeatable) 
  68. * @since 1.1.0 
  69. */ 
  70. public function render() { 
  71. if ( $this->field->args( 'repeatable' ) ) { 
  72. $this->render_repeatable_field(); 
  73. } else { 
  74. $this->_render(); 
  75.  
  76. /** 
  77. * Render a field type 
  78. * @since 1.1.0 
  79. */ 
  80. protected function _render() { 
  81. $this->field->peform_param_callback( 'before_field' ); 
  82. echo $this->{$this->field->type()}(); 
  83. $this->field->peform_param_callback( 'after_field' ); 
  84.  
  85. /** 
  86. * Proxies the method call to the CMB2_Type_Base object, if it exists, otherwise returns a default fallback value. 
  87. * @since 2.2.2 
  88. * @param string $method Method to call on the CMB2_Type_Base object. 
  89. * @param mixed $default Default fallback value if method is not found. 
  90. * @return mixed Results from called method. 
  91. */ 
  92. protected function proxy_method( $method, $default, $args = array() ) { 
  93. if ( ! is_object( $this->type ) ) { 
  94. $this->guess_type_object( $method ); 
  95.  
  96. if ( is_object( $this->type ) && method_exists( $this->type, $method ) ) { 
  97.  
  98. return empty( $args ) 
  99. ? $this->type->$method() 
  100. : call_user_func_array( array( $this->type, $method ), $args ); 
  101.  
  102. return $default; 
  103.  
  104. /** 
  105. * If no CMB2_Types::$type object is initiated when a proxy method is called, it means 
  106. * it's a custom field type (which SHOULD be instantiating a Type), but let's try and 
  107. * guess the type object for them, instantiate it, and throw a _doing_it_wrong notice. 
  108. * @since 2.2.3 
  109. * @param string $method Method attempting to be called on the CMB2_Type_Base object. 
  110. */ 
  111. protected function guess_type_object( $method ) { 
  112. // Try to "guess" the Type object based on the method requested. 
  113. switch ( $method ) { 
  114. case 'select_option': 
  115. case 'list_input': 
  116. case 'list_input_checkbox': 
  117. case 'concat_items': 
  118. $this->type = new CMB2_Type_Select( $this ); 
  119. break; 
  120. case 'is_valid_img_ext': 
  121. case 'img_status_output': 
  122. case 'file_status_output': 
  123. $this->type = new CMB2_Type_File_Base( $this ); 
  124. break; 
  125. case 'parse_picker_options': 
  126. $this->type = new CMB2_Type_Text_Date( $this ); 
  127. break; 
  128. case 'get_object_terms': 
  129. case 'get_terms': 
  130. $this->type = new CMB2_Type_Taxonomy_Multicheck( $this ); 
  131. break; 
  132. case 'date_args': 
  133. case 'time_args': 
  134. $this->type = new CMB2_Type_Text_Datetime_Timestamp( $this ); 
  135. break; 
  136. case 'parse_args': 
  137. $this->type = new CMB2_Type_Text( $this ); 
  138. break; 
  139.  
  140. // Then, let's throw a debug _doing_it_wrong notice. 
  141.  
  142. $message = array( sprintf( esc_html__( 'Custom field types require a Type object instantiation to use this method. This method was called by the \'%s\' field type.' ), $this->field->type() ) ); 
  143.  
  144. $message[] = is_object( $this->type ) 
  145. ? esc_html__( 'That field type may not work as expected.', 'cmb2' ) 
  146. : esc_html__( 'That field type will not work as expected.', 'cmb2' ); 
  147.  
  148. $message[] = esc_html__( 'For more information about this change see: https://github.com/mustardBees/cmb-field-select2/pull/34w', 'cmb2' ); 
  149.  
  150. _doing_it_wrong( __CLASS__ . '::' . $method, implode( ' ', $message ), '2.2.2' ); 
  151.  
  152. /** 
  153. * Retrieve text parameter from field's options array (if it has one), or use fallback text 
  154. * @since 2.0.0 
  155. * @param string $text_key Key in field's options array 
  156. * @param string $fallback Fallback text 
  157. * @return string Text 
  158. */ 
  159. public function _text( $text_key, $fallback = '' ) { 
  160. return $this->field->get_string( $text_key, $fallback ); 
  161.  
  162. /** 
  163. * Determine a file's extension 
  164. * @since 1.0.0 
  165. * @param string $file File url 
  166. * @return string|false File extension or false 
  167. */ 
  168. public function get_file_ext( $file ) { 
  169. return CMB2_Utils::get_file_ext( $file ); 
  170.  
  171. /** 
  172. * Get the file name from a url 
  173. * @since 2.0.0 
  174. * @param string $value File url or path 
  175. * @return string File name 
  176. */ 
  177. public function get_file_name_from_path( $value ) { 
  178. return CMB2_Utils::get_file_name_from_path( $value ); 
  179.  
  180. /** 
  181. * Combines attributes into a string for a form element 
  182. * @since 1.1.0 
  183. * @param array $attrs Attributes to concatenate 
  184. * @param array $attr_exclude Attributes that should NOT be concatenated 
  185. * @return string String of attributes for form element 
  186. */ 
  187. public function concat_attrs( $attrs, $attr_exclude = array() ) { 
  188. return CMB2_Utils::concat_attrs( $attrs, $attr_exclude ); 
  189.  
  190. /** 
  191. * Generates repeatable field table markup 
  192. * @since 1.0.0 
  193. */ 
  194. public function render_repeatable_field() { 
  195. $table_id = $this->field->id() . '_repeat'; 
  196.  
  197. $this->_desc( true, true, true ); 
  198. ?> 
  199.  
  200. <div id="<?php echo $table_id; ?>" class="cmb-repeat-table cmb-nested"> 
  201. <div class="cmb-tbody cmb-field-list"> 
  202. <?php $this->repeatable_rows(); ?> 
  203. </div> 
  204. </div> 
  205. <p class="cmb-add-row"> 
  206. <button type="button" data-selector="<?php echo $table_id; ?>" class="cmb-add-row-button button"><?php echo esc_html( $this->_text( 'add_row_text', esc_html__( 'Add Row', 'cmb2' ) ) ); ?></button> 
  207. </p> 
  208.  
  209. <?php 
  210. // reset iterator 
  211. $this->iterator = 0; 
  212.  
  213. /** 
  214. * Generates repeatable field rows 
  215. * @since 1.1.0 
  216. */ 
  217. public function repeatable_rows() { 
  218. $meta_value = array_filter( (array) $this->field->escaped_value() ); 
  219. // check for default content 
  220. $default = $this->field->get_default(); 
  221.  
  222. // check for saved data 
  223. if ( ! empty( $meta_value ) ) { 
  224. $meta_value = is_array( $meta_value ) ? array_filter( $meta_value ) : $meta_value; 
  225. $meta_value = ! empty( $meta_value ) ? $meta_value : $default; 
  226. } else { 
  227. $meta_value = $default; 
  228.  
  229. // Loop value array and add a row 
  230. if ( ! empty( $meta_value ) ) { 
  231. $count = count( $meta_value ); 
  232. foreach ( (array) $meta_value as $val ) { 
  233. $this->field->escaped_value = $val; 
  234. $this->repeat_row( $count < 2 ); 
  235. $this->iterator++; 
  236. } else { 
  237.  
  238. // If value is empty (including empty array), then clear the value. 
  239. $this->field->escaped_value = $this->field->value = null; 
  240.  
  241. // Otherwise add one row 
  242. $this->repeat_row( true ); 
  243.  
  244. // Then add an empty row 
  245. $this->field->escaped_value = ''; 
  246. $this->iterator = $this->iterator ? $this->iterator : 1; 
  247. $this->repeat_row( false, 'empty-row hidden' ); 
  248.  
  249. /** 
  250. * Generates a repeatable row's markup 
  251. * @since 1.1.0 
  252. * @param bool $disable_remover Whether remove button should be disabled 
  253. * @param string $class Repeatable table row's class 
  254. */ 
  255. protected function repeat_row( $disable_remover = false, $class = 'cmb-repeat-row' ) { 
  256. $disabled = $disable_remover ? ' button-disabled' : ''; 
  257. ?> 
  258.  
  259. <div class="cmb-row <?php echo $class; ?>"> 
  260. <div class="cmb-td"> 
  261. <?php $this->_render(); ?> 
  262. </div> 
  263. <div class="cmb-td cmb-remove-row"> 
  264. <button type="button" class="button cmb-remove-row-button<?php echo $disabled; ?>"><?php echo esc_html( $this->_text( 'remove_row_text', esc_html__( 'Remove', 'cmb2' ) ) ); ?></button> 
  265. </div> 
  266. </div> 
  267.  
  268. <?php 
  269.  
  270. /** 
  271. * Generates description markup 
  272. * @since 1.0.0 
  273. * @param boolean $paragraph Paragraph tag or span 
  274. * @param boolean $echo Whether to echo description or only return it 
  275. * @return string Field's description markup 
  276. */ 
  277. public function _desc( $paragraph = false, $echo = false, $repeat_group = false ) { 
  278. // Prevent description from printing multiple times for repeatable fields 
  279. if ( ! $repeat_group && ( $this->field->args( 'repeatable' ) || $this->iterator > 0 ) ) { 
  280. return ''; 
  281.  
  282. $desc = $this->field->args( 'description' ); 
  283.  
  284. if ( ! $desc ) { 
  285. return; 
  286.  
  287. $tag = $paragraph ? 'p' : 'span'; 
  288. $desc = sprintf( "\n" . '<%1$s class="cmb2-metabox-description">%2$s</%1$s>' . "\n", $tag, $desc ); 
  289.  
  290. if ( $echo ) { 
  291. echo $desc; 
  292.  
  293. return $desc; 
  294.  
  295. /** 
  296. * Generate field name attribute 
  297. * @since 1.1.0 
  298. * @param string $suffix For multi-part fields 
  299. * @return string Name attribute 
  300. */ 
  301. public function _name( $suffix = '' ) { 
  302. return $this->field->args( '_name' ) . ( $this->field->args( 'repeatable' ) ? '[' . $this->iterator . ']' : '' ) . $suffix; 
  303.  
  304. /** 
  305. * Generate field id attribute 
  306. * @since 1.1.0 
  307. * @param string $suffix For multi-part fields 
  308. * @return string Id attribute 
  309. */ 
  310. public function _id( $suffix = '' ) { 
  311. return $this->field->id() . $suffix . ( $this->field->args( 'repeatable' ) ? '_' . $this->iterator . '" data-iterator="' . $this->iterator : '' ); 
  312.  
  313. /** 
  314. * Handles outputting an 'input' element 
  315. * @since 1.1.0 
  316. * @param array $args Override arguments 
  317. * @param string $type Field type 
  318. * @return string Form input element 
  319. */ 
  320. public function input( $args = array(), $type = __FUNCTION__ ) { 
  321. $this->type = new CMB2_Type_Text( $this, $args, $type ); 
  322. return $this->type->render(); 
  323.  
  324. /** 
  325. * Handles outputting an 'textarea' element 
  326. * @since 1.1.0 
  327. * @param array $args Override arguments 
  328. * @return string Form textarea element 
  329. */ 
  330. public function textarea( $args = array() ) { 
  331. $this->type = new CMB2_Type_Textarea( $this, $args ); 
  332. return $this->type->render(); 
  333.  
  334. /** 
  335. * Begin Field Types 
  336. */ 
  337.  
  338. public function text() { 
  339. return $this->input(); 
  340.  
  341. public function hidden() { 
  342. $args = array( 
  343. 'type' => 'hidden',  
  344. 'desc' => '',  
  345. 'class' => 'cmb2-hidden',  
  346. ); 
  347. if ( $this->field->group ) { 
  348. $args['data-groupid'] = $this->field->group->id(); 
  349. $args['data-iterator'] = $this->iterator; 
  350. return $this->input( $args ); 
  351.  
  352. public function text_small() { 
  353. return $this->input( array( 
  354. 'class' => 'cmb2-text-small',  
  355. 'desc' => $this->_desc(),  
  356. ) ); 
  357.  
  358. public function text_medium() { 
  359. return $this->input( array( 
  360. 'class' => 'cmb2-text-medium',  
  361. 'desc' => $this->_desc(),  
  362. ) ); 
  363.  
  364. public function text_email() { 
  365. return $this->input( array( 
  366. 'class' => 'cmb2-text-email cmb2-text-medium',  
  367. 'type' => 'email',  
  368. ) ); 
  369.  
  370. public function text_url() { 
  371. return $this->input( array( 
  372. 'class' => 'cmb2-text-url cmb2-text-medium regular-text',  
  373. 'value' => $this->field->escaped_value( 'esc_url' ),  
  374. ) ); 
  375.  
  376. public function text_money() { 
  377. $input = $this->input( array( 
  378. 'class' => 'cmb2-text-money',  
  379. 'desc' => $this->_desc(),  
  380. ) ); 
  381. return ( ! $this->field->get_param_callback_result( 'before_field' ) ? '$ ' : ' ' ) . $input; 
  382.  
  383. public function textarea_small() { 
  384. return $this->textarea( array( 
  385. 'class' => 'cmb2-textarea-small',  
  386. 'rows' => 4,  
  387. ) ); 
  388.  
  389. public function textarea_code() { 
  390. $this->type = new CMB2_Type_Textarea_Code( $this ); 
  391. return $this->type->render(); 
  392.  
  393. public function wysiwyg( $args = array() ) { 
  394. $this->type = new CMB2_Type_Wysiwyg( $this, $args ); 
  395. return $this->type->render(); 
  396.  
  397. public function text_date( $args = array() ) { 
  398. $this->type = new CMB2_Type_Text_Date( $this, $args ); 
  399. return $this->type->render(); 
  400.  
  401. // Alias for text_date 
  402. public function text_date_timestamp( $args = array() ) { 
  403. return $this->text_date( $args ); 
  404.  
  405. public function text_time( $args = array() ) { 
  406. $this->type = new CMB2_Type_Text_Time( $this, $args ); 
  407. return $this->type->render(); 
  408.  
  409. public function text_datetime_timestamp( $args = array() ) { 
  410. $this->type = new CMB2_Type_Text_Datetime_Timestamp( $this, $args ); 
  411. return $this->type->render(); 
  412.  
  413. public function text_datetime_timestamp_timezone( $args = array() ) { 
  414. $this->type = new CMB2_Type_Text_Datetime_Timestamp_Timezone( $this, $args ); 
  415. return $this->type->render(); 
  416.  
  417. public function select_timezone() { 
  418. $this->type = new CMB2_Type_Select_Timezone( $this ); 
  419. return $this->type->render(); 
  420.  
  421. public function colorpicker( $args = array(), $meta_value = '' ) { 
  422. $this->type = new CMB2_Type_Colorpicker( $this, $args, $meta_value ); 
  423. return $this->type->render(); 
  424.  
  425. public function title( $args = array() ) { 
  426. $this->type = new CMB2_Type_Title( $this, $args ); 
  427. return $this->type->render(); 
  428.  
  429. public function select( $args = array() ) { 
  430. $this->type = new CMB2_Type_Select( $this, $args ); 
  431. return $this->type->render(); 
  432.  
  433. public function taxonomy_select() { 
  434. $this->type = new CMB2_Type_Taxonomy_Select( $this ); 
  435. return $this->type->render(); 
  436.  
  437. public function radio( $args = array(), $type = __FUNCTION__ ) { 
  438. $this->type = new CMB2_Type_Radio( $this, $args, $type ); 
  439. return $this->type->render(); 
  440.  
  441. public function radio_inline() { 
  442. return $this->radio( array(), __FUNCTION__ ); 
  443.  
  444. public function multicheck( $type = 'checkbox' ) { 
  445. $this->type = new CMB2_Type_Multicheck( $this, array(), $type ); 
  446. return $this->type->render(); 
  447.  
  448. public function multicheck_inline() { 
  449. return $this->multicheck( 'multicheck_inline' ); 
  450.  
  451. public function checkbox( $args = array(), $is_checked = null ) { 
  452. $this->type = new CMB2_Type_Checkbox( $this, $args, $is_checked ); 
  453. return $this->type->render(); 
  454.  
  455. public function taxonomy_radio() { 
  456. $this->type = new CMB2_Type_Taxonomy_Radio( $this ); 
  457. return $this->type->render(); 
  458.  
  459. public function taxonomy_radio_inline() { 
  460. return $this->taxonomy_radio(); 
  461.  
  462. public function taxonomy_multicheck() { 
  463. $this->type = new CMB2_Type_Taxonomy_Multicheck( $this ); 
  464. return $this->type->render(); 
  465.  
  466. public function taxonomy_multicheck_inline() { 
  467. return $this->taxonomy_multicheck(); 
  468.  
  469. public function oembed() { 
  470. $this->type = new CMB2_Type_Oembed( $this ); 
  471. return $this->type->render(); 
  472.  
  473. public function file_list() { 
  474. $this->type = new CMB2_Type_File_List( $this ); 
  475. return $this->type->render(); 
  476.  
  477. public function file() { 
  478. $this->type = new CMB2_Type_File( $this ); 
  479. return $this->type->render(); 
  480.