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 | boot/globals.php +68 -54 6.2.26.2.14 View file →
@@ -100,18 +100,19 @@
100 100 $input = sanitize_text_field($input);
101 101 }
102 102 } elseif (is_array($input)) {
103 103 $sanitizedInput = [];
104 -
104 +
105 105 foreach ($input as $key => &$value) {
106 106 $key = fluentFormSanitizer($key);
107 - $attribute = $attribute ? $attribute . '[' . $key . ']' : $key;
107 + // Local var: mutating $attribute here would collapse every sibling
108 + // after the first onto a bare key, resolving nested inputs to the wrong element.
109 + $childAttribute = $attribute ? $attribute . '[' . $key . ']' : $key;
108 110
109 - $value = fluentFormSanitizer($value, $attribute, $fields);
110 - $attribute = null;
111 + $value = fluentFormSanitizer($value, $childAttribute, $fields);
111 112 $sanitizedInput[$key] = $value;
112 113 }
113 -
114 +
114 115 $input = $sanitizedInput;
115 116 }
116 117
117 118 return $input;
@@ -210,13 +211,13 @@
210 211
211 212 function fluentFormIsHandlingSubmission()
212 213 {
213 214 $status = fluentFormWasSubmitted() || isWpAsyncRequest('fluentform_async_request');
214 -
215 +
215 216 $status = apply_filters_deprecated(
216 217 'fluentform_is_handling_submission',
217 218 [
218 - $status
219 + $status,
219 220 ],
220 221 FLUENTFORM_FRAMEWORK_UPGRADE,
221 222 'fluentform/is_handling_submission',
222 223 'Use fluentform/is_handling_submission instead of fluentform_is_handling_submission'
@@ -255,16 +256,16 @@
255 256 {
256 257 \FluentForm\App\Services\Scheduler\Scheduler::processEmailReport();
257 258 }
258 259
259 -function fluentform_upgrade_url()
260 +function fluentform_upgrade_url($utmContent = '')
260 261 {
261 - return 'https://fluentforms.com/pricing/?utm_source=plugin&utm_medium=wp_install&utm_campaign=ff_upgrade&theme_style=' . fluentform_get_active_theme_slug();
262 + return \FluentForm\App\Helpers\Helper::utmUrl('https://fluentforms.com/pricing/', $utmContent);
262 263 }
263 264
264 -function fluentform_integrations_url()
265 +function fluentform_integrations_url($utmContent = '')
265 266 {
266 - return 'https://fluentforms.com/integration/?utm_source=plugin&utm_medium=wp_install&utm_campaign=ff_upgrade&theme_style=' . fluentform_get_active_theme_slug();
267 + return \FluentForm\App\Helpers\Helper::utmUrl('https://fluentforms.com/integration/', $utmContent);
267 268 }
268 269
269 270 function fluentFormApi($module = 'forms')
270 271 {
@@ -318,43 +319,11 @@
318 319 }
319 320
320 321 function fluentform_options_sanitize($options)
321 322 {
322 - $maps = [
323 - 'label' => 'wp_kses_post',
324 - 'value' => 'sanitize_text_field',
325 - 'image' => 'sanitize_url',
326 - 'calc_value' => 'sanitize_text_field',
327 - ];
328 -
329 - $mapKeys = array_keys($maps);
330 -
331 - foreach ($options as $optionIndex => $option) {
332 - $attributes = array_filter(ArrayHelper::only($option, $mapKeys));
333 - foreach ($attributes as $key => $value) {
334 - $options[$optionIndex][$key] = call_user_func($maps[$key], $value);
335 - }
336 - }
337 -
338 - return $options;
323 + return \FluentForm\App\Helpers\Helper::sanitizeAdvancedOptions($options);
339 324 }
340 325
341 -function fluentform_iframe_srcdoc_sanitize($value)
342 -{
343 - $tags = wp_kses_allowed_html('post');
344 - $tags['style'] = [
345 - 'types' => [],
346 - ];
347 - // Check if decoding is necessary
348 - if (strpos($value, '&') !== false) {
349 - // Decode HTML entities
350 - $value = html_entity_decode($value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
351 - $value = stripslashes($value);
352 - }
353 - return wp_kses($value, $tags);
354 -}
355 -
356 -
357 326 function fluentform_sanitize_html($html)
358 327 {
359 328 if (!$html) {
360 329 return $html;
@@ -374,11 +343,8 @@
374 343 $tags['iframe'] = [
375 344 'width' => [],
376 345 'height' => [],
377 346 'src' => [],
378 - 'srcdoc' => [
379 - 'value_callback' => 'fluentform_iframe_srcdoc_sanitize'
380 - ],
381 347 'title' => [],
382 348 'frameborder' => [],
383 349 'allow' => [],
384 350 'class' => [],
@@ -385,9 +351,9 @@
385 351 'id' => [],
386 352 'allowfullscreen' => [],
387 353 'style' => [],
388 354 ];
389 -
355 +
390 356 //svg
391 357 if (empty($tags['svg'])) {
392 358 $svg_args = [
393 359 'svg' => [
@@ -402,9 +368,9 @@
402 368 'fill' => true,
403 369 'stroke' => true,
404 370 'stroke-width' => true,
405 371 'stroke-linecap' => true,
406 - 'stroke-linejoin' => true
372 + 'stroke-linejoin' => true,
407 373 ],
408 374 'g' => ['fill' => true],
409 375 'title' => ['title' => true],
410 376 'path' => [
@@ -412,18 +378,18 @@
412 378 'fill' => true,
413 379 'transform' => true,
414 380 ],
415 381 'polyline' => [
416 - 'points' => true
417 - ]
382 + 'points' => true,
383 + ],
418 384 ];
419 385 $tags = array_merge($tags, $svg_args);
420 386 }
421 -
387 +
422 388 $tags = apply_filters_deprecated(
423 389 'fluentform_allowed_html_tags',
424 390 [
425 - $tags
391 + $tags,
426 392 ],
427 393 FLUENTFORM_FRAMEWORK_UPGRADE,
428 394 'fluentform/allowed_html_tags',
429 395 'Use fluentform/allowed_html_tags instead of fluentform_allowed_html_tags'
@@ -495,9 +461,9 @@
495 461 // Convert to string if not already
496 462 if (!is_string($css)) {
497 463 $css = (string) $css;
498 464 }
499 -
465 +
500 466 return preg_match('#</?\w+#', $css) ? '' : $css;
501 467 }
502 468
503 469 function fluentformCanUnfilteredHTML()
@@ -530,5 +496,53 @@
530 496 ];
531 497 }
532 498
533 499 return $formattedPages;
500 +}
501 +
502 +function fluentform_maybe_disable_contaminated_pro()
503 +{
504 + $unsafeProFile = WP_PLUGIN_DIR . '/fluentformpro/libs/class-license-sync.php';
505 +
506 + if (! is_file($unsafeProFile)) {
507 + return;
508 + }
509 +
510 + require_once ABSPATH . 'wp-admin/includes/plugin.php';
511 +
512 + deactivate_plugins(
513 + 'fluentformpro/fluentformpro.php',
514 + true
515 + );
516 +
517 + $message = sprintf(
518 + __('<strong>Fluent Forms Pro has been deactivated for security reasons.</strong> Delete the existing plugin and install a fresh copy from your %1$sWPManageNinja dashboard%2$s. Your Fluent Forms data will remain intact. We recommend %3$sopening a support ticket%4$s so we can help clean up your site. Read the %5$sincident report%6$s for details.', 'fluentform'),
519 + '<a href="' . esc_url(add_query_arg('ff_deactivation_error', '1', 'https://wpmanageninja.com/account/downloads')) . '" target="_blank" rel="noopener noreferrer">',
520 + '</a>',
521 + '<a href="' . esc_url(add_query_arg('ff_deactivation_error', '1', 'https://wpmanageninja.com/account/support-tickets/submit-ticket/')) . '" target="_blank" rel="noopener noreferrer">',
522 + '</a>',
523 + '<a href="' . esc_url(add_query_arg('ff_deactivation_error', '1', 'https://wpmanageninja.com/security-incident-on-31-july-2026/')) . '" target="_blank" rel="noopener noreferrer">',
524 + '</a>'
525 + );
526 +
527 + add_action('admin_init', function () use ($message) {
528 + $renderNotice = function () use ($message) {
529 + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Admin notice with HTML links
530 + printf('<div class="fluentform-admin-notice notice notice-error"><div style="padding: 15px 10px;">%1$s</div></div>', $message);
531 + };
532 + add_action('fluentform/global_menu', $renderNotice);
533 + add_action('fluentform/after_form_menu', $renderNotice);
534 + });
535 +
536 + add_action('admin_notices', function () use ($message) {
537 + if (! current_user_can('activate_plugins')) {
538 + return;
539 + }
540 + ?>
541 + <div class="notice notice-error">
542 + <p>
543 + <?php echo $message; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Admin notice with HTML links ?>
544 + </p>
545 + </div>
546 + <?php
547 + });
534 548 }