PageRenderTime 34ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/includes/fields/class-gf-field-checkbox.php

https://gitlab.com/level-level/gravityforms
PHP | 380 lines | 299 code | 69 blank | 12 comment | 85 complexity | 5ebe830f33dd1609ec8ce30033c2e530 MD5 | raw file
  1. <?php
  2. if ( ! class_exists( 'GFForms' ) ) {
  3. die();
  4. }
  5. class GF_Field_Checkbox extends GF_Field {
  6. public $type = 'checkbox';
  7. public function get_form_editor_field_title() {
  8. return esc_attr__( 'Checkboxes', 'gravityforms' );
  9. }
  10. public function get_form_editor_field_settings() {
  11. return array(
  12. 'conditional_logic_field_setting',
  13. 'prepopulate_field_setting',
  14. 'error_message_setting',
  15. 'label_setting',
  16. 'label_placement_setting',
  17. 'admin_label_setting',
  18. 'choices_setting',
  19. 'rules_setting',
  20. 'visibility_setting',
  21. 'description_setting',
  22. 'css_class_setting',
  23. );
  24. }
  25. public function is_conditional_logic_supported() {
  26. return true;
  27. }
  28. public function get_field_input( $form, $value = '', $entry = null ) {
  29. $form_id = absint( $form['id'] );
  30. $is_entry_detail = $this->is_entry_detail();
  31. $is_form_editor = $this->is_form_editor();
  32. $id = $this->id;
  33. $field_id = $is_entry_detail || $is_form_editor || $form_id == 0 ? "input_$id" : 'input_' . $form_id . "_$id";
  34. $disabled_text = $is_form_editor ? 'disabled="disabled"' : '';
  35. return sprintf( "<div class='ginput_container ginput_container_checkbox'><ul class='gfield_checkbox' id='%s'>%s</ul></div>", esc_attr( $field_id ), $this->get_checkbox_choices( $value, $disabled_text, $form_id ) );
  36. }
  37. public function get_first_input_id( $form ) {
  38. return '';
  39. }
  40. public function get_value_default() {
  41. return $this->is_form_editor() ? $this->defaultValue : GFCommon::replace_variables_prepopulate( $this->defaultValue );
  42. }
  43. public function get_value_submission( $field_values, $get_from_post_global_var = true ) {
  44. $parameter_values = GFFormsModel::get_parameter_value( $this->inputName, $field_values, $this );
  45. if ( ! empty( $parameter_values ) && ! is_array( $parameter_values ) ) {
  46. $parameter_values = explode( ',', $parameter_values );
  47. }
  48. if ( ! is_array( $this->inputs ) ) {
  49. return '';
  50. }
  51. $choice_index = 0;
  52. $value = array();
  53. foreach ( $this->inputs as $input ) {
  54. if ( ! empty( $_POST[ 'is_submit_' . $this->formId ] ) && $get_from_post_global_var ) {
  55. $input_value = rgpost( 'input_' . str_replace( '.', '_', strval( $input['id'] ) ) );
  56. if ( is_array( $input_value ) ) {
  57. $input_value = '';
  58. }
  59. $value[ strval( $input['id'] ) ] = $input_value;
  60. } else {
  61. if ( is_array( $parameter_values ) ) {
  62. foreach ( $parameter_values as $item ) {
  63. $item = trim( $item );
  64. if ( GFFormsModel::choice_value_match( $this, $this->choices[ $choice_index ], $item ) ) {
  65. $value[ $input['id'] . '' ] = $item;
  66. break;
  67. }
  68. }
  69. }
  70. }
  71. $choice_index ++;
  72. }
  73. return $value;
  74. }
  75. public function get_value_entry_list( $value, $entry, $field_id, $columns, $form ) {
  76. //if this is the main checkbox field (not an input), display a comma separated list of all inputs
  77. if ( absint( $field_id ) == $field_id ) {
  78. $lead_field_keys = array_keys( $entry );
  79. $items = array();
  80. foreach ( $lead_field_keys as $input_id ) {
  81. if ( is_numeric( $input_id ) && absint( $input_id ) == $field_id ) {
  82. $items[] = GFCommon::selection_display( rgar( $entry, $input_id ), null, $entry['currency'], false );
  83. }
  84. }
  85. $value = GFCommon::implode_non_blank( ', ', $items );
  86. // special case for post category checkbox fields
  87. if ( $this->type == 'post_category' ) {
  88. $value = GFCommon::prepare_post_category_value( $value, $this, 'entry_list' );
  89. }
  90. } else {
  91. $value = '';
  92. if ( ! rgblank( $this->is_checkbox_checked( $field_id, $columns[ $field_id ]['label'], $entry ) ) ) {
  93. $value = "<i class='fa fa-check gf_valid'></i>";
  94. }
  95. }
  96. return $value;
  97. }
  98. public function get_value_entry_detail( $value, $currency = '', $use_text = false, $format = 'html', $media = 'screen' ) {
  99. if ( is_array( $value ) ) {
  100. $items = '';
  101. foreach ( $value as $key => $item ) {
  102. if ( ! rgblank( $item ) ) {
  103. switch ( $format ) {
  104. case 'text' :
  105. $items .= GFCommon::selection_display( $item, $this, $currency, $use_text ) . ', ';
  106. break;
  107. default:
  108. $items .= '<li>' . GFCommon::selection_display( $item, $this, $currency, $use_text ) . '</li>';
  109. break;
  110. }
  111. }
  112. }
  113. if ( empty( $items ) ) {
  114. return '';
  115. } elseif ( $format == 'text' ) {
  116. return substr( $items, 0, strlen( $items ) - 2 ); //removing last comma
  117. } else {
  118. return "<ul class='bulleted'>$items</ul>";
  119. }
  120. } else {
  121. return $value;
  122. }
  123. }
  124. public function get_value_merge_tag( $value, $input_id, $entry, $form, $modifier, $raw_value, $url_encode, $esc_html, $format, $nl2br ) {
  125. $use_value = $modifier == 'value';
  126. $use_price = in_array( $modifier, array( 'price', 'currency' ) );
  127. $format_currency = $modifier == 'currency';
  128. if ( is_array( $raw_value ) && (string) intval( $input_id ) != $input_id ) {
  129. $items = array( $input_id => $value ); //float input Ids. (i.e. 4.1 ). Used when targeting specific checkbox items
  130. } elseif ( is_array( $raw_value ) ) {
  131. $items = $raw_value;
  132. } else {
  133. $items = array( $input_id => $raw_value );
  134. }
  135. $ary = array();
  136. foreach ( $items as $input_id => $item ) {
  137. if ( $use_value ) {
  138. list( $val, $price ) = rgexplode( '|', $item, 2 );
  139. } elseif ( $use_price ) {
  140. list( $name, $val ) = rgexplode( '|', $item, 2 );
  141. if ( $format_currency ) {
  142. $val = GFCommon::to_money( $val, rgar( $entry, 'currency' ) );
  143. }
  144. } elseif ( $this->type == 'post_category' ) {
  145. $use_id = strtolower( $modifier ) == 'id';
  146. $item_value = GFCommon::format_post_category( $item, $use_id );
  147. $val = RGFormsModel::is_field_hidden( $form, $this, array(), $entry ) ? '' : $item_value;
  148. } else {
  149. $val = RGFormsModel::is_field_hidden( $form, $this, array(), $entry ) ? '' : RGFormsModel::get_choice_text( $this, $raw_value, $input_id );
  150. }
  151. $ary[] = GFCommon::format_variable_value( $val, $url_encode, $esc_html, $format );
  152. }
  153. return GFCommon::implode_non_blank( ', ', $ary );
  154. }
  155. public function get_value_save_entry( $value, $form, $input_name, $lead_id, $lead ) {
  156. if ( rgblank( $value ) ) {
  157. return '';
  158. } elseif ( is_array( $value ) ) {
  159. foreach ( $value as &$v ) {
  160. if ( is_array( $v ) ) {
  161. $v = '';
  162. }
  163. $v = $this->sanitize_entry_value( $v, $form['id'] );
  164. }
  165. return implode( ',', $value );
  166. } else {
  167. return $this->sanitize_entry_value( $value, $form['id'] );
  168. }
  169. }
  170. public function get_checkbox_choices( $value, $disabled_text, $form_id = 0 ) {
  171. $choices = '';
  172. $is_entry_detail = $this->is_entry_detail();
  173. $is_form_editor = $this->is_form_editor();
  174. if ( is_array( $this->choices ) ) {
  175. $choice_number = 1;
  176. $count = 1;
  177. foreach ( $this->choices as $choice ) {
  178. if ( $choice_number % 10 == 0 ) { //hack to skip numbers ending in 0. so that 5.1 doesn't conflict with 5.10
  179. $choice_number ++;
  180. }
  181. $input_id = $this->id . '.' . $choice_number;
  182. if ( $is_entry_detail || $is_form_editor || $form_id == 0 ){
  183. $id = $this->id . '_' . $choice_number ++;
  184. } else {
  185. $id = $form_id . '_' . $this->id . '_' . $choice_number ++;
  186. }
  187. if ( ! isset( $_GET['gf_token'] ) && empty( $_POST ) && rgar( $choice, 'isSelected' ) ) {
  188. $checked = "checked='checked'";
  189. } elseif ( is_array( $value ) && RGFormsModel::choice_value_match( $this, $choice, rgget( $input_id, $value ) ) ) {
  190. $checked = "checked='checked'";
  191. } elseif ( ! is_array( $value ) && RGFormsModel::choice_value_match( $this, $choice, $value ) ) {
  192. $checked = "checked='checked'";
  193. } else {
  194. $checked = '';
  195. }
  196. $logic_event = $this->get_conditional_logic_event( 'click' );
  197. $tabindex = $this->get_tabindex();
  198. $choice_value = $choice['value'];
  199. if ( $this->enablePrice ) {
  200. $price = rgempty( 'price', $choice ) ? 0 : GFCommon::to_number( rgar( $choice, 'price' ) );
  201. $choice_value .= '|' . $price;
  202. }
  203. $choice_value = esc_attr( $choice_value );
  204. $choice_markup = "<li class='gchoice_{$id}'>
  205. <input name='input_{$input_id}' type='checkbox' $logic_event value='{$choice_value}' {$checked} id='choice_{$id}' {$tabindex} {$disabled_text} />
  206. <label for='choice_{$id}' id='label_{$id}'>{$choice['text']}</label>
  207. </li>";
  208. $choices .= gf_apply_filters( array(
  209. 'gform_field_choice_markup_pre_render',
  210. $this->formId,
  211. $this->id
  212. ), $choice_markup, $choice, $this, $value );
  213. $is_entry_detail = $this->is_entry_detail();
  214. $is_form_editor = $this->is_form_editor();
  215. $is_admin = $is_entry_detail || $is_form_editor;
  216. if ( $is_admin && RG_CURRENT_VIEW != 'entry' && $count >= 5 ) {
  217. break;
  218. }
  219. $count ++;
  220. }
  221. $total = sizeof( $this->choices );
  222. if ( $count < $total ) {
  223. $choices .= "<li class='gchoice_total'>" . sprintf( esc_html__( '%d of %d items shown. Edit field to view all', 'gravityforms' ), $count, $total ) . '</li>';
  224. }
  225. }
  226. return gf_apply_filters( array( 'gform_field_choices', $this->formId, $this->id ), $choices, $this );
  227. }
  228. public function allow_html() {
  229. return true;
  230. }
  231. public function sanitize_settings() {
  232. parent::sanitize_settings();
  233. if ( $this->type === 'option' ) {
  234. $this->productField = absint( $this->productField );
  235. }
  236. if ( $this->type === 'post_category' ) {
  237. $this->displayAllCategories = (bool) $this->displayAllCategories;
  238. }
  239. }
  240. public function get_value_export( $entry, $input_id = '', $use_text = false, $is_csv = false ) {
  241. if ( empty( $input_id ) || absint( $input_id ) == $input_id ) {
  242. $selected = array();
  243. foreach ( $this->inputs as $input ) {
  244. $index = (string) $input['id'];
  245. if ( ! rgempty( $index, $entry ) ) {
  246. $selected[] = GFCommon::selection_display( rgar( $entry, $index ), $this, rgar( $entry, 'currency' ), $use_text );
  247. }
  248. }
  249. return implode( ', ', $selected );
  250. } elseif ( $is_csv ) {
  251. $value = $this->is_checkbox_checked( $input_id, GFCommon::get_label( $this, $input_id ), $entry );
  252. return empty( $value ) ? '' : $value;
  253. } else {
  254. return GFCommon::selection_display( rgar( $entry, $input_id ), $this, rgar( $entry, 'currency' ), $use_text );
  255. }
  256. }
  257. public function is_checkbox_checked( $field_id, $field_label, $entry ) {
  258. $allowed_tags = wp_kses_allowed_html( 'post' );
  259. //looping through lead detail values trying to find an item identical to the column label. Mark with a tick if found.
  260. $lead_field_keys = array_keys( $entry );
  261. foreach ( $lead_field_keys as $input_id ) {
  262. //mark as a tick if input label (from form meta) is equal to submitted value (from lead)
  263. if ( is_numeric( $input_id ) && absint( $input_id ) == absint( $field_id ) ) {
  264. $sanitized_value = wp_kses( $entry[ $input_id ], $allowed_tags );
  265. $sanitized_label = wp_kses( $field_label, $allowed_tags );
  266. if ( $sanitized_value == $sanitized_label ) {
  267. return $entry[ $input_id ];
  268. } else {
  269. if ( $this->enableChoiceValue || $this->enablePrice ) {
  270. foreach ( $this->choices as $choice ) {
  271. if ( $choice['value'] == $entry[ $field_id ] ) {
  272. return $choice['value'];
  273. } elseif ( $this->enablePrice ) {
  274. $ary = explode( '|', $entry[ $field_id ] );
  275. $val = count( $ary ) > 0 ? $ary[0] : '';
  276. $price = count( $ary ) > 1 ? $ary[1] : '';
  277. if ( $val == $choice['value'] ) {
  278. return $choice['value'];
  279. }
  280. }
  281. }
  282. }
  283. }
  284. }
  285. }
  286. return false;
  287. }
  288. /**
  289. * Strip scripts and some HTML tags.
  290. *
  291. * @param string $value The field value to be processed.
  292. * @param int $form_id The ID of the form currently being processed.
  293. *
  294. * @return string
  295. */
  296. public function sanitize_entry_value( $value, $form_id ) {
  297. if ( is_array( $value ) ) {
  298. return '';
  299. }
  300. $allowable_tags = $this->get_allowable_tags( $form_id );
  301. if ( $allowable_tags !== true ) {
  302. $value = strip_tags( $value, $allowable_tags );
  303. }
  304. $allowed_protocols = wp_allowed_protocols();
  305. $value = wp_kses_no_null( $value, array( 'slash_zero' => 'keep' ) );
  306. $value = wp_kses_hook( $value, 'post', $allowed_protocols );
  307. $value = wp_kses_split( $value, 'post', $allowed_protocols );
  308. return $value;
  309. }
  310. }
  311. GF_Fields::register( new GF_Field_Checkbox() );