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 / EditorShortcodeParser.php

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

413 lines 12.3 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;
4
5 use FluentForm\App\Helpers\Helper;
6 use FluentForm\App\Services\Browser\Browser;
7
8 class EditorShortcodeParser
9 {
10 /**
11 * Available dynamic short codes
12 *
13 * @var null
14 */
15 private static $dynamicShortcodes = null;
16
17 /**
18 * mappings of methods to parse the shortcode
19 *
20 * @var array
21 */
22 private static $handlers = [
23 'ip' => 'parseIp',
24 'date.m/d/Y' => 'parseDate',
25 'date.d/m/Y' => 'parseDate',
26
27 'embed_post.ID' => 'parsePostProperties',
28 'embed_post.post_title' => 'parsePostProperties',
29 'embed_post.permalink' => 'parsePostProperties',
30 'http_referer' => 'parseWPProperties',
31
32 'wp.admin_email' => 'parseWPProperties',
33 'wp.site_url' => 'parseWPProperties',
34 'wp.site_title' => 'parseWPProperties',
35
36 'user.ID' => 'parseUserProperties',
37 'user.display_name' => 'parseUserProperties',
38 'user.first_name' => 'parseUserProperties',
39 'user.last_name' => 'parseUserProperties',
40 'user.user_email' => 'parseUserProperties',
41 'user.user_login' => 'parseUserProperties',
42
43 'browser.name' => 'parseBrowserProperties',
44 'browser.platform' => 'parseBrowserProperties',
45
46 'get.param_name' => 'parseRequestParam',
47 'random_string.param_name' => 'parseRandomString',
48 ];
49
50 /**
51 * Filter dynamic shortcodes in input value
52 *
53 * @param string $value
54 *
55 * @return string
56 */
57 public static function filter($value, $form)
58 {
59 if (0 === strpos($value, '{ ')) {
60 // it's the css
61 return $value;
62 }
63
64 if (is_null(static::$dynamicShortcodes)) {
65 static::$dynamicShortcodes = fluentFormEditorShortCodes();
66 }
67
68 $filteredValue = '';
69
70 foreach (static::parseValue($value) as $handler) {
71 if (isset(static::$handlers[$handler])) {
72 return call_user_func_array(
73 [__CLASS__, static::$handlers[$handler]],
74 ['{' . $handler . '}', $form]
75 );
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 return '';
89 }
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.')) {
98 $key = substr(str_replace(['{', '}'], '', $value), 16);
99 global $post;
100 if ($post) {
101 $metaValue = get_post_meta($post->ID, $key, true);
102 if (!is_array($metaValue) && !is_object($metaValue)) {
103 return esc_html($metaValue);
104 }
105 }
106 return '';
107 }
108
109 if (false !== strpos($handler, 'embed_post.')) {
110 return self::parsePostProperties($handler, $form);
111 }
112
113 if (false !== strpos($handler, 'cookie.')) {
114 $scookieProperty = substr($handler, strlen('cookie.'));
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.')) {
121 $dynamicKey = substr($handler, strlen('dynamic.'));
122 // maybe has fallback value
123 $dynamicKey = explode('|', $dynamicKey);
124 $fallBack = '';
125 $ref = '';
126 if (count($dynamicKey) > 1) {
127 $fallBack = $dynamicKey[1];
128 }
129 if (isset($dynamicKey[0])) {
130 $ref = $dynamicKey[0];
131 }
132
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>');
135 }
136
137 return fluentform_sanitize_html('<span class="ff_dynamic_value" data-ref="' . $ref . '" data-fallback="' . $fallBack . '">' . $fallBack . '</span>');
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);
156 }
157
158 return $filteredValue;
159 }
160
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 /**
183 * Parse the curly braced shortcode into array
184 *
185 * @param string $value
186 *
187 * @return mixed
188 */
189 public static function parseValue($value)
190 {
191 if (!is_array($value)) {
192 return preg_split(
193 '/{(.*?)}/',
194 $value,
195 -1,
196 PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
197 );
198 }
199
200 return $value;
201 }
202
203 /**
204 * Declare all parsers and must be [private] static methods
205 */
206
207 /**
208 * Parse loggedin user properties
209 *
210 * @param string $value
211 *
212 * @return string
213 */
214 private static function parseUserProperties($value, $form = null)
215 {
216 if ($user = wp_get_current_user()) {
217 $prop = substr(str_replace(['{', '}'], '', $value), 5);
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});
239 }
240
241 return '';
242 }
243
244 /**
245 * Parse embedded post properties
246 *
247 * @param string $value
248 *
249 * @return string
250 */
251 private static function parsePostProperties($value, $form = null)
252 {
253 global $post;
254 if (!$post) {
255 return '';
256 }
257
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 }
288 }
289
290 if ('permalink' == $prop) {
291 return site_url(esc_attr(urldecode(wpFluentForm('request')->server('REQUEST_URI'))));
292 }
293
294 if ('post_password' !== $prop && property_exists($post, $prop)) {
295 return esc_html($post->{$prop});
296 }
297 return '';
298 }
299
300 /**
301 * Parse WP Properties
302 *
303 * @param string $value
304 *
305 * @return string
306 */
307 private static function parseWPProperties($value, $form = null)
308 {
309 if ('{wp.admin_email}' == $value) {
310 return esc_html(get_option('admin_email'));
311 }
312 if ('{wp.site_url}' == $value) {
313 return esc_url(site_url());
314 }
315 if ('{wp.site_title}' == $value) {
316 return esc_html(get_option('blogname'));
317 }
318 if ('{http_referer}' == $value) {
319 return esc_url(wp_get_referer());
320 }
321
322 return '';
323 }
324
325 /**
326 * Parse browser/user-agent properties
327 *
328 * @param string $value
329 *
330 * @return string
331 */
332 private static function parseBrowserProperties($value, $form = null)
333 {
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());
339 }
340
341 return '';
342 }
343
344 /**
345 * Parse ip shortcode
346 *
347 * @param string $value
348 *
349 * @return string
350 */
351 private static function parseIp($value, $form = null)
352 {
353 $rawIp = wpFluentForm('request')->getIp();
354 $ip = sanitize_text_field($rawIp);
355 return $ip ? esc_html($ip) : $value;
356 }
357
358 /**
359 * Parse date shortcode
360 *
361 * @param string $value
362 *
363 * @return string
364 */
365 private static function parseDate($value, $form = null)
366 {
367 $format = substr(str_replace(['}', '{'], '', $value), 5);
368 $date = date($format, strtotime(current_time('mysql')));
369 return $date ? esc_html($date) : '';
370 }
371
372 /**
373 * Parse request query param.
374 *
375 * @param string $value
376 * @param \stdClass $form
377 *
378 * @return string
379 */
380 public static function parseQueryParam($value)
381 {
382 $exploded = explode('.', $value);
383 $param = array_pop($exploded);
384 $value = wpFluentForm('request')->get($param);
385
386 if (!$value) {
387 return '';
388 }
389
390 if (is_array($value)) {
391 return sanitize_textarea_field(implode(', ', $value));
392 }
393
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()));
411 }
412 }
413