Changeset 3075001
- Timestamp:
- 04/22/2024 12:12:51 PM (2 years ago)
- Location:
- fresh-forms-for-gravity/trunk
- Files:
-
- 2 added
- 3 edited
-
class-fresh-forms-for-gravity.php (modified) (16 diffs)
-
fresh-forms-for-gravity.php (modified) (6 diffs)
-
images (added)
-
images/menu-icon.svg (added)
-
readme.txt (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
fresh-forms-for-gravity/trunk/class-fresh-forms-for-gravity.php
r3044601 r3075001 46 46 47 47 /** 48 * Return the plugin's icon for the plugin/form settings menu. 49 * 50 * @return string 51 */ 52 public function get_menu_icon() { 53 return file_get_contents( $this->get_base_path() . '/images/menu-icon.svg' ); // phpcs:ignore 54 } 55 56 /** 57 * Configures the settings which should be rendered on the add-on settings tab. 58 * 59 * @return array 60 */ 61 public function plugin_settings_fields() { 62 63 return array( 64 array( 65 'title' => esc_html__( 'ACF Settings', 'fresh-forms-for-gravity' ), 66 'description' => '<p style="text-align: left;">' . esc_html__( 'Enable optional ACF support using the settings below.', 'fresh-forms-for-gravity' ) . '</p>', 67 'fields' => array( 68 array( 69 'name' => 'acf', 70 'label' => esc_html__( 'Search ACF fields for:', 'fresh-forms-for-gravity' ), 71 'type' => 'checkbox', 72 'choices' => array( 73 array( 74 'label' => esc_html__( 'Gravity Forms shortcode', 'fresh-forms-for-gravity' ), 75 'name' => 'acf_shortcode', 76 'default_value' => 0, 77 ), 78 array( 79 'label' => esc_html__( 'Gravity Forms gform_wrapper class', 'fresh-forms-for-gravity' ), 80 'name' => 'acf_scan', 81 'default_value' => 0, 82 'tooltip' => esc_html__( 'Enable this option only if the shortcode option is not able to detect the form.', 'fresh-forms-for-gravity' ), 83 ), 84 ), 85 ), 86 ), 87 ), 88 array( 89 'title' => esc_html__( 'Other Settings', 'fresh-forms-for-gravity' ), 90 'fields' => array( 91 array( 92 'type' => 'text', 93 'name' => 'force_has_form', 94 'label' => esc_html__( 'Force Fresh Forms to run for the following page or post IDs', 'fresh-forms-for-gravity' ), 95 'tooltip' => esc_html__( 'This is useful if your caching plugin is supported but the embedding method is not.', 'fresh-forms-for-gravity' ), 96 'default_value' => '', 97 'after_input' => esc_html__( 'Enter a comma separated list. Example: 6,8,5,3', 'fresh-forms-for-gravity' ), 98 ), 99 ), 100 ), 101 ); 102 } 103 104 /** 105 * Handles save of settings and clearing cache after it. 106 * 107 * @param array $settings Plugin settings to be saved. 108 */ 109 public function update_plugin_settings( $settings ) { 110 parent::update_plugin_settings( $settings ); 111 fffg_purge_all_cache(); // Clear the site cache after saving settings. 112 } 113 114 /** 48 115 * Handles hooks. 49 116 */ … … 253 320 /** 254 321 * Exclude Gravity Forms scripts from Automattic's Page Optimize plugin. No documentation available for this filter. 255 * 256 * @param bool $do_concat true concatenates the script.322 * 323 * @param bool $do_concat true concatenates the script. 257 324 * @param string $handle Script handler name. 258 325 */ … … 267 334 */ 268 335 add_filter( 'perfmatters_delay_js_exclusions', 'partial_match_exclude_gf_js_files', 99 ); 269 270 336 } 271 337 … … 284 350 285 351 // Allow forcing Fresh Form run for certain post ID's without doing the checkings. 286 $post_has_gform = apply_filters( 'freshforms_post_has_gform', array() ); 352 $force_has_form = $this->get_plugin_setting( 'force_has_form' ) ? $this->get_plugin_setting( 'force_has_form' ) : ''; 353 // Remove any empty spaces and convert to array. 354 $force_has_form = array_map( 'intval', explode( ',', preg_replace( '/\s+/', '', $force_has_form ) ) ); 355 356 $post_has_gform = apply_filters( 'freshforms_post_has_gform', $force_has_form ); 357 287 358 if ( ! empty( $post_has_gform ) && in_array( $post->ID, $post_has_gform, true ) ) { 288 $this->log_debug( __METHOD__ . '(): freshforms_post_has_gform filter in use.');359 $this->log_debug( __METHOD__ . "(): Form detection forced to return true by setting or filter for post ID {$post->ID}." ); 289 360 return true; 290 361 } … … 366 437 $module_list = array_reduce( 367 438 $rows, 368 function ( $module_list, $row ) {439 function ( $module_list, $row ) { 369 440 return array_merge( $module_list, $this->get_row_module_list( $row ) ); 370 441 }, … … 395 466 } 396 467 397 // ACF Support disabled by default. 398 $acf_support = apply_filters( 'freshforms_acf_support', false ); 399 400 // Look for a GF shortcode inside ACF fields. 401 if ( class_exists( 'ACF' ) && true === $acf_support ) { 468 // Legacy freshforms_acf_support filter. 469 $shortcode = apply_filters_deprecated( 'freshforms_acf_support', array( $this->get_plugin_setting( 'acf_shortcode' ) ), '1.5' ); 470 $scan = apply_filters_deprecated( 'freshforms_acf_support', array( $this->get_plugin_setting( 'acf_scan' ) ), '1.5' ); 471 472 $acf_support = $shortcode || $scan ? true : false; 473 474 if ( class_exists( 'ACF' ) && true == $acf_support ) { 402 475 $this->log_debug( __METHOD__ . '(): ACF support is enabled.' ); 403 $acf_fields = get_field_objects( $post->ID );404 405 if ( is_array( $acf_fields ) && true === $this->find_gf_acf_field( $acf_fields ) ) {476 $acf_fields = get_field_objects( $post->ID, true, false ); // Get ACF fields without the value. 477 478 if ( is_array( $acf_fields ) && true === $this->find_gf_acf_field( $acf_fields, $shortcode, $scan ) ) { 406 479 return true; 407 480 } … … 410 483 // If we're here, no form was detected. 411 484 return false; 412 413 485 } 414 486 … … 463 535 * Search for the value provided inside the content passed. 464 536 * 465 * @param string $content Content for searching.466 * @param string $value The value to search.467 * @param string $generat ionThe software that generates the content to scan.537 * @param string $content Content for searching. 538 * @param string $value The value to search. 539 * @param string $generator The software that generates the content to scan. 468 540 */ 469 541 public function scan_content( $content, $value, $generator ) { 470 542 471 543 // Return without scanning if there's no content to scan. 472 if ( empty( $content ) ){473 $this->log_debug( __METHOD__ . "(): {$generator} content is empty . Nothing to scan." );544 if ( ! is_string( $content ) || empty( $content ) ) { 545 $this->log_debug( __METHOD__ . "(): {$generator} content is empty or not a string. Nothing to scan." ); 474 546 return false; 475 547 } … … 490 562 * 491 563 * @param array $acf_fields ACF Fields saved for the post. 492 */ 493 public function find_gf_acf_field( $acf_fields ) { 564 * @param bool $shortcode Set to true to scan ACF fields for a GF shortocode. 565 * @param bool $scan Set to true to scan ACF fields for the gform_wrapper class. 566 */ 567 public function find_gf_acf_field( $acf_fields, $shortcode = false, $scan = false ) { 494 568 495 569 $supported_acf_fields = array( 'text', 'textarea', 'wysiwyg', 'flexible_content', 'repeater' ); 496 570 497 571 foreach ( $acf_fields as $acf_field ) { 498 //$this->log_debug( __METHOD__ . '(): ACF field properties: ' . print_r( $acf_field, true ) );499 572 500 573 if ( ! in_array( $acf_field['type'], $supported_acf_fields, true ) ) { 574 $this->log_debug( __METHOD__ . "(): ACF field not supported. Skipping field: {$acf_field['name']}" ); 501 575 continue; 502 576 } 503 577 504 if ( 'text' === $acf_field['type'] || 'textarea' === $acf_field['type'] ) { // Look for a GF shortcode inside a standalone text or textarea fields. 505 if ( is_string( $acf_field['value'] ) && true === $this->find_gf_shortcode( $acf_field['value'] ) ) { 506 $this->log_debug( __METHOD__ . "(): ACF {$acf_field['type']} field has a GF form!" ); 507 return true; 578 // Get the field content. No need to set the post id as the list of fields received is already limited to the current post. 579 $acf_field_content = get_field( $acf_field['name'] ); // Using name which in this case means "custom field meta key name". 580 581 if ( true == $shortcode ) { // Check for GF shortcodes added to ACF fields if it's enabled. 582 583 // Look for a GF shortcode inside a standalone text or textarea fields. 584 if ( ( is_string( $acf_field_content ) && 'text' === $acf_field['type'] ) || ( is_string( $acf_field_content ) && 'textarea' === $acf_field['type'] ) ) { 585 $this->log_debug( __METHOD__ . "(): Checking for GF shorcodes added to ACF field {$acf_field['name']}" ); 586 if ( true === $this->find_gf_shortcode( $acf_field_content ) ) { 587 $this->log_debug( __METHOD__ . "(): ACF {$acf_field['type']} field has a GF form!" ); 588 return true; 589 } 508 590 } 509 } elseif ( 'wysiwyg' === $acf_field['type'] ) { // Look for a GF class inside a standalone wysiwyg field. 510 if ( is_string( $acf_field['value'] ) && true === $this->scan_content( $acf_field['value'], 'gform_wrapper', 'ACF' ) ) { 511 $this->log_debug( __METHOD__ . "(): ACF {$acf_field['type']} field has a GF form!" ); 512 return true; 513 } 514 } elseif ( ( 'flexible_content' === $acf_field['type'] || 'repeater' === $acf_field['type'] ) && ! empty( $acf_field['value'] ) ) { 515 // Look for a GF shortcode or GF class inside the value of any sub-field for a flexible_content field. 516 foreach ( $acf_field['value'] as $acf_subfield_array ) { 517 foreach ( $acf_subfield_array as $key => $value ) { 518 if ( is_string( $value ) && true === $this->find_gf_shortcode( $value ) ) { 519 $this->log_debug( __METHOD__ . "(): ACF {$acf_field['type']} field has a GF form!" ); 520 return true; 521 } elseif ( is_string( $value ) && true === $this->scan_content( $value, 'gform_wrapper', 'ACF' ) ) { 522 $this->log_debug( __METHOD__ . "(): ACF {$acf_field['type']} field has a GF form!" ); 523 return true; 591 592 if ( ( 'flexible_content' === $acf_field['type'] || 'repeater' === $acf_field['type'] ) && ! empty( $acf_field_content ) ) { 593 // Look for a GF shortcode inside the value of any sub-field for a flexible_content or repeater field. 594 foreach ( $acf_field_content as $acf_subfield_array ) { 595 foreach ( $acf_subfield_array as $key => $value ) { 596 $this->log_debug( __METHOD__ . "(): Checking for GF shorcodes added to ACF field {$acf_field['name']}" ); 597 if ( is_string( $value ) && true === $this->find_gf_shortcode( $value ) ) { 598 $this->log_debug( __METHOD__ . "(): ACF {$acf_field['type']} field has a GF form!" ); 599 return true; 600 } 524 601 } 525 602 } 526 603 } 527 } 604 } // Shortcode search done. 605 606 if ( true == $scan ) { // Check for GF class added to ACF fields if it's enabled. 607 608 if ( is_string( $acf_field_content ) && 'wysiwyg' === $acf_field['type'] ) { // Look for a GF class inside a standalone wysiwyg field. 609 $this->log_debug( __METHOD__ . "(): Checking GF HTML markup for ACF field {$acf_field['name']}" ); 610 if ( true === $this->scan_content( $acf_field_content, 'gform_wrapper', 'ACF' ) ) { 611 $this->log_debug( __METHOD__ . "(): ACF {$acf_field['type']} field has a GF form!" ); 612 return true; 613 } 614 } 615 616 if ( ( 'flexible_content' === $acf_field['type'] || 'repeater' === $acf_field['type'] ) && ! empty( $acf_field_content ) ) { 617 // Look for a GF shortcode or GF class inside the value of any sub-field for a flexible_content or repeater field. 618 foreach ( $acf_field_content as $acf_subfield_array ) { 619 foreach ( $acf_subfield_array as $key => $value ) { 620 $this->log_debug( __METHOD__ . "(): Checking GF HTML markup for ACF field {$acf_field['name']}" ); 621 if ( is_string( $value ) && true === $this->scan_content( $value, 'gform_wrapper', 'ACF' ) ) { 622 $this->log_debug( __METHOD__ . "(): ACF {$acf_field['type']} field has a GF form!" ); 623 return true; 624 } 625 } 626 } 627 } 628 } // Class scan done. 629 528 630 } 529 631 // If we're here, there's no ACF field with a GF form. … … 547 649 return array_reduce( 548 650 $groups, 549 function ( $module_list, $group ) {651 function ( $module_list, $group ) { 550 652 return array_merge( $module_list, $this->get_group_module_list( $group ) ); 551 653 }, … … 567 669 return array_reduce( 568 670 $cols, 569 function ( $module_list, $col ) {671 function ( $module_list, $col ) { 570 672 return array_merge( $module_list, $this->get_column_module_list( $col ) ); 571 673 }, … … 592 694 return array_reduce( 593 695 $nodes, 594 function ( $module_list, $node ) {696 function ( $module_list, $node ) { 595 697 return array_merge( $module_list, $this->get_beaver_builder_node_module_list( $node ) ); 596 698 }, … … 697 799 // Adds WP nocache headers and some additional stuff. 698 800 $this->headers_and_cookies( $post ); 699 700 801 } 701 802 … … 747 848 add_filter( 'wpo_minify_exclude_contents', '__return_true', 99 ); // Lower priority to ensure it runs later than default. 748 849 add_filter( 'wpo_minify_run_on_page', '__return_true', 99 ); // Lower priority to ensure it runs later than default. 749 750 850 } 751 851 … … 831 931 $this->log_debug( __METHOD__ . '(): FreshForms Cookie added. Path: ' . $this->return_cookie_path( $post ) ); 832 932 } 833 834 933 } 835 934 … … 842 941 return is_object( $post ) && is_singular() ? "/$post->post_name/" : '/'; 843 942 } 844 845 943 } -
fresh-forms-for-gravity/trunk/fresh-forms-for-gravity.php
r3044601 r3075001 2 2 /** 3 3 * Plugin Name: Fresh Forms for Gravity 4 * Description: Prevent posts and pages with a Gravity Forms shortcode or Gutenberg block from being cached.4 * Description: Prevent supported caching and JS optimization plugins breaking Gravity Forms. 5 5 * Author: Samuel Aguilera 6 * Version: 1. 4.176 * Version: 1.5 7 7 * Author URI: https://www.samuelaguilera.com 8 8 * Text Domain: fresh-forms-for-gravity … … 27 27 */ 28 28 29 define( 'FRESH_FORMS_FOR_GRAVITY_VERSION', '1. 4.17' );29 define( 'FRESH_FORMS_FOR_GRAVITY_VERSION', '1.5' ); 30 30 31 31 // Scripts handlers for plugins using them for exclusion filters (e.g. SG Optimizer or Hummingbird). - Defined here to allow WordPress functions to access them. … … 110 110 'gform.initializeOnLoaded', 111 111 'gform', // Try to catch any other gform based script. 112 'gform_gravityforms_theme-js-extra', // Honeypot. 113 'version_hash', // Honeypot. 112 114 ) 113 115 ); … … 162 164 GFAddOn::register( 'Fresh_Forms_For_Gravity' ); 163 165 } 164 165 166 } 166 167 … … 298 299 $cache_folder = PAGE_OPTIMIZE_CACHE_DIR; 299 300 } 300 301 301 page_optimize_cache_cleanup( $cache_folder, 0 /* max file age in seconds */ ); 302 302 } 303 304 303 } 305 304 … … 324 323 // Update stored version. 325 324 update_option( 'fffg_version', FRESH_FORMS_FOR_GRAVITY_VERSION ); 326 327 325 } -
fresh-forms-for-gravity/trunk/readme.txt
r3044601 r3075001 4 4 Requires at least: 4.9 5 5 Tested up to: 6.4.3 6 Stable tag: 1. 4.176 Stable tag: 1.5 7 7 Requires PHP: 7.0 8 8 License: GPLv3 9 9 License URI: http://www.gnu.org/licenses/gpl-3.0.en.html 10 10 11 Exclude pages from cache when a Gravity Forms shortcode or block is detected. Also deals with issues caused by some automatic JS optimizations.11 Prevent supported caching and JS optimization plugins breaking Gravity Forms. 12 12 13 13 == Description == … … 26 26 27 27 * **WordPress default editor, shortcode or Gutenberg block**. Content of any post type, including pages and custom posts. 28 * **ACF** fields of type Text, Text Area, and WYSIWYG. ** Requires a filter to enable it**, see the FAQ for more details.28 * **ACF** fields of type Text, Text Area, and WYSIWYG. **Disabled by default**. 29 29 * **Avada**. The following elements has been proven to work: Content Boxes, "Gravity Form", Modal, Text Block. Other elements could work too, but not tested. 30 30 * **Beaver Builder**. It will detect Gravity Forms shortcodes added to a Text Editor module. … … 93 93 = Usage = 94 94 95 Just install and activate , no settings page.95 Just install and activate. No settings required except for ACF support (see FAQ). 96 96 97 97 == Frequently Asked Questions == … … 103 103 = I want to enable ACF support = 104 104 105 ACF fields of the following types are supported as standalone fields and also as subfields of a Flexible Content or Repeater field: Text, Text Area, WYSIWYG. 106 107 To enable ACF support add the following line to your theme's functions.php file or a custom functionality plugin. 108 109 `add_filter( 'freshforms_acf_support', '__return_true' );` 105 ACF fields of the following types are supported as standalone fields and also as subfields of a Flexible Content or Repeater field: Text, Text Area, WYSIWYG. But this is disabled by default. 106 107 To enable ACF support go to the settings page at Forms > Settings > Fresh Forms. 110 108 111 109 = I want Fresh Forms to run for certain posts where I'm embedding forms using an embed method that is not supported. = 112 110 113 Starting with Fresh Forms 1.3.1 you can use the freshforms_post_has_gform filter in your theme functions.php file or a custom fucntionatliy plugin to pass Fresh Forms an array containing the ID of the posts where you want it to run without performing the usual automatic detection of forms. 111 Starting with Fresh Forms 1.5 you can add a list of pages or posts IDs where you would like to force Fresh Forms to run by going to Forms > Settings > Fresh Forms. 112 113 You could also add the freshforms_post_has_gform filter in your theme functions.php file or a custom fucntionatliy plugin to pass Fresh Forms an array containing the ID of the pages/posts where you want it to run without performing the usual automatic detection of forms. 114 114 115 115 The following example would exclude posts with ID 1 and 8: … … 162 162 163 163 == Changelog == 164 165 = 1.5 = 166 167 * Improved ACF support by requesting the field content only for supported types. 168 * Added a settings page for optional settings. 169 * Filter freshforms_acf_support is now deprecated in favor or the new settings page. 164 170 165 171 = 1.4.17 =
Note: See TracChangeset
for help on using the changeset viewer.