PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.14
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.14
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / app / Services / FormBuilder / Components / Checkable.php

Checkable.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.14, at app/Services/FormBuilder/Components/Checkable.php

216 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\App\Services\FormBuilder\Components;
4
5 use FluentForm\Framework\Helpers\ArrayHelper;
6
7 class Checkable extends BaseComponent
8 {
9 /**
10 * Compile and echo the html element
11 *
12 * @param array $data [element data]
13 * @param \stdClass $form [Form Object]
14 *
15 * @return void
16 */
17 public function compile($data, $form)
18 {
19 $elementName = $data['element'];
20
21 $data = apply_filters_deprecated(
22 'fluentform_rendering_field_data_' . $elementName,
23 [
24 $data,
25 $form
26 ],
27 FLUENTFORM_FRAMEWORK_UPGRADE,
28 'fluentform/rendering_field_data_' . $elementName,
29 'Use fluentform/rendering_field_data_' . $elementName . ' instead of fluentform_rendering_field_data_' . $elementName
30 );
31
32 $data = apply_filters('fluentform/rendering_field_data_' . $elementName, $data, $form);
33
34 $data['attributes']['class'] = trim(
35 'ff-el-form-check-input ' .
36 'ff-el-form-check-' . $data['attributes']['type'] . ' ' .
37 ArrayHelper::get($data, 'attributes.class')
38 );
39
40 if ('checkbox' == $data['attributes']['type']) {
41 $data['attributes']['name'] = $data['attributes']['name'] . '[]';
42 }
43
44 $defaultValues = (array) $this->extractValueFromAttributes($data);
45
46 if ($dynamicValues = $this->extractDynamicValues($data, $form)) {
47 $defaultValues = $dynamicValues;
48 }
49
50 $elMarkup = '';
51
52 $firstTabIndex = \FluentForm\App\Helpers\Helper::getNextTabIndex();
53
54 if (! $formattedOptions = ArrayHelper::get($data, 'settings.advanced_options')) {
55 $options = ArrayHelper::get($data, 'options', []);
56 $formattedOptions = [];
57 foreach ($options as $value => $label) {
58 $formattedOptions[] = [
59 'label' => $label,
60 'value' => $value,
61 'calc_value' => '',
62 'image' => '',
63 ];
64 }
65 }
66
67 $hasImageOption = ArrayHelper::get($data, 'settings.enable_image_input');
68
69 if ($hasImageOption) {
70 if (empty($data['settings']['layout_class'])) {
71 $data['settings']['layout_class'] = 'ff_list_buttons';
72 }
73 $elMarkup .= '<div class="ff_el_checkable_photo_holders">';
74 }
75
76 $data['settings']['container_class'] = trim(
77 ArrayHelper::get($data, 'settings.container_class', '')
78 . ' ' . ArrayHelper::get($data, 'settings.layout_class', '')
79 );
80
81 if ('yes' == ArrayHelper::get($data, 'settings.randomize_options')) {
82 shuffle($formattedOptions);
83 }
84
85 // Add "Other" option if enabled
86 $enableOtherOption = ArrayHelper::get($data, 'settings.enable_other_option') === 'yes';
87 if ($enableOtherOption && in_array($data['attributes']['type'], ['checkbox', 'radio']) && defined('FLUENTFORMPRO')) {
88 $fieldName = sanitize_text_field(str_replace(['[', ']'], '', $data['attributes']['name']));
89 $otherLabel = ArrayHelper::get($data, 'settings.other_option_label', __('Other', 'fluentform'));
90 $formattedOptions[] = [
91 'label' => $otherLabel,
92 'value' => '__ff_other_' . $fieldName . '__',
93 'calc_value' => '',
94 'image' => '',
95 'is_other' => true,
96 ];
97 }
98 // @todo : Find a alternative screen reader support
99 // $legendId = $this->getUniqueid(str_replace(['[', ']'], ['', ''], $data['attributes']['name']));
100 // $elMarkup .= '<fieldset role="group" style="border: none!important;margin: 0!important;padding: 0!important;background-color: transparent!important;box-shadow: none!important;outline: none!important; min-inline-size: 100%;" aria-labelledby="legend_' . $legendId . '">';
101 //
102 // $elMarkup .= '<legend style=" position: absolute;width: 1px;height: 1px;padding: 0;margin: 0;overflow: hidden;clip: rect(0, 0, 0, 0);border: 0;" role="heading" id="legend_' . $legendId . '" class="ff-sreader-only">' . esc_attr($this->removeShortcode($data['settings']['label'])) . '</legend>';
103
104 $otherInputHtml = '';
105 foreach ($formattedOptions as $option) {
106 $displayType = isset($data['settings']['display_type']) ? ' ff-el-form-check-' . $data['settings']['display_type'] : '';
107 $parentClass = 'ff-el-form-check' . esc_attr($displayType) . '';
108
109 if (in_array($option['value'], $defaultValues)) {
110 $data['attributes']['checked'] = true;
111 $parentClass .= ' ff_item_selected';
112 } else {
113 $data['attributes']['checked'] = false;
114 }
115
116 if ($firstTabIndex) {
117 $data['attributes']['tabindex'] = $firstTabIndex;
118 $firstTabIndex = '-1';
119 }
120
121 $data['attributes']['value'] = $option['value'];
122 $data['attributes']['data-calc_value'] = ArrayHelper::get($option, 'calc_value');
123
124 $atts = $this->buildAttributes($data['attributes']);
125
126 $id = $this->getUniqueid(str_replace(['[', ']'], ['', ''], $data['attributes']['name']));
127
128 if ($hasImageOption) {
129 $parentClass .= ' ff-el-image-holder';
130 }
131
132 $elMarkup .= "<div class='" . esc_attr($parentClass) . "'>";
133
134 $id = esc_attr($id);
135
136 $label = fluentform_sanitize_html($option['label']);
137 $ariaLabel = esc_attr($label);
138 // Here we can push the visual items
139 if ($hasImageOption) {
140 $elMarkup .= "<label style='background-image: url(" . esc_url($option['image']) . ")' class='ff-el-image-input-src' for='{$id}' aria-label='{$this->removeShortcode($ariaLabel)}'></label>";
141 }
142
143 $ariaRequired = 'false';
144 if (ArrayHelper::get($data, 'settings.validation_rules.required.value')) {
145 $ariaRequired = 'true';
146 }
147
148 $disabled = ArrayHelper::get($option, 'disabled') ? 'disabled' : '';
149
150 $isOtherOption = ArrayHelper::get($option, 'is_other', false);
151 $otherClass = $isOtherOption ? ' ff-other-option' : '';
152
153 $elMarkup .= "<label class='ff-el-form-check-label{$otherClass}' for='{$id}'><input {$disabled} {$atts} id='{$id}' aria-label='{$this->removeShortcode($ariaLabel)}' aria-invalid='false' aria-required={$ariaRequired}> <span>" . $label . '</span></label>';
154
155 // Add text input for "Other" option
156 if ($isOtherOption && defined('FLUENTFORMPRO')) {
157 $otherPlaceholder = ArrayHelper::get($data, 'settings.other_option_placeholder', __('Please specify...', 'fluentform'));
158 $fieldName = str_replace(['[', ']'], '', $data['attributes']['name']);
159 $otherInputName = $fieldName . '__ff_other_input__';
160 $otherValue = '';
161
162 // Defaulted like the sibling reads above: forms saved before this
163 // setting existed would otherwise fall through to the field's
164 // "This field is required", which is wrong on an optional field.
165 $otherRequiredMessage = trim((string) ArrayHelper::get(
166 $data,
167 'settings.other_option_required_message',
168 __('Please specify a value for the selected "Other" option', 'fluentform')
169 ));
170
171 // An "Other" that is already selected (configured or dynamic
172 // default) must render with its input visible and required —
173 // otherwise the field is mandatory but invisible and the form
174 // cannot be submitted at all.
175 $otherIsSelected = in_array($option['value'], $defaultValues);
176 $wrapperDisplay = $otherIsSelected ? '' : 'display: none; ';
177 $otherAriaRequired = $otherIsSelected ? " aria-required='true'" : '';
178
179 $marginTop = $hasImageOption ? '20px' : '8px';
180 $otherInputHtml .= "<div class='ff-other-input-wrapper' style='{$wrapperDisplay}margin-top: {$marginTop};' data-field='" . esc_attr($fieldName) . "' data-required-message='" . esc_attr($otherRequiredMessage) . "'>";
181 // The id is what the validator points aria-describedby at when the
182 // free text is required but empty.
183 $otherInputId = $this->getUniqueid('ff_other_' . $fieldName);
184 $otherInputHtml .= "<input type='text' id='" . esc_attr($otherInputId) . "' name='" . esc_attr($otherInputName) . "' class='ff-el-form-control'{$otherAriaRequired} placeholder='" . esc_attr($otherPlaceholder) . "' value='" . esc_attr($otherValue) . "'>";
185 $otherInputHtml .= "</div>";
186 }
187
188 $elMarkup .= '</div>';
189 }
190
191 if ($hasImageOption) {
192 $elMarkup .= '</div>';
193 }
194 if ($otherInputHtml) {
195 $elMarkup .= $otherInputHtml;
196 }
197 // $elMarkup .= '</fieldset>';
198
199 $html = $this->buildElementMarkup($elMarkup, $data, $form);
200
201 $data = apply_filters_deprecated(
202 'fluentform_rendering_field_html_' . $elementName,
203 [
204 $html,
205 $data,
206 $form
207 ],
208 FLUENTFORM_FRAMEWORK_UPGRADE,
209 'fluentform/rendering_field_html_' . $elementName,
210 'Use fluentform/rendering_field_html_' . $elementName . ' instead of fluentform_nonce_verify.'
211 );
212
213 $this->printContent('fluentform/rendering_field_html_' . $elementName, $html, $data, $form);
214 }
215 }
216