CMB2_Sanitize

CMB2 field sanitization.

Defined (2)

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

/includes/libraries/metabox/includes/CMB2_Sanitize.php  
  1. class CMB2_Sanitize { 
  2.  
  3. /** 
  4. * A CMB field object 
  5. * @var CMB2_Field object 
  6. */ 
  7. public $field; 
  8.  
  9. /** 
  10. * Field's value 
  11. * @var mixed 
  12. */ 
  13. public $value; 
  14.  
  15. /** 
  16. * Setup our class vars 
  17. * @since 1.1.0 
  18. * @param CMB2_Field $field A CMB2 field object 
  19. * @param mixed $value Field value 
  20. */ 
  21. public function __construct( CMB2_Field $field, $value ) { 
  22. $this->field = $field; 
  23. $this->value = stripslashes_deep( $value ); // get rid of those evil magic quotes 
  24.  
  25. /** 
  26. * Catchall method if field's 'sanitization_cb' is NOT defined, or field type does not have a corresponding validation method 
  27. * @since 1.0.0 
  28. * @param string $name Non-existent method name 
  29. * @param array $arguments All arguments passed to the method 
  30. */ 
  31. public function __call( $name, $arguments ) { 
  32. return $this->default_sanitization( $this->value ); 
  33.  
  34. /** 
  35. * Default fallback sanitization method. Applies filters. 
  36. * @since 1.0.2 
  37. */ 
  38. public function default_sanitization() { 
  39.  
  40. /** 
  41. * Filter the value before it is saved. 
  42. * The dynamic portion of the hook name, $this->field->type(), refers to the field type. 
  43. * Passing a non-null value to the filter will short-circuit saving 
  44. * the field value, saving the passed value instead. 
  45. * @param bool|mixed $override_value Sanitization/Validation override value to return. 
  46. * Default false to skip it. 
  47. * @param mixed $value The value to be saved to this field. 
  48. * @param int $object_id The ID of the object where the value will be saved 
  49. * @param array $field_args The current field's arguments 
  50. * @param object $sanitizer This `CMB2_Sanitize` object 
  51. */ 
  52. $override_value = apply_filters( "cmb2_sanitize_{$this->field->type()}", null, $this->value, $this->field->object_id, $this->field->args(), $this ); 
  53. /** 
  54. * This exists for back-compatibility, but validation 
  55. * is not what happens here. 
  56. * @deprecated See documentation above. 
  57. */ 
  58. $override_value = apply_filters( "cmb2_validate_{$this->field->type()}", $override_value, $this->value, $this->field->object_id, $this->field->args(), $this ); 
  59.  
  60. if ( null !== $override_value ) { 
  61. return $override_value; 
  62.  
  63. $sanitized_value = ''; 
  64. switch ( $this->field->type() ) { 
  65. case 'wysiwyg': 
  66. // $value = wp_kses( $this->value ); 
  67. // break; 
  68. case 'textarea_small': 
  69. $sanitized_value = $this->textarea( $this->value ); 
  70. break; 
  71. case 'taxonomy_select': 
  72. case 'taxonomy_radio': 
  73. case 'taxonomy_multicheck': 
  74. if ( $this->field->args( 'taxonomy' ) ) { 
  75. wp_set_object_terms( $this->field->object_id, $this->value, $this->field->args( 'taxonomy' ) ); 
  76. break; 
  77. case 'multicheck': 
  78. case 'file_list': 
  79. case 'oembed': 
  80. case 'group': 
  81. // no filtering 
  82. $sanitized_value = $this->value; 
  83. break; 
  84. default: 
  85. // Handle repeatable fields array 
  86. // We'll fallback to 'sanitize_text_field' 
  87. $sanitized_value = is_array( $this->value ) ? array_map( 'sanitize_text_field', $this->value ) : call_user_func( 'sanitize_text_field', $this->value ); 
  88. break; 
  89.  
  90. return $this->_is_empty_array( $sanitized_value ) ? '' : $sanitized_value; 
  91.  
  92. /** 
  93. * Simple checkbox validation 
  94. * @since 1.0.1 
  95. * @return string|false 'on' or false 
  96. */ 
  97. public function checkbox() { 
  98. return $this->value === 'on' ? 'on' : false; 
  99.  
  100. /** 
  101. * Validate url in a meta value 
  102. * @since 1.0.1 
  103. * @return string Empty string or escaped url 
  104. */ 
  105. public function text_url() { 
  106. $protocols = $this->field->args( 'protocols' ); 
  107. // for repeatable 
  108. if ( is_array( $this->value ) ) { 
  109. foreach ( $this->value as $key => $val ) { 
  110. $this->value[ $key ] = $val ? esc_url_raw( $val, $protocols ) : $this->field->args( 'default' ); 
  111. } else { 
  112. $this->value = $this->value ? esc_url_raw( $this->value, $protocols ) : $this->field->args( 'default' ); 
  113.  
  114. return $this->value; 
  115.  
  116. public function colorpicker() { 
  117. // for repeatable 
  118. if ( is_array( $this->value ) ) { 
  119. $check = $this->value; 
  120. $this->value = array(); 
  121. foreach ( $check as $key => $val ) { 
  122. if ( $val && '#' != $val ) { 
  123. $this->value[ $key ] = esc_attr( $val ); 
  124. } else { 
  125. $this->value = ! $this->value || '#' == $this->value ? '' : esc_attr( $this->value ); 
  126. return $this->value; 
  127.  
  128. /** 
  129. * Validate email in a meta value 
  130. * @since 1.0.1 
  131. * @return string Empty string or sanitized email 
  132. */ 
  133. public function text_email() { 
  134. // for repeatable 
  135. if ( is_array( $this->value ) ) { 
  136. foreach ( $this->value as $key => $val ) { 
  137. $val = trim( $val ); 
  138. $this->value[ $key ] = is_email( $val ) ? $val : ''; 
  139. } else { 
  140. $this->value = trim( $this->value ); 
  141. $this->value = is_email( $this->value ) ? $this->value : ''; 
  142.  
  143. return $this->value; 
  144.  
  145. /** 
  146. * Validate money in a meta value 
  147. * @since 1.0.1 
  148. * @return string Empty string or sanitized money value 
  149. */ 
  150. public function text_money() { 
  151.  
  152. global $wp_locale; 
  153.  
  154. $search = array( $wp_locale->number_format['thousands_sep'], $wp_locale->number_format['decimal_point'] ); 
  155. $replace = array( '', '.' ); 
  156.  
  157. // for repeatable 
  158. if ( is_array( $this->value ) ) { 
  159. foreach ( $this->value as $key => $val ) { 
  160. $this->value[ $key ] = number_format_i18n( (float) str_ireplace( $search, $replace, $val ), 2 ); 
  161. } else { 
  162. $this->value = number_format_i18n( (float) str_ireplace( $search, $replace, $this->value ), 2 ); 
  163.  
  164. return $this->value; 
  165.  
  166. /** 
  167. * Converts text date to timestamp 
  168. * @since 1.0.2 
  169. * @return string Timestring 
  170. */ 
  171. public function text_date_timestamp() { 
  172. return is_array( $this->value ) ? array_map( 'strtotime', $this->value ) : strtotime( $this->value ); 
  173.  
  174. /** 
  175. * Datetime to timestamp 
  176. * @since 1.0.1 
  177. * @return string Timestring 
  178. */ 
  179. public function text_datetime_timestamp( $repeat = false ) { 
  180.  
  181. $test = is_array( $this->value ) ? array_filter( $this->value ) : ''; 
  182. if ( empty( $test ) ) { 
  183. return ''; 
  184.  
  185. if ( $repeat_value = $this->_check_repeat( __FUNCTION__, $repeat ) ) { 
  186. return $repeat_value; 
  187.  
  188. $this->value = strtotime( $this->value['date'] . ' ' . $this->value['time'] ); 
  189.  
  190. if ( $tz_offset = $this->field->field_timezone_offset() ) { 
  191. $this->value += $tz_offset; 
  192.  
  193. return $this->value; 
  194.  
  195. /** 
  196. * Datetime to imestamp with timezone 
  197. * @since 1.0.1 
  198. * @return string Timestring 
  199. */ 
  200. public function text_datetime_timestamp_timezone( $repeat = false ) { 
  201.  
  202. $test = is_array( $this->value ) ? array_filter( $this->value ) : ''; 
  203. if ( empty( $test ) ) { 
  204. return ''; 
  205.  
  206. if ( $repeat_value = $this->_check_repeat( __FUNCTION__, $repeat ) ) { 
  207. return $repeat_value; 
  208.  
  209. $tzstring = null; 
  210.  
  211. if ( is_array( $this->value ) && array_key_exists( 'timezone', $this->value ) ) { 
  212. $tzstring = $this->value['timezone']; 
  213.  
  214. if ( empty( $tzstring ) ) { 
  215. $tzstring = cmb2_utils()->timezone_string(); 
  216.  
  217. $offset = cmb2_utils()->timezone_offset( $tzstring ); 
  218.  
  219. if ( 'UTC' === substr( $tzstring, 0, 3 ) ) { 
  220. $tzstring = timezone_name_from_abbr( '', $offset, 0 ); 
  221.  
  222. $this->value = new DateTime( $this->value['date'] . ' ' . $this->value['time'], new DateTimeZone( $tzstring ) ); 
  223. $this->value = serialize( $this->value ); 
  224.  
  225. return $this->value; 
  226.  
  227. /** 
  228. * Sanitize textareas and wysiwyg fields 
  229. * @since 1.0.1 
  230. * @return string Sanitized data 
  231. */ 
  232. public function textarea() { 
  233. return is_array( $this->value ) ? array_map( 'wp_kses_post', $this->value ) : wp_kses_post( $this->value ); 
  234.  
  235. /** 
  236. * Sanitize code textareas 
  237. * @since 1.0.2 
  238. * @return string Sanitized data 
  239. */ 
  240. public function textarea_code( $repeat = false ) { 
  241. if ( $repeat_value = $this->_check_repeat( __FUNCTION__, $repeat ) ) { 
  242. return $repeat_value; 
  243.  
  244. return htmlspecialchars_decode( stripslashes( $this->value ) ); 
  245.  
  246. /** 
  247. * Peforms saving of `file` attachement's ID 
  248. * @since 1.1.0 
  249. */ 
  250. public function _save_file_id() { 
  251. $group = $this->field->group; 
  252. $args = $this->field->args(); 
  253. $args['id'] = $args['_id'] . '_id'; 
  254.  
  255. unset( $args['_id'], $args['_name'] ); 
  256. // And get new field object 
  257. $field = new CMB2_Field( array( 
  258. 'field_args' => $args,  
  259. 'group_field' => $group,  
  260. 'object_id' => $this->field->object_id,  
  261. 'object_type' => $this->field->object_type,  
  262. ) ); 
  263. $id_key = $field->_id(); 
  264. $id_val_old = $field->escaped_value( 'absint' ); 
  265.  
  266. if ( $group ) { 
  267. // Check group $_POST data 
  268. $i = $group->index; 
  269. $base_id = $group->_id(); 
  270. $id_val = isset( $_POST[ $base_id ][ $i ][ $id_key ] ) ? absint( $_POST[ $base_id ][ $i ][ $id_key ] ) : 0; 
  271.  
  272. } else { 
  273. // Check standard $_POST data 
  274. $id_val = isset( $_POST[ $field->id() ] ) ? $_POST[ $field->id() ] : null; 
  275.  
  276.  
  277. // If there is no ID saved yet, try to get it from the url 
  278. if ( $this->value && ! $id_val ) { 
  279. $id_val = cmb2_utils()->image_id_from_url( $this->value ); 
  280.  
  281. if ( $group ) { 
  282. return array( 
  283. 'attach_id' => $id_val,  
  284. 'field_id' => $id_key,  
  285. ); 
  286.  
  287. if ( $id_val && $id_val != $id_val_old ) { 
  288. return $field->update_data( $id_val ); 
  289. } elseif ( empty( $id_val ) && $id_val_old ) { 
  290. return $field->remove_data( $id_val_old ); 
  291.  
  292. /** 
  293. * Handles saving of attachment post ID and sanitizing file url 
  294. * @since 1.1.0 
  295. * @return string Sanitized url 
  296. */ 
  297. public function file() { 
  298. $id_value = $this->_save_file_id( $this->value ); 
  299. $clean = $this->text_url( $this->value ); 
  300.  
  301. // Return an array with url/id if saving a group field 
  302. return $this->field->group ? array_merge( array( 'url' => $clean ), $id_value ) : $clean; 
  303.  
  304. /** 
  305. * If repeating, loop through and re-apply sanitization method 
  306. * @since 1.1.0 
  307. * @param string $method Class method 
  308. * @param bool $repeat Whether repeating or not 
  309. * @return mixed Sanitized value 
  310. */ 
  311. public function _check_repeat( $method, $repeat ) { 
  312. if ( $repeat || ! $this->field->args( 'repeatable' ) ) { 
  313. return; 
  314. $new_value = array(); 
  315. foreach ( $this->value as $iterator => $val ) { 
  316. $new_value[] = $this->$method( $val, true ); 
  317. return $new_value; 
  318.  
  319. /** 
  320. * Determine if passed value is an empty array 
  321. * @since 2.0.6 
  322. * @param mixed $to_check Value to check 
  323. * @return boolean Whether value is an array that's empty 
  324. */ 
  325. public function _is_empty_array( $to_check ) { 
  326. if ( is_array( $to_check ) ) { 
  327. $cleaned_up = array_filter( $to_check ); 
  328. return empty( $cleaned_up ); 
  329. return false; 
  330.  
/vendor/wordimpress/maps-builder-core/includes/libraries/metabox/includes/CMB2_Sanitize.php  
  1. class CMB2_Sanitize { 
  2.  
  3. /** 
  4. * A CMB field object 
  5. * @var CMB2_Field object 
  6. */ 
  7. public $field; 
  8.  
  9. /** 
  10. * Field's value 
  11. * @var mixed 
  12. */ 
  13. public $value; 
  14.  
  15. /** 
  16. * Setup our class vars 
  17. * @since 1.1.0 
  18. * @param CMB2_Field $field A CMB2 field object 
  19. * @param mixed $value Field value 
  20. */ 
  21. public function __construct( CMB2_Field $field, $value ) { 
  22. $this->field = $field; 
  23. $this->value = stripslashes_deep( $value ); // get rid of those evil magic quotes 
  24.  
  25. /** 
  26. * Catchall method if field's 'sanitization_cb' is NOT defined, or field type does not have a corresponding validation method 
  27. * @since 1.0.0 
  28. * @param string $name Non-existent method name 
  29. * @param array $arguments All arguments passed to the method 
  30. */ 
  31. public function __call( $name, $arguments ) { 
  32. return $this->default_sanitization(); 
  33.  
  34. /** 
  35. * Default fallback sanitization method. Applies filters. 
  36. * @since 1.0.2 
  37. */ 
  38. public function default_sanitization() { 
  39.  
  40. /** 
  41. * This exists for back-compatibility, but validation 
  42. * is not what happens here. 
  43. * @deprecated See documentation for "cmb2_sanitize_{$this->type()}". 
  44. */ 
  45. $override_value = apply_filters( "cmb2_validate_{$this->field->type()}", null, $this->value, $this->field->object_id, $this->field->args(), $this ); 
  46.  
  47. if ( null !== $override_value ) { 
  48. return $override_value; 
  49.  
  50. $sanitized_value = ''; 
  51. switch ( $this->field->type() ) { 
  52. case 'wysiwyg': 
  53. case 'textarea_small': 
  54. case 'oembed': 
  55. $sanitized_value = $this->textarea(); 
  56. break; 
  57. case 'taxonomy_select': 
  58. case 'taxonomy_radio': 
  59. case 'taxonomy_radio_inline': 
  60. case 'taxonomy_multicheck': 
  61. case 'taxonomy_multicheck_inline': 
  62. if ( $this->field->args( 'taxonomy' ) ) { 
  63. wp_set_object_terms( $this->field->object_id, $this->value, $this->field->args( 'taxonomy' ) ); 
  64. } else { 
  65. cmb2_utils()->log_if_debug( __METHOD__, __LINE__, "{$this->field->type()} {$this->field->_id()} is missing the 'taxonomy' parameter." ); 
  66. break; 
  67. case 'multicheck': 
  68. case 'multicheck_inline': 
  69. case 'file_list': 
  70. case 'group': 
  71. // no filtering 
  72. $sanitized_value = $this->value; 
  73. break; 
  74. default: 
  75. // Handle repeatable fields array 
  76. // We'll fallback to 'sanitize_text_field' 
  77. $sanitized_value = is_array( $this->value ) ? array_map( 'sanitize_text_field', $this->value ) : sanitize_text_field( $this->value ); 
  78. break; 
  79.  
  80. return $this->_is_empty_array( $sanitized_value ) ? '' : $sanitized_value; 
  81.  
  82. /** 
  83. * Simple checkbox validation 
  84. * @since 1.0.1 
  85. * @return string|false 'on' or false 
  86. */ 
  87. public function checkbox() { 
  88. return $this->value === 'on' ? 'on' : false; 
  89.  
  90. /** 
  91. * Validate url in a meta value 
  92. * @since 1.0.1 
  93. * @return string Empty string or escaped url 
  94. */ 
  95. public function text_url() { 
  96. $protocols = $this->field->args( 'protocols' ); 
  97. // for repeatable 
  98. if ( is_array( $this->value ) ) { 
  99. foreach ( $this->value as $key => $val ) { 
  100. $this->value[ $key ] = $val ? esc_url_raw( $val, $protocols ) : $this->field->get_default(); 
  101. } else { 
  102. $this->value = $this->value ? esc_url_raw( $this->value, $protocols ) : $this->field->get_default(); 
  103.  
  104. return $this->value; 
  105.  
  106. public function colorpicker() { 
  107. // for repeatable 
  108. if ( is_array( $this->value ) ) { 
  109. $check = $this->value; 
  110. $this->value = array(); 
  111. foreach ( $check as $key => $val ) { 
  112. if ( $val && '#' != $val ) { 
  113. $this->value[ $key ] = esc_attr( $val ); 
  114. } else { 
  115. $this->value = ! $this->value || '#' == $this->value ? '' : esc_attr( $this->value ); 
  116. return $this->value; 
  117.  
  118. /** 
  119. * Validate email in a meta value 
  120. * @since 1.0.1 
  121. * @return string Empty string or sanitized email 
  122. */ 
  123. public function text_email() { 
  124. // for repeatable 
  125. if ( is_array( $this->value ) ) { 
  126. foreach ( $this->value as $key => $val ) { 
  127. $val = trim( $val ); 
  128. $this->value[ $key ] = is_email( $val ) ? $val : ''; 
  129. } else { 
  130. $this->value = trim( $this->value ); 
  131. $this->value = is_email( $this->value ) ? $this->value : ''; 
  132.  
  133. return $this->value; 
  134.  
  135. /** 
  136. * Validate money in a meta value 
  137. * @since 1.0.1 
  138. * @return string Empty string or sanitized money value 
  139. */ 
  140. public function text_money() { 
  141. if ( ! $this->value ) { 
  142. return ''; 
  143.  
  144. global $wp_locale; 
  145.  
  146. $search = array( $wp_locale->number_format['thousands_sep'], $wp_locale->number_format['decimal_point'] ); 
  147. $replace = array( '', '.' ); 
  148.  
  149. // for repeatable 
  150. if ( is_array( $this->value ) ) { 
  151. foreach ( $this->value as $key => $val ) { 
  152. if ( $val ) { 
  153. $this->value[ $key ] = number_format_i18n( (float) str_ireplace( $search, $replace, $val ), 2 ); 
  154. } else { 
  155. $this->value = number_format_i18n( (float) str_ireplace( $search, $replace, $this->value ), 2 ); 
  156.  
  157. return $this->value; 
  158.  
  159. /** 
  160. * Converts text date to timestamp 
  161. * @since 1.0.2 
  162. * @return string Timestring 
  163. */ 
  164. public function text_date_timestamp() { 
  165. return is_array( $this->value ) 
  166. ? array_map( array( $this->field, 'get_timestamp_from_value' ), $this->value ) 
  167. : $this->field->get_timestamp_from_value( $this->value ); 
  168.  
  169. /** 
  170. * Datetime to timestamp 
  171. * @since 1.0.1 
  172. * @return string Timestring 
  173. */ 
  174. public function text_datetime_timestamp( $repeat = false ) { 
  175.  
  176. $test = is_array( $this->value ) ? array_filter( $this->value ) : ''; 
  177. if ( empty( $test ) ) { 
  178. return ''; 
  179.  
  180. $repeat_value = $this->_check_repeat( __FUNCTION__, $repeat ); 
  181. if ( false !== $repeat_value ) { 
  182. return $repeat_value; 
  183.  
  184. if ( isset( $this->value['date'], $this->value['time'] ) ) { 
  185. $this->value = $this->field->get_timestamp_from_value( $this->value['date'] . ' ' . $this->value['time'] ); 
  186.  
  187. if ( $tz_offset = $this->field->field_timezone_offset() ) { 
  188. $this->value += (int) $tz_offset; 
  189.  
  190. return $this->value; 
  191.  
  192. /** 
  193. * Datetime to timestamp with timezone 
  194. * @since 1.0.1 
  195. * @return string Timestring 
  196. */ 
  197. public function text_datetime_timestamp_timezone( $repeat = false ) { 
  198. static $utc_values = array(); 
  199.  
  200. $test = is_array( $this->value ) ? array_filter( $this->value ) : ''; 
  201. if ( empty( $test ) ) { 
  202. return ''; 
  203.  
  204. $utc_key = $this->field->_id() . '_utc'; 
  205.  
  206. $repeat_value = $this->_check_repeat( __FUNCTION__, $repeat ); 
  207. if ( false !== $repeat_value ) { 
  208. if ( ! empty( $utc_values[ $utc_key ] ) ) { 
  209. $this->_save_utc_value( $utc_key, $utc_values[ $utc_key ] ); 
  210. unset( $utc_values[ $utc_key ] ); 
  211.  
  212. return $repeat_value; 
  213.  
  214. $tzstring = null; 
  215.  
  216. if ( is_array( $this->value ) && array_key_exists( 'timezone', $this->value ) ) { 
  217. $tzstring = $this->value['timezone']; 
  218.  
  219. if ( empty( $tzstring ) ) { 
  220. $tzstring = cmb2_utils()->timezone_string(); 
  221.  
  222. $offset = cmb2_utils()->timezone_offset( $tzstring ); 
  223.  
  224. if ( 'UTC' === substr( $tzstring, 0, 3 ) ) { 
  225. $tzstring = timezone_name_from_abbr( '', $offset, 0 ); 
  226. /** 
  227. * timezone_name_from_abbr() returns false if not found based on offset. 
  228. * Since there are currently some invalid timezones in wp_timezone_dropdown(),  
  229. * fallback to an offset of 0 (UTC+0) 
  230. * https://core.trac.wordpress.org/ticket/29205 
  231. */ 
  232. $tzstring = false !== $tzstring ? $tzstring : timezone_name_from_abbr( '', 0, 0 ); 
  233.  
  234. $full_format = $this->field->args['date_format'] . ' ' . $this->field->args['time_format']; 
  235. $full_date = $this->value['date'] . ' ' . $this->value['time']; 
  236.  
  237. try { 
  238.  
  239. $datetime = date_create_from_format( $full_format, $full_date ); 
  240.  
  241. if ( ! is_object( $datetime ) ) { 
  242. $this->value = $utc_stamp = ''; 
  243. } else { 
  244. $timestamp = $datetime->setTimezone( new DateTimeZone( $tzstring ) )->getTimestamp(); 
  245. $utc_stamp = $timestamp - $offset; 
  246. $this->value = serialize( $datetime ); 
  247.  
  248. if ( $this->field->group ) { 
  249. $this->value = array( 
  250. 'supporting_field_value' => $utc_stamp,  
  251. 'supporting_field_id' => $utc_key,  
  252. 'value' => $this->value,  
  253. ); 
  254. } else { 
  255. // Save the utc timestamp supporting field 
  256. if ( $repeat ) { 
  257. $utc_values[ $utc_key ][] = $utc_stamp; 
  258. } else { 
  259. $this->_save_utc_value( $utc_key, $utc_stamp ); 
  260.  
  261. } catch ( Exception $e ) { 
  262. $this->value = ''; 
  263. cmb2_utils()->log_if_debug( __METHOD__, __LINE__, $e->getMessage() ); 
  264.  
  265. return $this->value; 
  266.  
  267. /** 
  268. * Sanitize textareas and wysiwyg fields 
  269. * @since 1.0.1 
  270. * @return string Sanitized data 
  271. */ 
  272. public function textarea() { 
  273. return is_array( $this->value ) ? array_map( 'wp_kses_post', $this->value ) : wp_kses_post( $this->value ); 
  274.  
  275. /** 
  276. * Sanitize code textareas 
  277. * @since 1.0.2 
  278. * @return string Sanitized data 
  279. */ 
  280. public function textarea_code( $repeat = false ) { 
  281. $repeat_value = $this->_check_repeat( __FUNCTION__, $repeat ); 
  282. if ( false !== $repeat_value ) { 
  283. return $repeat_value; 
  284.  
  285. return htmlspecialchars_decode( stripslashes( $this->value ) ); 
  286.  
  287. /** 
  288. * Handles saving of attachment post ID and sanitizing file url 
  289. * @since 1.1.0 
  290. * @return string Sanitized url 
  291. */ 
  292. public function file() { 
  293. $file_id_key = $this->field->_id() . '_id'; 
  294.  
  295. if ( $this->field->group ) { 
  296. // Return an array with url/id if saving a group field 
  297. $this->value = $this->_get_group_file_value_array( $file_id_key ); 
  298. } else { 
  299. $this->_save_file_id_value( $file_id_key ); 
  300. $this->text_url(); 
  301.  
  302. return $this->value; 
  303.  
  304. /** 
  305. * Gets the values for the `file` field type from the data being saved. 
  306. * @since 2.2.0 
  307. */ 
  308. public function _get_group_file_value_array( $id_key ) { 
  309. $alldata = $this->field->group->data_to_save; 
  310. $base_id = $this->field->group->_id(); 
  311. $i = $this->field->group->index; 
  312.  
  313. // Check group $alldata data 
  314. $id_val = isset( $alldata[ $base_id ][ $i ][ $id_key ] ) 
  315. ? absint( $alldata[ $base_id ][ $i ][ $id_key ] ) 
  316. : 0; 
  317.  
  318. return array( 
  319. 'value' => $this->text_url(),  
  320. 'supporting_field_value' => $id_val,  
  321. 'supporting_field_id' => $id_key,  
  322. ); 
  323.  
  324. /** 
  325. * Peforms saving of `file` attachement's ID 
  326. * @since 1.1.0 
  327. */ 
  328. public function _save_file_id_value( $file_id_key ) { 
  329. $id_field = $this->_new_supporting_field( $file_id_key ); 
  330.  
  331. // Check standard data_to_save data 
  332. $id_val = isset( $this->field->data_to_save[ $file_id_key ] ) 
  333. ? $this->field->data_to_save[ $file_id_key ] 
  334. : null; 
  335.  
  336. // If there is no ID saved yet, try to get it from the url 
  337. if ( $this->value && ! $id_val ) { 
  338. $id_val = cmb2_utils()->image_id_from_url( $this->value ); 
  339.  
  340. return $id_field->save_field( $id_val ); 
  341.  
  342. /** 
  343. * Peforms saving of `text_datetime_timestamp_timezone` utc timestamp 
  344. * @since 2.2.0 
  345. */ 
  346. public function _save_utc_value( $utc_key, $utc_stamp ) { 
  347. return $this->_new_supporting_field( $utc_key )->save_field( $utc_stamp ); 
  348.  
  349. /** 
  350. * Returns a new, supporting, CMB2_Field object based on a new field id. 
  351. * @since 2.2.0 
  352. */ 
  353. public function _new_supporting_field( $new_field_id ) { 
  354. return $this->field->get_field_clone( array( 
  355. 'id' => $new_field_id,  
  356. 'sanitization_cb' => false,  
  357. ) ); 
  358.  
  359. /** 
  360. * If repeating, loop through and re-apply sanitization method 
  361. * @since 1.1.0 
  362. * @param string $method Class method 
  363. * @param bool $repeat Whether repeating or not 
  364. * @return mixed Sanitized value 
  365. */ 
  366. public function _check_repeat( $method, $repeat ) { 
  367. if ( $repeat || ! $this->field->args( 'repeatable' ) ) { 
  368. return false; 
  369.  
  370. $values_array = $this->value; 
  371.  
  372. $new_value = array(); 
  373. foreach ( $values_array as $iterator => $this->value ) { 
  374. if ( $this->value ) { 
  375. $val = $this->$method( true ); 
  376. if ( ! empty( $val ) ) { 
  377. $new_value[] = $val; 
  378.  
  379. $this->value = $new_value; 
  380.  
  381. return empty( $this->value ) ? null : $this->value; 
  382.  
  383. /** 
  384. * Determine if passed value is an empty array 
  385. * @since 2.0.6 
  386. * @param mixed $to_check Value to check 
  387. * @return boolean Whether value is an array that's empty 
  388. */ 
  389. public function _is_empty_array( $to_check ) { 
  390. if ( is_array( $to_check ) ) { 
  391. $cleaned_up = array_filter( $to_check ); 
  392. return empty( $cleaned_up ); 
  393. return false; 
  394.