PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / V3.3.2
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder vV3.3.2
V3.3.2 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 All 139 releases
← All changes | includes/Frontend/Form/View/Conversational/ConversationalHelpers.php +166 -143 2.10.0 → V3.3.2 View file →
@@ -8,9 +8,15 @@
8 8 {
9 9 private $_formId;
10 10 private $_conversationalSettings;
11 11 private $_stepListObject;
12 + private static $_isPreviewMode = false;
12 13
14 + public static function setPreviewMode(bool $isPreview): void
15 + {
16 + self::$_isPreviewMode = $isPreview;
17 + }
18 +
13 19 public function __construct($formId, $conversationalSettings)
14 20 {
15 21 $this->_formId = $formId;
16 22 $this->_conversationalSettings = $conversationalSettings;
@@ -18,53 +24,53 @@
18 24 }
19 25
20 26 public function getWelcomePageView()
21 27 {
22 - $welcomePageSettings = $this->getMergedStepSettings("welcomePage");
28 + $welcomePageSettings = $this->getMergedStepSettings('welcomePage');
23 29 $welcomeTitle = '';
24 30 $welcomePageMarkup = '';
25 31 $buttonMarkup = '';
26 32
27 - if(!$welcomePageSettings->enable) return '';
33 + if (!$welcomePageSettings->enable) {
34 + return '';
35 + }
28 36 if (!empty($welcomePageSettings->title)) {
29 - $welcomeTitle = <<<WELCOMETITLE
30 - <div class="bc{$this->_formId}-welcome-title">
31 - <h2>{$welcomePageSettings->title}</h2>
32 - </div>
33 -WELCOMETITLE;
37 + $welcomeTitle =
38 + ' <div class="bc' . $this->_formId . '-welcome-title">' . "\n"
39 + . ' <h2>' . $this->escHtml($welcomePageSettings->title) . '</h2>' . "\n"
40 + . ' </div>';
34 41 }
35 42
36 43 $startBtnPreIcn = $this->conversationalSettingsIcon($welcomePageSettings, 'startBtnPreIcn', 'btn-pre-icon', 'Start Button Pre Icon');
37 44 $startBtnSufIcn = $this->conversationalSettingsIcon($welcomePageSettings, 'startBtnSufIcn', 'btn-suf-icon', 'Start Button Suf Icon');
38 45
39 - $startBtnText = !empty($welcomePageSettings->btnTxt) ? $welcomePageSettings->btnTxt : 'Start';
46 + $startBtnText = $this->escHtml(!empty($welcomePageSettings->btnTxt) ? $welcomePageSettings->btnTxt : 'Start');
40 47
41 - $stepHints = !empty($welcomePageSettings->stepHints) ? $welcomePageSettings->stepHints : '';
48 + $stepHints = !empty($welcomePageSettings->stepHints) ? $this->ksesPost($welcomePageSettings->stepHints) : '';
49 + $welcomeContent = !empty($welcomePageSettings->content) ? $this->ksesPost($welcomePageSettings->content) : '';
42 50
43 - $buttonMarkup = <<<BUTTONMARKUP
44 - <div class="bc{$this->_formId}-step-btn-wrpr">
45 - <div class="bc{$this->_formId}-step-btn-inner-wrpr">
46 - <div class="bc{$this->_formId}-step-btn-cntnt">
47 - <button class="bc{$this->_formId}-start-btn bc{$this->_formId}-btn" type="button">
48 - {$startBtnPreIcn}
49 - {$startBtnText}
50 - {$startBtnSufIcn}
51 - </button>
52 - <span class="bc{$this->_formId}-step-hints">
53 - {$stepHints}
54 - </span>
55 - </div>
56 - </div>
57 - </div>
58 -BUTTONMARKUP;
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>';
59 66
60 - $welcomePageMarkup = <<<WELCOMEPAGECONTENT
61 - <div class="bc{$this->_formId}-welcome-content">
62 - {$welcomeTitle}
63 - {$welcomePageSettings->content}
64 - {$buttonMarkup}
65 - </div>
66 -WELCOMEPAGECONTENT;
67 + $welcomePageMarkup =
68 + ' <div class="bc' . $this->_formId . '-welcome-content">' . "\n"
69 + . ' ' . $welcomeTitle . "\n"
70 + . ' ' . $welcomeContent . "\n"
71 + . ' ' . $buttonMarkup . "\n"
72 + . ' </div>';
67 73 $imageContent = $this->conversationalSettingsIcon($welcomePageSettings, 'layoutImage', 'step-img', 'Background Image');
68 74 $welcomeLayout = $welcomePageSettings->layout;
69 75 $welcomeLayoutClsNames = "bc{$this->_formId}-welcome $welcomeLayout";
70 76 return $this->getStepLayout($this->_formId, $imageContent, $welcomePageMarkup, $welcomeLayout, $welcomeLayoutClsNames);
@@ -79,85 +85,84 @@
79 85 $progressMarkup = '';
80 86 $brandingMarkup = '';
81 87 $navBtnMarkup = '';
82 88
83 - if ($navigationSettings->showProgressLabel) {
84 - $progressLabelMarkup = <<<PERCENTAGEMARKUP
85 - <div class="bc{$formId}-progress-lbl-wrpr">
86 - <span class="bc{$formId}-progress-lbl">
87 - {$navigationSettings->progressLabel}
88 - </span>
89 - </div>
90 -PERCENTAGEMARKUP;
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>';
91 99 }
92 100
93 - if ($navigationSettings->showProgressBar) {
94 - $progressBarMarkup = <<<PROGRESSBARMARKUP
95 - <div class="bc{$formId}-progress-bar-wrpr">
96 - <div class="bc{$formId}-progress-bar">
97 - <div class="bc{$formId}-progress-fill" style="width: 40%"></div>
98 - </div>
99 - </div>
100 -PROGRESSBARMARKUP;
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>';
101 109 }
102 110
103 - if ($navigationSettings->showProgressBar || $navigationSettings->showProgressLabel) {
104 - $progressMarkup = <<<PROGRESSMARKUP
105 - <div class="bc{$formId}-progress-wrpr">
106 - <div class="bc{$formId}-progress-cntnt" >
107 - {$progressLabelMarkup}
108 - {$progressBarMarkup}
109 - </div>
110 - </div>
111 -PROGRESSMARKUP;
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>';
112 119 }
113 120
114 - if ($navigationSettings->showBranding) {
115 - $brandingMarkup = <<<BRANDINGMARKUP
116 - <div class="bc{$formId}-branding-wrpr">
117 - <div class="bc{$formId}-branding-cntnt">
118 - <div class="bc{$formId}-branding-lbl">
119 - <span class="bc{$formId}-prowered-by-lbl">Powered by</span>
120 - <span class="bc{$formId}-bit-form-lbl">Bit Form</span>
121 - </div>
122 - </div>
123 - </div>
124 -BRANDINGMARKUP;
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>';
125 131 }
126 132
127 - if ($navigationSettings->showNavigateBtn) {
128 - $navBtnMarkup = <<<NAVBTNMARKUP
129 - <div class="bc{$formId}-nav-btn-wrpr">
130 - <div class="bc{$formId}-nav-btn-cntnt">
131 - <button class="bc{$formId}-nav-btn bc{$formId}-nav-btn-up" type="button">
132 - <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>
133 - </button>
134 - <button class="bc{$formId}-nav-btn bc{$formId}-nav-btn-down" type="button">
135 - <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>
136 - </button>
137 - </div>
138 - </div>
139 -NAVBTNMARKUP;
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>';
140 146 }
141 147 $navBtnContainer = '';
142 - if ($navigationSettings->showNavigateBtn || $navigationSettings->showBranding) {
143 - $navBtnContainer = <<<NAVBTNCNTNR
144 - <div class="bc{$formId}-nav-btn-container">
145 - {$brandingMarkup}
146 - {$navBtnMarkup}
147 - </div>
148 -NAVBTNCNTNR;
148 + if ($navigationSettings->showNavigateBtn || $isPreview) {
149 + $navBtnContainer =
150 + ' <div class="bc' . $formId . '-nav-btn-container">' . "\n"
151 + . ' ' . $navBtnMarkup . "\n"
152 + . ' </div>';
149 153 }
150 154
151 - if ($navigationSettings->show) {
152 - return <<<NAVVIEW
153 - <div class="bc{$formId}-nav-wrpr">
154 - <div class="bc{$formId}-nav-wrpr-cntnt">
155 - {$progressMarkup}
156 - {$navBtnContainer}
157 - </div>
158 - </div>
159 -NAVVIEW;
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>';
160 165 }
161 166 return '';
162 167 }
163 168
@@ -164,55 +169,58 @@
164 169 public function getStepButtonsView($fieldData, $stepSettings)
165 170 {
166 171 $formId = $this->_formId;
167 172 $isFieldRequired = !empty($fieldData->valid->req) && $fieldData->valid->req;
168 - $btnTxt = $isFieldRequired ? $stepSettings->nextBtnTxt : $stepSettings->btnTxt;
169 - $btnPreIcn = $this->conversationalSettingsIcon($stepSettings, 'btnPreIcn', 'btn-pre-icon', 'Button Leading Icon');
170 - $btnSufIcn = $this->conversationalSettingsIcon($stepSettings, 'btnSufIcn', 'btn-suf-icon', 'Button Trailing Icon');
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');
171 176 $hiddenClass = $isFieldRequired ? 'bc-grid-hide' : '';
172 - $stepHints = !empty($stepSettings->stepHints) ? $stepSettings->stepHints : '';
177 + $stepHints = !empty($stepSettings->stepHints) ? $this->ksesPost($stepSettings->stepHints) : '';
173 178
174 - $btnWrapperMarkup = <<<BTNWRAPPERMARKUP
175 - <div class="{$hiddenClass} bc{$formId}-step-btn-wrpr">
176 - <div class="bc{$formId}-step-btn-inner-wrpr">
177 - <div class="bc{$formId}-step-btn-cntnt">
178 - <button class="bc{$formId}-btn bc{$formId}-btn-ok" type="button">
179 - {$btnPreIcn}
180 - {$btnTxt}
181 - {$btnSufIcn}
182 - </button>
183 - <span class="bc{$formId}-step-hints">
184 - {$stepHints}
185 - </span>
186 - </div>
187 - </div>
188 - </div>
189 -BTNWRAPPERMARKUP;
179 + $dataBtnTxt = esc_attr(!empty($stepSettings->btnTxt) ? $stepSettings->btnTxt : 'Skip');
180 + $dataNextBtnTxt = esc_attr(!empty($stepSettings->nextBtnTxt) ? $stepSettings->nextBtnTxt : 'Next');
190 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 +
191 199 return $btnWrapperMarkup;
192 200 }
193 201
194 202 public static function getStepLayout($formID, $imageContent, $fieldContent, $layoutName, $layoutClassNames = '')
195 203 {
196 - $imageContentWrapper = <<<IMAGECONTENTWRAPPER
197 - <div class="bc{$formID}-step-img-cntnr">
198 - <picture class="bc{$formID}-step-img-wrpr">
199 - {$imageContent}
200 - </picture>
201 - </div>
202 -IMAGECONTENTWRAPPER;
203 - $imageContentWrapper = $layoutName === 'normal-layout' ? '' : $imageContentWrapper;
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;
204 213
205 - return <<<STEPLAYOUT
206 - <div class="bc{$formID}-step-wrapper bc{$formID}-step bc-step-deactive {$layoutClassNames}">
207 - <div class="bc{$formID}-step-content">
208 - {$imageContentWrapper}
209 - <div class="bc{$formID}-step-fld-wrpr">
210 - {$fieldContent}
211 - </div>
212 - </div>
213 - </div>
214 -STEPLAYOUT;
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>';
215 223 }
216 224
217 225 public function conversationalSettingsIcon($data, $icnPropName, $element, $alt = 'Image')
218 226 {
@@ -217,15 +225,16 @@
217 225 public function conversationalSettingsIcon($data, $icnPropName, $element, $alt = 'Image')
218 226 {
219 227 if (Helpers::property_exists_nested($data, $icnPropName, '', 1)) {
220 228 $url = esc_url($data->$icnPropName);
221 - return <<<ICON
222 - <img
223 - class="bc{$this->_formId}-{$element}"
224 - src="{$url}"
225 - alt={$alt}
226 - />
227 -ICON;
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 + . ' />';
228 237 }
229 238 return '';
230 239 }
231 240
@@ -245,12 +254,15 @@
245 254 {
246 255 return [
247 256 'button',
248 257 'divider',
258 + 'spacer',
249 259 'title',
250 260 'html',
261 + 'shortcode',
251 262 'recaptcha',
252 263 'turnstile',
264 + 'hcaptcha',
253 265 'image',
254 266 'stripe',
255 267 'paypal',
256 268 'razorpay',
@@ -256,12 +268,23 @@
256 268 'razorpay',
257 269 ];
258 270 }
259 271
260 - public function getMergedStepSettings($stepPropertyName){
272 + public function getMergedStepSettings($stepPropertyName)
273 + {
261 274 $allStepsSettings = $this->_stepListObject->allSteps;
262 275 $stepSettings = !empty($this->_stepListObject->{$stepPropertyName}) ? $this->_stepListObject->{$stepPropertyName} : (object) [];
263 276 $mergedSettings = (object) array_merge((array) $allStepsSettings, (array) $stepSettings);
264 277
265 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);
266 289 }
267 290 }