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
← All changes | app/Services/FormBuilder/EditorShortcodeParser.php +212 -79 3.6.506.2.14 View file →
@@ -1,16 +1,16 @@
1 1 <?php
2 2
3 3 namespace FluentForm\App\Services\FormBuilder;
4 4
5 +use FluentForm\App\Helpers\Helper;
5 6 use FluentForm\App\Services\Browser\Browser;
6 -use FluentForm\Framework\Helpers\ArrayHelper;
7 -use FluentForm\Request;
8 7
9 8 class EditorShortcodeParser
10 9 {
11 10 /**
12 11 * Available dynamic short codes
12 + *
13 13 * @var null
14 14 */
15 15 private static $dynamicShortcodes = null;
16 16
@@ -15,8 +15,9 @@
15 15 private static $dynamicShortcodes = null;
16 16
17 17 /**
18 18 * mappings of methods to parse the shortcode
19 + *
19 20 * @var array
20 21 */
21 22 private static $handlers = [
22 23 'ip' => 'parseIp',
@@ -41,24 +42,26 @@
41 42
42 43 'browser.name' => 'parseBrowserProperties',
43 44 'browser.platform' => 'parseBrowserProperties',
44 45
45 - 'get.param_name' => 'parseQueryParam'
46 + 'get.param_name' => 'parseRequestParam',
47 + 'random_string.param_name' => 'parseRandomString',
46 48 ];
47 49
48 50 /**
49 51 * Filter dynamic shortcodes in input value
50 - * @param string $value
52 + *
53 + * @param string $value
54 + *
51 55 * @return string
52 56 */
53 57 public static function filter($value, $form)
54 58 {
55 - if(strpos($value, '{ ') === 0) {
59 + if (0 === strpos($value, '{ ')) {
56 60 // it's the css
57 61 return $value;
58 62 }
59 63
60 -
61 64 if (is_null(static::$dynamicShortcodes)) {
62 65 static::$dynamicShortcodes = fluentFormEditorShortCodes();
63 66 }
64 67
@@ -69,65 +72,88 @@
69 72 return call_user_func_array(
70 73 [__CLASS__, static::$handlers[$handler]],
71 74 ['{' . $handler . '}', $form]
72 75 );
73 - } elseif (strpos($handler, 'get.') !== false) {
74 - return static::parseQueryParam($handler);
75 - } else if (strpos($handler, 'user.meta.') !== false) {
76 - $key = substr(str_replace(['{', '}'], '', $value), 10);
77 - $user = wp_get_current_user();
78 - if ($user) {
79 - $value = get_post_meta($user->ID, $key, true);
80 - if (!is_array($value) && !is_object($value)) {
81 - return $value;
82 - }
83 - }
84 - return '';
85 - } else if (strpos($handler, 'user.') !== false) {
86 - $value = self::parseUserProperties($handler);
87 - if (is_array($value) || is_object($value)) {
76 + }
77 +
78 + if (false !== strpos($handler, 'get.')) {
79 + return static::parseRequestParam($handler);
80 + }
81 + if (false !== strpos($handler, 'random_string.')) {
82 + return static::parseRandomString($handler);
83 + }
84 +
85 + if (false !== strpos($handler, 'user.')) {
86 + $parsedValue = self::parseUserProperties($handler);
87 + if (is_array($parsedValue) || is_object($parsedValue)) {
88 88 return '';
89 89 }
90 - return $value;
91 - } else if (strpos($handler, 'date.') !== false) {
92 - return self::parseDate($handler);
93 - } else if (strpos($handler, 'embed_post.meta.') !== false) {
90 + return esc_html($parsedValue);
91 + }
92 +
93 + if (false !== strpos($handler, 'date.')) {
94 + return esc_html(self::parseDate($handler));
95 + }
96 +
97 + if (false !== strpos($handler, 'embed_post.meta.')) {
94 98 $key = substr(str_replace(['{', '}'], '', $value), 16);
95 99 global $post;
96 100 if ($post) {
97 - $value = get_post_meta($post->ID, $key, true);
98 - if (!is_array($value) && !is_object($value)) {
99 - return $value;
101 + $metaValue = get_post_meta($post->ID, $key, true);
102 + if (!is_array($metaValue) && !is_object($metaValue)) {
103 + return esc_html($metaValue);
100 104 }
101 105 }
102 106 return '';
103 - } else if (strpos($handler, 'embed_post.') !== false) {
107 + }
108 +
109 + if (false !== strpos($handler, 'embed_post.')) {
104 110 return self::parsePostProperties($handler, $form);
105 - } else if (strpos($handler, 'cookie.') !== false) {
111 + }
112 +
113 + if (false !== strpos($handler, 'cookie.')) {
106 114 $scookieProperty = substr($handler, strlen('cookie.'));
107 - return ArrayHelper::get($_COOKIE, $scookieProperty);
108 - } else if (strpos($handler, 'dynamic.') !== false) {
115 + $cookieValue = array_key_exists($scookieProperty, $_COOKIE) ? sanitize_text_field(wp_unslash($_COOKIE[$scookieProperty])) : '';
116 +
117 + return esc_attr($cookieValue);
118 + }
119 +
120 + if (false !== strpos($handler, 'dynamic.')) {
109 121 $dynamicKey = substr($handler, strlen('dynamic.'));
110 122 // maybe has fallback value
111 123 $dynamicKey = explode('|', $dynamicKey);
112 124 $fallBack = '';
113 125 $ref = '';
114 - if(count($dynamicKey) > 1) {
126 + if (count($dynamicKey) > 1) {
115 127 $fallBack = $dynamicKey[1];
116 128 }
117 - $ref = $dynamicKey[0];
129 + if (isset($dynamicKey[0])) {
130 + $ref = $dynamicKey[0];
131 + }
118 132
119 - if($ref == 'payment_summary') {
120 - return '<div class="ff_dynamic_value ff_dynamic_payment_summary" data-ref="payment_summary"><div class="ff_payment_summary"></div><div class="ff_payment_summary_fallback">'.$fallBack.'</div></div>';
133 + if ('payment_summary' == $ref) {
134 + return fluentform_sanitize_html('<div class="ff_dynamic_value ff_dynamic_payment_summary" data-ref="payment_summary"><div class="ff_payment_summary"></div><div class="ff_payment_summary_fallback">' . $fallBack . '</div></div>');
121 135 }
122 136
123 - return '<span class="ff_dynamic_value" data-ref="'.$ref.'" data-fallback="'.$fallBack.'">'.$fallBack.'</span>';
124 - } else {
125 - // This can be the css
126 - $handlerValue = apply_filters('fluentform_editor_shortcode_callback_' . $handler, '{' . $handler . '}', $form);
127 - // In not found then return the original please
128 - $filteredValue = $handlerValue;
137 + return fluentform_sanitize_html('<span class="ff_dynamic_value" data-ref="' . $ref . '" data-fallback="' . $fallBack . '">' . $fallBack . '</span>');
129 138 }
139 +
140 + // if it's multi line then just return
141 + if (false !== strpos($handler, PHP_EOL)) { // most probably it's a css
142 + return '{' . $handler . '}';
143 + }
144 +
145 + $handlerArray = explode('.', $handler);
146 +
147 + if (count($handlerArray) > 1) {
148 + // it's a grouped handler
149 + $group = array_shift($handlerArray);
150 + $parsedValue = apply_filters('fluentform_editor_shortcode_callback_group_' . $group, '{' . $handler . '}', $form, $handlerArray);
151 + return apply_filters('fluentform/editor_shortcode_callback_group_' . $group, $parsedValue, $form, $handlerArray);
152 + }
153 +
154 + $parsedValue = apply_filters('fluentform_editor_shortcode_callback_' . $handler, '{' . $handler . '}', $form);
155 + return apply_filters('fluentform/editor_shortcode_callback_' . $handler, $parsedValue, $form);
130 156 }
131 157
132 158 return $filteredValue;
133 159 }
@@ -132,10 +158,33 @@
132 158 return $filteredValue;
133 159 }
134 160
135 161 /**
162 + * Parse request query param.
163 + *
164 + * @param string $value
165 + * @param \stdClass $form
166 + *
167 + * @return string
168 + */
169 + public static function parseRequestParam($value)
170 + {
171 + $exploded = explode('.', $value);
172 + $param = array_pop($exploded);
173 + $value = wpFluentForm('request')->get($param);
174 +
175 + if (null === $value || '' === $value) {
176 + return '';
177 + }
178 +
179 + return esc_attr(Helper::flattenRequestValue($value));
180 + }
181 +
182 + /**
136 183 * Parse the curly braced shortcode into array
137 - * @param string $value
184 + *
185 + * @param string $value
186 + *
138 187 * @return mixed
139 188 */
140 189 public static function parseValue($value)
141 190 {
@@ -142,9 +191,9 @@
142 191 if (!is_array($value)) {
143 192 return preg_split(
144 193 '/{(.*?)}/',
145 194 $value,
146 - null,
195 + -1,
147 196 PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
148 197 );
149 198 }
150 199
@@ -156,9 +205,11 @@
156 205 */
157 206
158 207 /**
159 208 * Parse loggedin user properties
160 - * @param string $value
209 + *
210 + * @param string $value
211 + *
161 212 * @return string
162 213 */
163 214 private static function parseUserProperties($value, $form = null)
164 215 {
@@ -163,9 +214,29 @@
163 214 private static function parseUserProperties($value, $form = null)
164 215 {
165 216 if ($user = wp_get_current_user()) {
166 217 $prop = substr(str_replace(['{', '}'], '', $value), 5);
167 - return $user->{$prop};
218 +
219 + if (false !== strpos($prop, 'meta.')) {
220 + $metaKey = substr($prop, strlen('meta.'));
221 + $metaKey = sanitize_text_field($metaKey);
222 + if (empty($metaKey) || ShortCodeParser::isDeniedUserProperty($metaKey)) {
223 + return '';
224 + }
225 + $userId = $user->ID;
226 + $data = get_user_meta($userId, $metaKey, true);
227 + $data = Helper::safeUnserialize($data);
228 + if (!is_array($data)) {
229 + return esc_html($data);
230 + }
231 + return esc_html(implode(',', $data));
232 + }
233 +
234 + if (ShortCodeParser::isDeniedUserProperty($prop)) {
235 + return '';
236 + }
237 +
238 + return esc_html($user->{$prop});
168 239 }
169 240
170 241 return '';
171 242 }
@@ -170,10 +241,12 @@
170 241 return '';
171 242 }
172 243
173 244 /**
174 - * Parse loggedin user properties
175 - * @param string $value
245 + * Parse embedded post properties
246 + *
247 + * @param string $value
248 + *
176 249 * @return string
177 250 */
178 251 private static function parsePostProperties($value, $form = null)
179 252 {
@@ -181,37 +254,70 @@
181 254 if (!$post) {
182 255 return '';
183 256 }
184 257
185 - $prop = substr(str_replace(['{', '}'], '', $value), 11);
186 - if ($prop == 'permalink') {
187 - return htmlspecialchars(site_url(wp_unslash($_SERVER['REQUEST_URI'])));
258 + $key = $prop = substr(str_replace(['{', '}'], '', $value), 11);
259 +
260 + if (false !== strpos($key, 'author.')) {
261 + $authorProperty = substr($key, strlen('author.'));
262 + $authorId = $post->post_author;
263 + if ($authorId && !ShortCodeParser::isDeniedUserProperty($authorProperty)) {
264 + $data = get_the_author_meta($authorProperty, $authorId);
265 + if (!is_array($data)) {
266 + return esc_html($data);
267 + }
268 + }
269 + return '';
270 + } elseif (false !== strpos($key, 'meta.')) {
271 + $metaKey = substr($key, strlen('meta.'));
272 + $postId = $post->ID;
273 + $data = get_post_meta($postId, $metaKey, true);
274 + if (!is_array($data)) {
275 + return esc_html($data);
276 + }
277 + return '';
278 + } elseif (false !== strpos($key, 'acf.')) {
279 + $metaKey = substr($key, strlen('acf.'));
280 + $postId = $post->ID;
281 + if (function_exists('get_field')) {
282 + $data = get_field($metaKey, $postId, true);
283 + if (!is_array($data)) {
284 + return esc_html($data);
285 + }
286 + return '';
287 + }
188 288 }
189 - if (property_exists($post, $prop)) {
190 - return $post->{$prop};
289 +
290 + if ('permalink' == $prop) {
291 + return site_url(esc_attr(urldecode(wpFluentForm('request')->server('REQUEST_URI'))));
191 292 }
293 +
294 + if ('post_password' !== $prop && property_exists($post, $prop)) {
295 + return esc_html($post->{$prop});
296 + }
192 297 return '';
193 298 }
194 299
195 -
196 300 /**
197 301 * Parse WP Properties
198 - * @param string $value
302 + *
303 + * @param string $value
304 + *
199 305 * @return string
200 306 */
201 307 private static function parseWPProperties($value, $form = null)
202 308 {
203 - if ($value == '{wp.admin_email}') {
204 - return get_option('admin_email');
309 + if ('{wp.admin_email}' == $value) {
310 + return esc_html(get_option('admin_email'));
205 311 }
206 - if ($value == '{wp.site_url}') {
207 - return site_url();
312 + if ('{wp.site_url}' == $value) {
313 + return esc_url(site_url());
208 314 }
209 - if ($value == '{wp.site_title}') {
210 - return get_option('blogname');
315 + if ('{wp.site_title}' == $value) {
316 + return esc_html(get_option('blogname'));
211 317 }
212 - if ($value == '{http_referer}') {
213 - return wp_get_referer();
318 + if ('{http_referer}' == $value) {
319 + return esc_url(wp_get_referer());
214 320 }
215 321
216 322 return '';
217 323 }
@@ -217,18 +323,20 @@
217 323 }
218 324
219 325 /**
220 326 * Parse browser/user-agent properties
221 - * @param string $value
327 + *
328 + * @param string $value
329 + *
222 330 * @return string
223 331 */
224 332 private static function parseBrowserProperties($value, $form = null)
225 333 {
226 - $browser = new Browser;
227 - if ($value == '{browser.name}') {
228 - return $browser->getBrowser();
229 - } elseif ($value == '{browser.platform}') {
230 - return $browser->getPlatform();
334 + $browser = new Browser();
335 + if ('{browser.name}' == $value) {
336 + return esc_html($browser->getBrowser());
337 + } elseif ('{browser.platform}' == $value) {
338 + return esc_html($browser->getPlatform());
231 339 }
232 340
233 341 return '';
234 342 }
@@ -234,20 +342,25 @@
234 342 }
235 343
236 344 /**
237 345 * Parse ip shortcode
238 - * @param string $value
346 + *
347 + * @param string $value
348 + *
239 349 * @return string
240 350 */
241 351 private static function parseIp($value, $form = null)
242 352 {
243 - $ip = Request::getIp();
244 - return $ip ? $ip : $value;
353 + $rawIp = wpFluentForm('request')->getIp();
354 + $ip = sanitize_text_field($rawIp);
355 + return $ip ? esc_html($ip) : $value;
245 356 }
246 357
247 358 /**
248 359 * Parse date shortcode
249 - * @param string $value
360 + *
361 + * @param string $value
362 + *
250 363 * @return string
251 364 */
252 365 private static function parseDate($value, $form = null)
253 366 {
@@ -252,16 +365,17 @@
252 365 private static function parseDate($value, $form = null)
253 366 {
254 367 $format = substr(str_replace(['}', '{'], '', $value), 5);
255 368 $date = date($format, strtotime(current_time('mysql')));
256 - return $date ? $date : '';
369 + return $date ? esc_html($date) : '';
257 370 }
258 371
259 372 /**
260 373 * Parse request query param.
261 374 *
262 - * @param string $value
263 - * @param \stdClass $form
375 + * @param string $value
376 + * @param \stdClass $form
377 + *
264 378 * @return string
265 379 */
266 380 public static function parseQueryParam($value)
267 381 {
@@ -266,14 +380,33 @@
266 380 public static function parseQueryParam($value)
267 381 {
268 382 $exploded = explode('.', $value);
269 383 $param = array_pop($exploded);
270 - if(!isset($_REQUEST[$param])) {
384 + $value = wpFluentForm('request')->get($param);
385 +
386 + if (!$value) {
271 387 return '';
272 388 }
273 - $value = $_REQUEST[$param];
274 - if(is_array($value)) {
389 +
390 + if (is_array($value)) {
275 391 return sanitize_textarea_field(implode(', ', $value));
276 392 }
393 +
277 394 return sanitize_textarea_field($value);
395 + }
396 +
397 + /**
398 + * Generate random a string with prefix
399 + *
400 + * @param $value
401 + *
402 + * @return string
403 + */
404 + public static function parseRandomString($value)
405 + {
406 + $exploded = explode('.', $value);
407 + $prefix = array_pop($exploded);
408 + $value = $prefix . uniqid();
409 +
410 + return esc_html(apply_filters('fluentform/shortcode_parser_callback_random_string', $value, $prefix, new static()));
278 411 }
279 412 }