PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.13
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.13
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 / ShortCodeParser.php

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

712 lines 26.8 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\Models\SubmissionMeta;
6 use FluentForm\App\Modules\Form\FormDataParser;
7 use FluentForm\App\Modules\Form\FormFieldsParser;
8 use FluentForm\App\Services\Browser\Browser;
9 use FluentForm\Framework\Helpers\ArrayHelper;
10 use FluentForm\App\Helpers\Helper;
11
12 class ShortCodeParser
13 {
14 protected static $form = null;
15
16 protected static $entry = null;
17
18 protected static $browser = null;
19
20 protected static $formFields = null;
21
22 protected static $provider = null;
23
24 protected static $store = [
25 'inputs' => null,
26 'original_inputs' => null,
27 'user' => null,
28 'post' => null,
29 'other' => null,
30 'submission' => null,
31 ];
32
33 public static function parse($parsable, $entryId, $data = [], $form = null, $isUrl = false, $providerOrIsHTML = false, $htmlSanitized = false)
34 {
35 try {
36 static::setDependencies($entryId, $data, $form, $providerOrIsHTML);
37
38 if (is_array($parsable)) {
39 return static::parseShortCodeFromArray($parsable, $isUrl, $providerOrIsHTML, $htmlSanitized);
40 }
41
42 return static::parseShortCodeFromString($parsable, $isUrl, $providerOrIsHTML, $htmlSanitized);
43 } catch (\Exception $e) {
44 if (defined('WP_DEBUG') && WP_DEBUG) {
45 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Debug logging only when WP_DEBUG is enabled, helps developers troubleshoot shortcode parsing issues
46 error_log($e->getTraceAsString());
47 }
48 return '';
49 }
50 }
51
52 protected static function setDependencies($entry, $data, $form, $provider)
53 {
54 static::setEntry($entry);
55 static::setData($data);
56 static::setForm($form);
57 static::$provider = $provider;
58 }
59
60 protected static function setEntry($entry)
61 {
62 static::$entry = $entry;
63 }
64
65 protected static function setdata($data)
66 {
67 if (!is_null($data)) {
68 static::$store['inputs'] = $data;
69 static::$store['original_inputs'] = $data;
70 } else {
71 $data = json_decode(static::getEntry()->response, true);
72 static::$store['inputs'] = $data;
73 static::$store['original_inputs'] = $data;
74 }
75 }
76
77 protected static function setForm($form)
78 {
79 if (!is_null($form)) {
80 static::$form = $form;
81 } else {
82 static::$form = static::getEntry()->form_id;
83 }
84 }
85
86 protected static function parseShortCodeFromArray($parsable, $isUrl = false, $provider = false, $htmlSanitized = false)
87 {
88 foreach ($parsable as $key => $value) {
89 if (is_array($value)) {
90 $parsable[$key] = static::parseShortCodeFromArray($value, $isUrl, $provider, $htmlSanitized);
91 } else {
92 $isHtml = false;
93 if ($provider) {
94 $isHtml = apply_filters_deprecated(
95 'ff_will_return_html',
96 [
97 false,
98 $provider,
99 $key,
100 ],
101 FLUENTFORM_FRAMEWORK_UPGRADE,
102 'fluentform/will_return_html',
103 'Use fluentform/will_return_html instead of ff_will_return_html.'
104 );
105 $isHtml = apply_filters('fluentform/will_return_html', $isHtml, $provider, $key);
106 }
107 $parsable[$key] = static::parseShortCodeFromString($value, $isUrl, $isHtml, $htmlSanitized);
108 }
109 }
110
111 return $parsable;
112 }
113
114 protected static function parseShortCodeFromString($parsable, $isUrl = false, $isHtml = false, $htmlSanitized = false)
115 {
116 if ('0' === $parsable) {
117 return $parsable;
118 }
119
120 if (!$parsable) {
121 return '';
122 }
123 return preg_replace_callback('/{+(.*?)}/', function ($matches) use ($isUrl, $isHtml, $htmlSanitized) {
124 $value = '';
125 if (false !== strpos($matches[1], 'inputs.')) {
126 $formProperty = substr($matches[1], strlen('inputs.'));
127 $value = static::getFormData($formProperty, $isHtml);
128 } elseif (false !== strpos($matches[1], 'labels.')) {
129 $formLabelProperty = substr($matches[1], strlen('labels.'));
130 $value = static::getFormLabelData($formLabelProperty);
131 } elseif (false !== strpos($matches[1], 'user.')) {
132 $userProperty = substr($matches[1], strlen('user.'));
133 $value = static::getUserData($userProperty);
134 } elseif (false !== strpos($matches[1], 'embed_post.')) {
135 $postProperty = substr($matches[1], strlen('embed_post.'));
136 $value = static::getPostData($postProperty);
137 } elseif (false !== strpos($matches[1], 'wp.')) {
138 $wpProperty = substr($matches[1], strlen('wp.'));
139 $value = static::getWPData($wpProperty);
140 } elseif (false !== strpos($matches[1], 'submission.')) {
141 $submissionProperty = substr($matches[1], strlen('submission.'));
142 $value = static::getSubmissionData($submissionProperty);
143 } elseif (false !== strpos($matches[1], 'cookie.')) {
144 $scookieProperty = substr($matches[1], strlen('cookie.'));
145 $value = array_key_exists($scookieProperty, $_COOKIE) ? sanitize_text_field(wp_unslash($_COOKIE[$scookieProperty])) : '';
146 } elseif (false !== strpos($matches[1], 'payment.')) {
147 $property = substr($matches[1], strlen('payment.'));
148 $deprecatedValue = apply_filters_deprecated(
149 'fluentform_payment_smartcode', [
150 '',
151 $property,
152 self::getInstance(),
153 ],
154 FLUENTFORM_FRAMEWORK_UPGRADE,
155 'fluentform/payment_smartcode',
156 'Use fluentform/payment_smartcode instead of fluentform_payment_smartcode.'
157 );
158
159 $value = apply_filters('fluentform/payment_smartcode', $deprecatedValue, $property, self::getInstance());
160 } else {
161 $value = static::getOtherData($matches[1]);
162 }
163
164 if (is_array($value)) {
165 $value = fluentImplodeRecursive(', ', $value);
166 }
167
168 if ($isUrl) {
169 // Don't encode values that are already complete URLs like {wp.site_url}
170 if (!preg_match('#^https?://#i', (string) $value)) {
171 $value = rawurlencode($value);
172 }
173 } elseif ($htmlSanitized) {
174 $value = fluentform_sanitize_html($value);
175 }
176
177 return $value;
178 }, $parsable);
179 }
180
181 protected static function getFormData($key, $isHtml = false)
182 {
183 if (strpos($key, '.label')) {
184 $key = str_replace('.label', '', $key);
185 $isHtml = true;
186 }
187
188 if (strpos($key, '.value')) {
189 $key = str_replace('.value', '', $key);
190 return ArrayHelper::get(static::$store['original_inputs'], $key);
191 }
192
193 if (strpos($key, '.') && !isset(static::$store['inputs'][$key])) {
194 return ArrayHelper::get(
195 static::$store['original_inputs'],
196 $key,
197 ''
198 );
199 }
200
201 if (!isset(static::$store['inputs'][$key])) {
202 static::$store['inputs'][$key] = ArrayHelper::get(
203 static::$store['inputs'],
204 $key,
205 ''
206 );
207 }
208
209 if (is_null(static::$formFields)) {
210 static::$formFields = FormFieldsParser::getShortCodeInputs(
211 static::getForm(),
212 ['admin_label', 'attributes', 'options', 'raw']
213 );
214 }
215
216 $field = ArrayHelper::get(static::$formFields, $key, '');
217
218 if (!$field) {
219 return '';
220 }
221
222 if ($isHtml) {
223 $originalInput = ArrayHelper::get(static::$store['original_inputs'], $key, '');
224 $originalInput = apply_filters_deprecated(
225 'fluentform_response_render_' . $field['element'],
226 [
227 $originalInput,
228 $field,
229 static::getForm()->id,
230 $isHtml,
231 ],
232 FLUENTFORM_FRAMEWORK_UPGRADE,
233 'fluentform/response_render_' . $field['element'],
234 'Use fluentform/response_render_' . $field['element'] . ' instead of fluentform_response_render_' . $field['element']
235 );
236 return apply_filters(
237 'fluentform/response_render_' . $field['element'],
238 $originalInput,
239 $field,
240 static::getForm()->id,
241 $isHtml
242 );
243 }
244
245 static::$store['inputs'][$key] = apply_filters_deprecated(
246 'fluentform_response_render_' . $field['element'],
247 [
248 static::$store['inputs'][$key],
249 $field,
250 static::getForm()->id,
251 $isHtml,
252 ],
253 FLUENTFORM_FRAMEWORK_UPGRADE,
254 'fluentform/response_render_' . $field['element'],
255 'Use fluentform/response_render_' . $field['element'] . ' instead of fluentform_response_render_' . $field['element']
256 );
257
258 return static::$store['inputs'][$key] = apply_filters(
259 'fluentform/response_render_' . $field['element'],
260 static::$store['inputs'][$key],
261 $field,
262 static::getForm()->id,
263 $isHtml
264 );
265 }
266
267 protected static function getFormLabelData($key)
268 {
269 if (is_null(static::$formFields)) {
270 static::$formFields = FormFieldsParser::getShortCodeInputs(
271 static::getForm(),
272 ['admin_label', 'attributes', 'options', 'raw', 'label']
273 );
274 }
275
276 // Resolve global validation messages {labels.current_field} shortcode.
277 // Current field name attribute was setted as inputs data key 'current_field'.
278 if ('current_field' === $key && $currentFieldName = ArrayHelper::get(static::$store['inputs'], $key)) {
279 $currentFieldName = str_replace(['[', ']'], ['.', ''], $currentFieldName);
280 $key = $currentFieldName;
281 }
282 $inputLabel = ArrayHelper::get(ArrayHelper::get(static::$formFields, $key, []), 'label', '');
283 $inputLabel = str_replace(['[', ']'], '', $inputLabel);
284 $keys = explode('.', $key);
285 if (count($keys) > 1) {
286 $parentKey = array_shift($keys);
287 $inputLabel = str_replace($parentKey, '', $inputLabel);
288 }
289 if (empty($inputLabel)) {
290 $inputLabel = ArrayHelper::get(ArrayHelper::get(static::$formFields, $key, []), 'admin_label', '');
291 }
292 if (empty($inputLabel) && isset($parentKey) && $parentKey) {
293 $inputLabel = ArrayHelper::get(ArrayHelper::get(static::$formFields, $parentKey, []), 'label', '');
294 $key = $parentKey;
295 }
296
297 return apply_filters('fluentform/input_label_shortcode', $inputLabel, $key, static::getForm());
298 }
299
300 protected static function getUserData($key)
301 {
302 if (is_null(static::$store['user'])) {
303 static::$store['user'] = wp_get_current_user();
304 }
305
306 $user = static::$store['user'];
307
308 // SECURITY (FINDING-11): `$user->{$key}` reads straight from the wp_users row via
309 // WP_User::__get, so an author-controlled {user.user_pass} (or {user.user_activation_key})
310 // would exfiltrate the *submitting* user's password hash / reset token in a notification.
311 // Allow only a fixed set of safe profile fields; resolve anything else from user meta,
312 // which never contains the sensitive wp_users columns.
313 $allowed = [
314 'ID', 'id', 'display_name', 'first_name', 'last_name', 'user_email',
315 'user_login', 'user_nicename', 'nickname', 'user_url', 'description', 'roles',
316 'user_registered', // non-sensitive wp_users column; keep {user.user_registered} working
317 ];
318 if (in_array($key, $allowed, true)) {
319 return $user->{$key};
320 }
321
322 $key = (string) $key;
323 if ($user->ID && '' !== $key) {
324 return get_user_meta($user->ID, $key, true);
325 }
326
327 return '';
328 }
329
330 protected static function getPostData($key)
331 {
332 if (is_null(static::$store['post'])) {
333 $postId = static::$store['inputs']['__fluent_form_embded_post_id'];
334 static::$store['post'] = get_post($postId);
335 if (is_null(static::$store['post'])) {
336 return '';
337 }
338 static::$store['post']->permalink = get_the_permalink(static::$store['post']);
339 }
340
341 if (false !== strpos($key, 'author.')) {
342 $authorProperty = substr($key, strlen('author.'));
343 $authorId = static::$store['post']->post_author;
344 if ($authorId) {
345 $data = get_the_author_meta($authorProperty, $authorId);
346 if (!is_array($data)) {
347 return $data;
348 }
349 }
350 return '';
351 } elseif (false !== strpos($key, 'meta.')) {
352 $metaKey = substr($key, strlen('meta.'));
353 $postId = static::$store['post']->ID;
354 $data = get_post_meta($postId, $metaKey, true);
355 if (!is_array($data)) {
356 return $data;
357 }
358 return '';
359 } elseif (false !== strpos($key, 'acf.')) {
360 $metaKey = substr($key, strlen('acf.'));
361 $postId = static::$store['post']->ID;
362 if (function_exists('get_field')) {
363 $data = get_field($metaKey, $postId, true);
364 if (!is_array($data)) {
365 return $data;
366 }
367 return '';
368 }
369 }
370
371 return static::$store['post']->{$key};
372 }
373
374 protected static function getWPData($key)
375 {
376 if ('admin_email' == $key) {
377 return get_option('admin_email');
378 }
379 if ('site_url' == $key) {
380 return site_url();
381 }
382 if ('site_title' == $key) {
383 return get_option('blogname');
384 }
385 return $key;
386 }
387
388 protected static function getSubmissionData($key)
389 {
390 $entry = static::getEntry();
391
392 if (empty($entry->id)) {
393 return '';
394 }
395
396 $columns = Helper::getEntryColumns($entry);
397
398 if (array_key_exists($key, $columns)) {
399 if ('total_paid' == $key || 'payment_total' == $key) {
400 return round($entry->{$key} / 100, 2);
401 }
402 if ('payment_method' == $key && 'test' == $entry->{$key}) {
403 return __('Offline', 'fluentform');
404 }
405 return $entry->{$key};
406 }
407 if ('admin_view_url' == $key) {
408 return admin_url('admin.php?page=fluent_forms&route=entries&form_id=' . $entry->form_id . '#/entries/' . $entry->id);
409 } elseif ('entry_uid' == $key) {
410 return static::getShortEntryUid($entry);
411 } elseif ('entry_uid_link' == $key) {
412 return static::getEntryUidLink($entry);
413 } elseif (false !== strpos($key, 'meta.')) {
414 $metaKey = substr($key, strlen('meta.'));
415 $data = Helper::getSubmissionMeta($entry->id, $metaKey);
416 if (!is_array($data)) {
417 return $data;
418 }
419 return '';
420 }
421
422 return '';
423 }
424
425 protected static function getOtherData($key)
426 {
427 if (0 === strpos($key, 'date.')) {
428 $format = str_replace('date.', '', $key);
429 return date($format, strtotime(current_time('mysql')));
430 } elseif ('admin_email' == $key) {
431 return get_option('admin_email', false);
432 } elseif ('ip' == $key) {
433 return static::getRequest()->getIp();
434 } elseif ('browser.platform' == $key) {
435 return static::getUserAgent()->getPlatform();
436 } elseif ('browser.name' == $key) {
437 return static::getUserAgent()->getBrowser();
438 } elseif (in_array($key, ['all_data', 'all_data_without_hidden_fields'])) {
439 $formFields = FormFieldsParser::getEntryInputs(static::getForm());
440 $inputLabels = FormFieldsParser::getAdminLabels(static::getForm(), $formFields);
441 $response = FormDataParser::parseFormSubmission(static::getEntry(), static::getForm(), $formFields, true);
442
443 $status = apply_filters_deprecated(
444 'fluentform_all_data_skip_password_field',
445 [
446 __return_true(),
447 ],
448 FLUENTFORM_FRAMEWORK_UPGRADE,
449 'fluentform/all_data_skip_password_field',
450 'Use fluentform/all_data_skip_password_field instead of fluentform_all_data_skip_password_field.'
451 );
452
453 if (apply_filters('fluentform/all_data_skip_password_field', $status)) {
454 $passwords = FormFieldsParser::getInputsByElementTypes(static::getForm(), ['input_password']);
455 if (is_array($passwords) && !empty($passwords)) {
456 $user_inputs = $response->user_inputs;
457 ArrayHelper::forget($user_inputs, array_keys($passwords));
458 $response->user_inputs = $user_inputs;
459 }
460 }
461
462 $hideHiddenField = true;
463 $hideHiddenField = apply_filters_deprecated(
464 'fluentform_all_data_without_hidden_fields',
465 [
466 $hideHiddenField,
467 ],
468 FLUENTFORM_FRAMEWORK_UPGRADE,
469 'fluentform/all_data_without_hidden_fields',
470 'Use fluentform/all_data_without_hidden_fields instead of fluentform_all_data_without_hidden_fields.'
471 );
472 $skipHiddenFields = ('all_data_without_hidden_fields' == $key) &&
473 apply_filters('fluentform/all_data_without_hidden_fields', $hideHiddenField);
474
475 if ($skipHiddenFields) {
476 $hiddenFields = FormFieldsParser::getInputsByElementTypes(static::getForm(), ['input_hidden']);
477 if (is_array($hiddenFields) && !empty($hiddenFields)) {
478 ArrayHelper::forget($response->user_inputs, array_keys($hiddenFields));
479 }
480 }
481
482 $html = '<table class="ff_all_data" width="600" cellpadding="0" cellspacing="0"><tbody>';
483 foreach ($inputLabels as $inputKey => $label) {
484 if (array_key_exists($inputKey, $response->user_inputs) && '' !== ArrayHelper::get($response->user_inputs, $inputKey)) {
485 $data = ArrayHelper::get($response->user_inputs, $inputKey);
486 if (is_array($data) || is_object($data)) {
487 continue;
488 }
489 // $label is admin-set, $data is already sanitized via fluentFormSanitizer() on submission insert
490 $html .= '<tr class="field-label"><th style="padding: 6px 12px; background-color: #f8f8f8; text-align: left;"><strong>' . $label . '</strong></th></tr><tr class="field-value"><td style="padding: 6px 12px 12px 12px;">' . $data . '</td></tr>';
491 }
492 }
493
494 $html .= '</tbody></table>';
495 $html = apply_filters_deprecated(
496 'fluentform_all_data_shortcode_html',
497 [
498 $html,
499 $formFields,
500 $inputLabels,
501 $response,
502 ],
503 FLUENTFORM_FRAMEWORK_UPGRADE,
504 'fluentform/all_data_shortcode_html',
505 'Use fluentform/all_data_shortcode_html instead of fluentform_all_data_shortcode_html.'
506 );
507 return apply_filters('fluentform/all_data_shortcode_html', $html, $formFields, $inputLabels, $response);
508 } elseif ('http_referer' === $key) {
509 return wp_get_referer();
510 } elseif (0 === strpos($key, 'pdf.download_link.')) {
511 $key = apply_filters_deprecated(
512 'fluentform_shortcode_parser_callback_pdf.download_link.public',
513 [
514 $key, static::getInstance(),
515 ],
516 FLUENTFORM_FRAMEWORK_UPGRADE,
517 'fluentform/shortcode_parser_callback_pdf.download_link.public',
518 'Use fluentform/shortcode_parser_callback_pdf.download_link.public instead of fluentform_shortcode_parser_callback_pdf.download_link.public.'
519 );
520 return apply_filters('fluentform/shortcode_parser_callback_pdf.download_link.public', $key, static::getInstance());
521 } elseif (false !== strpos($key, 'random_string.')) {
522 $exploded = explode('.', $key);
523 $prefix = array_pop($exploded);
524 $value = $prefix . uniqid();
525
526 return apply_filters('fluentform/shortcode_parser_callback_random_string', $value, $prefix, static::getInstance());
527 } elseif ('form_title' == $key) {
528 return static::getForm()->title;
529 } elseif (false !== strpos($key, 'chat_gpt_response.')) {
530 if (defined('FLUENTFORMPRO') && class_exists('\FluentFormPro\classes\Chat\ChatFieldController')) {
531 $exploded = explode('.', $key);
532 $prefix = array_pop($exploded);
533 if (!$prefix) {
534 return '';
535 }
536 $exploded = explode('_', $prefix);
537 $formId = reset($exploded);
538 $feedId = end($exploded);
539 $chatGPT = new \FluentFormPro\classes\Chat\ChatFieldController(wpFluentForm());
540 if ($chatGPT->api->isApiEnabled()) {
541 $entry = static::getEntry();
542 $lastResponse = SubmissionMeta::retrieve("chat_gpt_response_{$feedId}", $entry->id);
543 if (!$lastResponse) {
544 $response = $chatGPT->chatGPTSubmissionMessageHandler($formId, $feedId, static::getInstance());
545 SubmissionMeta::persist($entry->id, "chat_gpt_response_{$feedId}", $response, $formId);
546 return $response;
547 }
548 return $lastResponse;
549 }
550 }
551 return '';
552 }
553
554 // if it's multi line then just return
555 if (false !== strpos($key, PHP_EOL)) { // most probably it's a css
556 return '{' . $key . '}';
557 }
558
559 $groups = explode('.', $key);
560 if (count($groups) > 1) {
561 $group = array_shift($groups);
562 $property = implode('.', $groups);
563 $handlerValue = apply_filters_deprecated(
564 'fluentform_smartcode_group_' . $group,
565 [
566 $property,
567 static::getInstance(),
568 ],
569 FLUENTFORM_FRAMEWORK_UPGRADE,
570 'fluentform/smartcode_group_' . $group,
571 'Use fluentform/smartcode_group_' . $group . ' instead of fluentform_smartcode_group_' . $group
572 );
573
574 $handlerValue = apply_filters('fluentform/smartcode_group_' . $group, $handlerValue, static::getInstance());
575 if ($handlerValue != $property) {
576 return $handlerValue;
577 }
578 }
579
580 // This fallback actually
581 $handlerValue = apply_filters_deprecated(
582 'fluentform_shortcode_parser_callback_' . $key,
583 [
584 '{' . $key . '}',
585 static::getInstance(),
586 ],
587 FLUENTFORM_FRAMEWORK_UPGRADE,
588 'fluentform/shortcode_parser_callback_' . $key,
589 'Use fluentform/shortcode_parser_callback_' . $key . ' instead of fluentform_shortcode_parser_callback_' . $key
590 );
591
592 $handlerValue = apply_filters('fluentform/shortcode_parser_callback_' . $key, $handlerValue, static::getInstance());
593
594 if ($handlerValue) {
595 return $handlerValue;
596 }
597
598 return '';
599 }
600
601 public static function getForm()
602 {
603 if (!is_object(static::$form)) {
604 static::$form = wpFluent()->table('fluentform_forms')->find(static::$form);
605 }
606
607 return static::$form;
608 }
609
610 public static function getProvider()
611 {
612 return static::$provider;
613 }
614
615 public static function getEntry()
616 {
617 if (!is_object(static::$entry)) {
618 static::$entry = wpFluent()->table('fluentform_submissions')->find(static::$entry);
619 }
620
621 return static::$entry;
622 }
623
624 protected static function getRequest()
625 {
626 return wpFluentForm('request');
627 }
628
629 protected static function getUserAgent()
630 {
631 if (is_null(static::$browser)) {
632 static::$browser = new Browser();
633 }
634 return static::$browser;
635 }
636
637 public static function getInstance()
638 {
639 static $instance;
640 if ($instance) {
641 return $instance;
642 }
643 $instance = new static();
644 return $instance;
645 }
646
647 public static function getInputs()
648 {
649 return static::$store['original_inputs'];
650 }
651
652 /**
653 * Get the entry UID link for a submission
654 *
655 * @param object $entry
656 * @return string
657 */
658 protected static function getEntryUidLink($entry)
659 {
660 // Check if entry already has the entry_uid_link property
661 if (isset($entry->entry_uid_link)) {
662 return $entry->entry_uid_link;
663 }
664
665 // Check if front-end entry view is enabled for this form
666 $frontEndSettings = Helper::getFormMeta($entry->form_id, 'front_end_entry_view', []);
667 if (ArrayHelper::get($frontEndSettings, 'status') !== 'yes') {
668 return '';
669 }
670
671 // Get the UID hash from submission meta
672 $meta = wpFluent()->table('fluentform_submission_meta')
673 ->where('response_id', $entry->id)
674 ->where('meta_key', '_entry_uid_hash')
675 ->first();
676
677 if (!$meta || !$meta->value) {
678 return '';
679 }
680
681 // Generate the link
682 return site_url('?ff_entry=1&hash=' . $meta->value);
683 }
684
685 protected static function getShortEntryUid($entry)
686 {
687 if (empty($entry->id)) {
688 return '';
689 }
690
691 $entryId = strtoupper(base_convert((string) absint($entry->id), 10, 36));
692 $entryHash = SubmissionMeta::retrieve('_entry_uid_hash', $entry->id);
693
694 if (!$entryHash) {
695 return $entryId;
696 }
697
698 return $entryId . '-' . strtoupper(substr($entryHash, 0, 4));
699 }
700
701 public static function resetData()
702 {
703 self::$form = null;
704 self::$entry = null;
705 self::$browser = null;
706 self::$formFields = null;
707
708 FormFieldsParser::resetData();
709 FormDataParser::resetData();
710 }
711 }
712