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 / Modules / Form / Settings / FormCssJs.php

FormCssJs.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.14, at app/Modules/Form/Settings/FormCssJs.php

264 lines 8.7 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\Modules\Form\Settings;
4
5 defined('ABSPATH') or die;
6
7 use FluentForm\App\Helpers\Helper;
8 use FluentForm\Framework\Helpers\ArrayHelper;
9
10 class FormCssJs
11 {
12 /**
13 * Request object
14 *
15 * @var \FluentForm\Framework\Request\Request $request
16 */
17 protected $request;
18
19 public function __construct()
20 {
21 $this->request = wpFluentForm('request');
22 }
23
24 public function addCustomCssJs($formId)
25 {
26 if (did_action('fluentform/adding_custom_css_js_' . $formId)) {
27 return;
28 }
29
30 do_action('fluentform/adding_custom_css_js_' . $formId, $formId);
31
32 $metaKeys = ['_custom_form_css', '_custom_form_js'];
33
34 $metas = (new \FluentForm\App\Services\Settings\Customizer())->get($formId, $metaKeys);
35
36 foreach ($metas as $metaKey => $metaValue) {
37 if ($metaValue) {
38 switch ($metaKey) {
39 case 'css':
40 $css = $metaValue;
41 $css = str_replace('{form_id}', $formId, $css);
42 $customCss = str_replace('FF_ID', $formId, $css);
43
44 if ($customCss) {
45 $this->addCss($formId, $customCss, 'fluentform_custom_css_' . $formId);
46 }
47 break;
48 case 'js':
49 $this->addJs($formId, $metaValue);
50 break;
51 }
52 }
53 }
54 }
55
56 public function addStylerCSS($formId, $styles = [])
57 {
58 $metaKeys = array_merge(
59 ['_ff_form_styler_css', '_ff_selected_style'],
60 $styles
61 );
62
63 $metas = (new \FluentForm\App\Services\Settings\Customizer())->get($formId, $metaKeys);
64
65 foreach ($styles as $style) {
66 if (!$style) {
67 continue;
68 }
69
70 if ('ffs_inherit_theme' === $style) {
71 continue;
72 }
73
74 $loadCss = ArrayHelper::get($metas, $style);
75
76 if (!$loadCss) {
77 $loadCss = apply_filters('fluentform/build_style_from_theme', '', $formId, $style);
78
79 // todo: remove this from next version. it's only here to support if the user updates the free version first.
80 if (!$loadCss) {
81 $selectedStyle = ArrayHelper::get($metas, '_ff_selected_style');
82 $selectedStyleCSS = ArrayHelper::get($metas, '_ff_form_styler_css');
83
84 if ($selectedStyle == $style && $selectedStyleCSS) {
85 $loadCss = $selectedStyleCSS;
86 }
87 }
88 }
89
90 if ($loadCss) {
91 $this->addCss($formId, $loadCss, 'fluentform_styler_css_' . $formId . '_' . $style);
92
93 do_action('fluent_form/loaded_styler_' . $formId . '_' . $style);
94 }
95 }
96 }
97
98 public function getCss($formId)
99 {
100 $cssMeta = wpFluent()->table('fluentform_form_meta')
101 ->where('form_id', $formId)
102 ->where('meta_key', '_custom_form_css')
103 ->first();
104
105 if (!$cssMeta || !$cssMeta->value) {
106 return '';
107 }
108
109 $css = $cssMeta->value;
110 $css = str_replace('{form_id}', $formId, $css);
111 $css = str_replace('FF_ID', $formId, $css);
112 return fluentformSanitizeCSS($css);
113 }
114
115 public function getJs($formId)
116 {
117 $jsMeta = wpFluent()->table('fluentform_form_meta')
118 ->where('form_id', $formId)
119 ->where('meta_key', '_custom_form_js')
120 ->first();
121
122 if (!$jsMeta || !$jsMeta->value) {
123 return '';
124 }
125
126 return $jsMeta->value;
127 }
128
129 public function addCss($formId, $css, $cssId = 'fluentform_custom_css')
130 {
131 if ($css) {
132 $action = false;
133
134 if (!did_action('wp_head')) {
135 $action = 'wp_head';
136 } elseif (!did_action('wp_footer')) {
137 $action = 'wp_footer';
138 }
139
140 if (Helper::isBlockEditor()) {
141 $action = false;
142 }
143
144 if ($action) {
145 add_action($action, function () use ($css, $cssId) {
146 ?>
147 <style id="<?php echo esc_attr($cssId); ?>" type="text/css">
148 <?php echo fluentformSanitizeCSS($css); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- fluentformSanitizeCSS() removes HTML tags, CSS is safe in style context ?>
149 </style>
150
151 <?php
152 }, 99);
153 } else {
154 ?>
155 <style id="<?php echo esc_attr($cssId); ?>" type="text/css">
156 <?php echo fluentformSanitizeCSS($css); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- fluentformSanitizeCSS() removes HTML tags, CSS is safe in style context ?>
157 </style>
158 <?php
159 }
160 }
161 }
162
163 public function addJs($formId, $customJS)
164 {
165 if (trim($customJS)) {
166 add_action('wp_footer', function () use ($formId, $customJS) {
167 ?>
168 <script type="text/javascript">
169 jQuery(document.body).on('fluentform_init_<?php echo esc_attr($formId); ?>',
170 function(event, data) {
171 var $form = jQuery(data[0]);
172 var formId = "<?php echo esc_attr($formId); ?>";
173 var $ = jQuery;
174 try {
175 <?php echo fluentform_kses_js($customJS); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- fluentform_kses_js() removes script tags, JS is safe in script context ?>
176 } catch (e) {
177 console.warn('Error in custom JS of Fluentform ID: ' + formId);
178 console.error(e);
179 }
180 });
181 </script>
182 <?php
183 }, 100);
184 }
185 }
186
187 /**
188 * Get settings for a particular form by id
189 */
190 public function getSettingsAjax()
191 {
192 $formId = absint($this->request->get('form_id'));
193 // SECURITY (H-02): this handler is currently unregistered, but it read form CSS/JS with no
194 // capability check. Guard it so it is safe if ever wired to an action.
195 \FluentForm\App\Modules\Acl\Acl::verify('fluentform_forms_manager', $formId);
196 wp_send_json_success([
197 'custom_css' => $this->getData($formId, '_custom_form_css'),
198 'custom_js' => $this->getData($formId, '_custom_form_js'),
199 ], 200);
200 }
201
202 /**
203 * Save settings for a particular form by id
204 */
205 public function saveSettingsAjax()
206 {
207 // SECURITY (H-02): this handler is currently unregistered; guard it (forms_manager scope)
208 // so it is safe if ever wired. The unfiltered_html gate below still applies on top.
209 \FluentForm\App\Modules\Acl\Acl::verify('fluentform_forms_manager', absint($this->request->get('form_id')));
210 if (!fluentformCanUnfilteredHTML()) {
211 wp_send_json_error([
212 'message' => __('You need unfiltered_html permission to save Custom CSS & JS', 'fluentform'),
213 ], 423);
214 }
215
216 $formId = absint($this->request->get('form_id'));
217
218 $css = fluentformSanitizeCSS($this->request->get('custom_css'));
219 $js = fluentform_kses_js($this->request->get('custom_js'));
220
221 $this->store($formId, '_custom_form_css', $css);
222 $this->store($formId, '_custom_form_js', $js);
223
224 wp_send_json_success([
225 'message' => __('Custom CSS & JS successfully updated', 'fluentform'),
226 ], 200);
227 }
228
229 protected function getData($formId, $metaKey)
230 {
231 $row = wpFluent()->table('fluentform_form_meta')
232 ->where('form_id', $formId)
233 ->where('meta_key', $metaKey)
234 ->first();
235 if ($row) {
236 return $row->value;
237 }
238 return '';
239 }
240
241 protected function store($formId, $metaKey, $metaValue)
242 {
243 $row = wpFluent()->table('fluentform_form_meta')
244 ->where('form_id', $formId)
245 ->where('meta_key', $metaKey)
246 ->first();
247
248 if (!$row) {
249 return wpFluent()->table('fluentform_form_meta')
250 ->insertGetId([
251 'form_id' => $formId,
252 'meta_key' => $metaKey,
253 'value' => $metaValue,
254 ]);
255 }
256
257 return wpFluent()->table('fluentform_form_meta')
258 ->where('id', $row->id)
259 ->update([
260 'value' => $metaValue,
261 ]);
262 }
263 }
264