PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 3.3.1
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v3.3.1
3.3.1 V-3.3.0 3.2.2 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 V3.0.3 V3.0.2 -3.0.1 V_3.0.0 1.1.1 1.1.8 1.2 1.3 1.4 1.4.18 1.5.2 1.9 2.0 2.10.0 2.10.1 All 138 releases
bit-form / includes / Frontend / Form / View / Conversational / ConversationalHelpers.php

ConversationalHelpers.php in Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder 3.3.1, at includes/Frontend/Form/View/Conversational/ConversationalHelpers.php

291 lines 12.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace BitCode\BitForm\Frontend\Form\View\Conversational;
4
5 use BitCode\BitForm\Admin\Form\Helpers;
6
7 class ConversationalHelpers
8 {
9 private $_formId;
10 private $_conversationalSettings;
11 private $_stepListObject;
12 private static $_isPreviewMode = false;
13
14 public static function setPreviewMode(bool $isPreview): void
15 {
16 self::$_isPreviewMode = $isPreview;
17 }
18
19 public function __construct($formId, $conversationalSettings)
20 {
21 $this->_formId = $formId;
22 $this->_conversationalSettings = $conversationalSettings;
23 $this->_stepListObject = $this->_conversationalSettings->stepListObject;
24 }
25
26 public function getWelcomePageView()
27 {
28 $welcomePageSettings = $this->getMergedStepSettings('welcomePage');
29 $welcomeTitle = '';
30 $welcomePageMarkup = '';
31 $buttonMarkup = '';
32
33 if (!$welcomePageSettings->enable) {
34 return '';
35 }
36 if (!empty($welcomePageSettings->title)) {
37 $welcomeTitle =
38 ' <div class="bc' . $this->_formId . '-welcome-title">' . "\n"
39 . ' <h2>' . $this->escHtml($welcomePageSettings->title) . '</h2>' . "\n"
40 . ' </div>';
41 }
42
43 $startBtnPreIcn = $this->conversationalSettingsIcon($welcomePageSettings, 'startBtnPreIcn', 'btn-pre-icon', 'Start Button Pre Icon');
44 $startBtnSufIcn = $this->conversationalSettingsIcon($welcomePageSettings, 'startBtnSufIcn', 'btn-suf-icon', 'Start Button Suf Icon');
45
46 $startBtnText = $this->escHtml(!empty($welcomePageSettings->btnTxt) ? $welcomePageSettings->btnTxt : 'Start');
47
48 $stepHints = !empty($welcomePageSettings->stepHints) ? $this->ksesPost($welcomePageSettings->stepHints) : '';
49 $welcomeContent = !empty($welcomePageSettings->content) ? $this->ksesPost($welcomePageSettings->content) : '';
50
51 $buttonMarkup =
52 ' <div class="bc' . $this->_formId . '-step-btn-wrpr">' . "\n"
53 . ' <div class="bc' . $this->_formId . '-step-btn-inner-wrpr">' . "\n"
54 . ' <div class="bc' . $this->_formId . '-step-btn-cntnt">' . "\n"
55 . ' <button class="bc' . $this->_formId . '-start-btn bc' . $this->_formId . '-btn" type="button">' . "\n"
56 . ' ' . $startBtnPreIcn . "\n"
57 . ' ' . $startBtnText . "\n"
58 . ' ' . $startBtnSufIcn . "\n"
59 . ' </button>' . "\n"
60 . ' <span class="bc' . $this->_formId . '-step-hints">' . "\n"
61 . ' ' . $stepHints . "\n"
62 . ' </span>' . "\n"
63 . ' </div>' . "\n"
64 . ' </div>' . "\n"
65 . ' </div>';
66
67 $welcomePageMarkup =
68 ' <div class="bc' . $this->_formId . '-welcome-content">' . "\n"
69 . ' ' . $welcomeTitle . "\n"
70 . ' ' . $welcomeContent . "\n"
71 . ' ' . $buttonMarkup . "\n"
72 . ' </div>';
73 $imageContent = $this->conversationalSettingsIcon($welcomePageSettings, 'layoutImage', 'step-img', 'Background Image');
74 $welcomeLayout = $welcomePageSettings->layout;
75 $welcomeLayoutClsNames = "bc{$this->_formId}-welcome $welcomeLayout";
76 return $this->getStepLayout($this->_formId, $imageContent, $welcomePageMarkup, $welcomeLayout, $welcomeLayoutClsNames);
77 }
78
79 public function getNavigationView()
80 {
81 $navigationSettings = $this->_conversationalSettings->navigationSettings;
82 $formId = $this->_formId;
83 $progressLabelMarkup = '';
84 $progressBarMarkup = '';
85 $progressMarkup = '';
86 $brandingMarkup = '';
87 $navBtnMarkup = '';
88
89 $isPreview = self::$_isPreviewMode;
90
91 if ($navigationSettings->showProgressLabel || $isPreview) {
92 $hiddenCls = ($isPreview && !$navigationSettings->showProgressLabel) ? ' bc-live-hidden' : '';
93 $progressLabelMarkup =
94 ' <div class="bc' . $formId . '-progress-lbl-wrpr' . $hiddenCls . '">' . "\n"
95 . ' <span class="bc' . $formId . '-progress-lbl">' . "\n"
96 . ' ' . $this->escHtml($navigationSettings->progressLabel) . "\n"
97 . ' </span>' . "\n"
98 . ' </div>';
99 }
100
101 if ($navigationSettings->showProgressBar || $isPreview) {
102 $hiddenCls = ($isPreview && !$navigationSettings->showProgressBar) ? ' bc-live-hidden' : '';
103 $progressBarMarkup =
104 ' <div class="bc' . $formId . '-progress-bar-wrpr' . $hiddenCls . '">' . "\n"
105 . ' <div class="bc' . $formId . '-progress-bar">' . "\n"
106 . ' <div class="bc' . $formId . '-progress-fill" style="width: 0%"></div>' . "\n"
107 . ' </div>' . "\n"
108 . ' </div>';
109 }
110
111 if ($navigationSettings->showProgressBar || $navigationSettings->showProgressLabel || $isPreview) {
112 $progressMarkup =
113 ' <div class="bc' . $formId . '-progress-wrpr">' . "\n"
114 . ' <div class="bc' . $formId . '-progress-cntnt" >' . "\n"
115 . ' ' . $progressLabelMarkup . "\n"
116 . ' ' . $progressBarMarkup . "\n"
117 . ' </div>' . "\n"
118 . ' </div>';
119 }
120
121 if ($navigationSettings->showBranding || $isPreview) {
122 $hiddenCls = ($isPreview && !$navigationSettings->showBranding) ? ' bc-live-hidden' : '';
123 $brandingMarkup =
124 ' <div class="bc' . $formId . '-branding-wrpr' . $hiddenCls . '">' . "\n"
125 . ' <div class="bc' . $formId . '-branding-cntnt">' . "\n"
126 . ' <div class="bc' . $formId . '-branding-lbl">' . "\n"
127 . ' <span class="bc' . $formId . '-prowered-by-lbl">Powered by</span> <span class="bc' . $formId . '-bit-form-lbl">BitForm</span>' . "\n"
128 . ' </div>' . "\n"
129 . ' </div>' . "\n"
130 . ' </div>';
131 }
132
133 if ($navigationSettings->showNavigateBtn || $isPreview) {
134 $hiddenCls = ($isPreview && !$navigationSettings->showNavigateBtn) ? ' bc-live-hidden' : '';
135 $navBtnMarkup =
136 ' <div class="bc' . $formId . '-nav-btn-wrpr' . $hiddenCls . '">' . "\n"
137 . ' <div class="bc' . $formId . '-nav-btn-cntnt">' . "\n"
138 . ' <button class="bc' . $formId . '-nav-btn bc' . $formId . '-nav-btn-up" type="button">' . "\n"
139 . ' <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-up"><line x1="12" y1="19" x2="12" y2="5"></line><polyline points="5 12 12 5 19 12"></polyline></svg>' . "\n"
140 . ' </button>' . "\n"
141 . ' <button class="bc' . $formId . '-nav-btn bc' . $formId . '-nav-btn-down" type="button">' . "\n"
142 . ' <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-up"><line x1="12" y1="19" x2="12" y2="5"></line><polyline points="5 12 12 5 19 12"></polyline></svg>' . "\n"
143 . ' </button>' . "\n"
144 . ' </div>' . "\n"
145 . ' </div>';
146 }
147 $navBtnContainer = '';
148 if ($navigationSettings->showNavigateBtn || $isPreview) {
149 $navBtnContainer =
150 ' <div class="bc' . $formId . '-nav-btn-container">' . "\n"
151 . ' ' . $navBtnMarkup . "\n"
152 . ' </div>';
153 }
154
155 if ($navigationSettings->show || $isPreview) {
156 $hiddenCls = ($isPreview && !$navigationSettings->show) ? ' bc-live-hidden' : '';
157 return
158 ' <div class="bc' . $formId . '-nav-wrpr' . $hiddenCls . '">' . "\n"
159 . ' <div class="bc' . $formId . '-nav-wrpr-cntnt">' . "\n"
160 . ' ' . $progressMarkup . "\n"
161 . ' ' . $navBtnContainer . "\n"
162 . ' </div>' . "\n"
163 . ' ' . $brandingMarkup . "\n"
164 . ' </div>';
165 }
166 return '';
167 }
168
169 public function getStepButtonsView($fieldData, $stepSettings)
170 {
171 $formId = $this->_formId;
172 $isFieldRequired = !empty($fieldData->valid->req) && $fieldData->valid->req;
173 $btnTxt = $this->escHtml($isFieldRequired ? $stepSettings->nextBtnTxt : $stepSettings->btnTxt);
174 $btnPreIcn = $this->conversationalSettingsIcon($stepSettings, 'btnPreIcn', 'btn-pre-icon', 'Button Prefix Icon');
175 $btnSufIcn = $this->conversationalSettingsIcon($stepSettings, 'btnSufIcn', 'btn-suf-icon', 'Button Suffix Icon');
176 $hiddenClass = $isFieldRequired ? 'bc-grid-hide' : '';
177 $stepHints = !empty($stepSettings->stepHints) ? $this->ksesPost($stepSettings->stepHints) : '';
178
179 $dataBtnTxt = esc_attr(!empty($stepSettings->btnTxt) ? $stepSettings->btnTxt : 'Skip');
180 $dataNextBtnTxt = esc_attr(!empty($stepSettings->nextBtnTxt) ? $stepSettings->nextBtnTxt : 'Next');
181
182 $btnWrapperMarkup =
183 ' <div class="' . $hiddenClass . ' bc' . $formId . '-step-btn-wrpr">' . "\n"
184 . ' <div class="bc' . $formId . '-step-btn-inner-wrpr">' . "\n"
185 . ' <div class="bc' . $formId . '-step-btn-cntnt">' . "\n"
186 . ' <button class="bc' . $formId . '-btn bc' . $formId . '-btn-ok" type="button"'
187 . ' data-btn-txt="' . $dataBtnTxt . '" data-next-btn-txt="' . $dataNextBtnTxt . '">' . "\n"
188 . ' ' . $btnPreIcn . "\n"
189 . ' ' . $btnTxt . "\n"
190 . ' ' . $btnSufIcn . "\n"
191 . ' </button>' . "\n"
192 . ' <span class="bc' . $formId . '-step-hints">' . "\n"
193 . ' ' . $stepHints . "\n"
194 . ' </span>' . "\n"
195 . ' </div>' . "\n"
196 . ' </div>' . "\n"
197 . ' </div>';
198
199 return $btnWrapperMarkup;
200 }
201
202 public static function getStepLayout($formID, $imageContent, $fieldContent, $layoutName, $layoutClassNames = '')
203 {
204 $stepWrapperClass = esc_attr('bc' . $formID . '-step-wrapper bc' . $formID . '-step bc-step-deactive ' . $layoutClassNames);
205 $imageContentWrapper =
206 ' <div class="bc' . $formID . '-step-img-cntnr">' . "\n"
207 . ' <picture class="bc' . $formID . '-step-img-wrpr">' . "\n"
208 . ' ' . $imageContent . "\n"
209 . ' </picture>' . "\n"
210 . ' </div>';
211 $noImageLayouts = ['normal-layout', 'centered-card-layout'];
212 $imageContentWrapper = in_array($layoutName, $noImageLayouts, true) ? '' : $imageContentWrapper;
213
214 return
215 ' <div class="' . $stepWrapperClass . '">' . "\n"
216 . ' <div class="bc' . $formID . '-step-content">' . "\n"
217 . ' ' . $imageContentWrapper . "\n"
218 . ' <div class="bc' . $formID . '-step-fld-wrpr">' . "\n"
219 . ' ' . $fieldContent . "\n"
220 . ' </div>' . "\n"
221 . ' </div>' . "\n"
222 . ' </div>';
223 }
224
225 public function conversationalSettingsIcon($data, $icnPropName, $element, $alt = 'Image')
226 {
227 if (Helpers::property_exists_nested($data, $icnPropName, '', 1)) {
228 $url = esc_url($data->$icnPropName);
229 $class = esc_attr('bc' . $this->_formId . '-' . $element);
230 $alt = esc_attr($alt);
231 return
232 ' <img' . "\n"
233 . ' class="' . $class . '"' . "\n"
234 . ' src="' . $url . '"' . "\n"
235 . ' alt="' . $alt . '"' . "\n"
236 . ' />';
237 }
238 return '';
239 }
240
241 public function filterConversationalAllowedFields($layout, $fields)
242 {
243 $ignoreFields = $this::getConversationalIgnoredFields();
244 $newLayouts = (object) ['lg' => []];
245 foreach ($layout->lg as $row) {
246 if (!in_array($fields->{$row->i}->typ, $ignoreFields)) {
247 $newLayouts->lg[] = $row;
248 }
249 }
250 return $newLayouts;
251 }
252
253 public static function getConversationalIgnoredFields()
254 {
255 return [
256 'button',
257 'divider',
258 'spacer',
259 'title',
260 'html',
261 'shortcode',
262 'recaptcha',
263 'turnstile',
264 'hcaptcha',
265 'image',
266 'stripe',
267 'paypal',
268 'razorpay',
269 ];
270 }
271
272 public function getMergedStepSettings($stepPropertyName)
273 {
274 $allStepsSettings = $this->_stepListObject->allSteps;
275 $stepSettings = !empty($this->_stepListObject->{$stepPropertyName}) ? $this->_stepListObject->{$stepPropertyName} : (object) [];
276 $mergedSettings = (object) array_merge((array) $allStepsSettings, (array) $stepSettings);
277
278 return $mergedSettings;
279 }
280
281 private function escHtml($value)
282 {
283 return esc_html((string) $value);
284 }
285
286 private function ksesPost($value)
287 {
288 return wp_kses_post((string) $value);
289 }
290 }
291