Plugin Directory

Changeset 3075001


Ignore:
Timestamp:
04/22/2024 12:12:51 PM (2 years ago)
Author:
samuelaguilera
Message:

1.5

  • Improved ACF support by requesting the field content only for supported types.
  • Added a settings page for optional settings.
  • Filter freshforms_acf_support is now deprecated in favor or the new settings page.
Location:
fresh-forms-for-gravity/trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • fresh-forms-for-gravity/trunk/class-fresh-forms-for-gravity.php

    r3044601 r3075001  
    4646
    4747    /**
     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    /**
    48115     * Handles hooks.
    49116     */
     
    253320        /**
    254321         * 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.
    257324         * @param string $handle  Script handler name.
    258325         */
     
    267334         */
    268335        add_filter( 'perfmatters_delay_js_exclusions', 'partial_match_exclude_gf_js_files', 99 );
    269        
    270336    }
    271337
     
    284350
    285351        // 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
    287358        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}." );
    289360            return true;
    290361        }
     
    366437            $module_list = array_reduce(
    367438                $rows,
    368                 function( $module_list, $row ) {
     439                function ( $module_list, $row ) {
    369440                    return array_merge( $module_list, $this->get_row_module_list( $row ) );
    370441                },
     
    395466        }
    396467
    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 ) {
    402475            $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 ) ) {
    406479                return true;
    407480            }
     
    410483        // If we're here, no form was detected.
    411484        return false;
    412 
    413485    }
    414486
     
    463535     * Search for the value provided inside the content passed.
    464536     *
    465      * @param string $content    Content for searching.
    466      * @param string $value      The value to search.
    467      * @param string $generation The 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.
    468540     */
    469541    public function scan_content( $content, $value, $generator ) {
    470542
    471543        // 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." );
    474546            return false;
    475547        }
     
    490562     *
    491563     * @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 ) {
    494568
    495569        $supported_acf_fields = array( 'text', 'textarea', 'wysiwyg', 'flexible_content', 'repeater' );
    496570
    497571        foreach ( $acf_fields as $acf_field ) {
    498             //$this->log_debug( __METHOD__ . '(): ACF field properties: ' . print_r( $acf_field, true ) );
    499572
    500573            if ( ! in_array( $acf_field['type'], $supported_acf_fields, true ) ) {
     574                $this->log_debug( __METHOD__ . "(): ACF field not supported. Skipping field: {$acf_field['name']}" );
    501575                continue;
    502576            }
    503577
    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                    }
    508590                }
    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                            }
    524601                        }
    525602                    }
    526603                }
    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
    528630        }
    529631        // If we're here, there's no ACF field with a GF form.
     
    547649        return array_reduce(
    548650            $groups,
    549             function( $module_list, $group ) {
     651            function ( $module_list, $group ) {
    550652                return array_merge( $module_list, $this->get_group_module_list( $group ) );
    551653            },
     
    567669        return array_reduce(
    568670            $cols,
    569             function( $module_list, $col ) {
     671            function ( $module_list, $col ) {
    570672                return array_merge( $module_list, $this->get_column_module_list( $col ) );
    571673            },
     
    592694        return array_reduce(
    593695            $nodes,
    594             function( $module_list, $node ) {
     696            function ( $module_list, $node ) {
    595697                return array_merge( $module_list, $this->get_beaver_builder_node_module_list( $node ) );
    596698            },
     
    697799        // Adds WP nocache headers and some additional stuff.
    698800        $this->headers_and_cookies( $post );
    699 
    700801    }
    701802
     
    747848        add_filter( 'wpo_minify_exclude_contents', '__return_true', 99 ); // Lower priority to ensure it runs later than default.
    748849        add_filter( 'wpo_minify_run_on_page', '__return_true', 99 ); // Lower priority to ensure it runs later than default.
    749 
    750850    }
    751851
     
    831931            $this->log_debug( __METHOD__ . '(): FreshForms Cookie added. Path: ' . $this->return_cookie_path( $post ) );
    832932        }
    833 
    834933    }
    835934
     
    842941        return is_object( $post ) && is_singular() ? "/$post->post_name/" : '/';
    843942    }
    844 
    845943}
  • fresh-forms-for-gravity/trunk/fresh-forms-for-gravity.php

    r3044601 r3075001  
    22/**
    33 * 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.
    55 * Author: Samuel Aguilera
    6  * Version: 1.4.17
     6 * Version: 1.5
    77 * Author URI: https://www.samuelaguilera.com
    88 * Text Domain: fresh-forms-for-gravity
     
    2727*/
    2828
    29 define( 'FRESH_FORMS_FOR_GRAVITY_VERSION', '1.4.17' );
     29define( 'FRESH_FORMS_FOR_GRAVITY_VERSION', '1.5' );
    3030
    3131// Scripts handlers for plugins using them for exclusion filters (e.g. SG Optimizer or Hummingbird). - Defined here to allow WordPress functions to access them.
     
    110110        'gform.initializeOnLoaded',
    111111        'gform', // Try to catch any other gform based script.
     112        'gform_gravityforms_theme-js-extra', // Honeypot.
     113        'version_hash', // Honeypot.
    112114    )
    113115);
     
    162164        GFAddOn::register( 'Fresh_Forms_For_Gravity' );
    163165    }
    164 
    165166}
    166167
     
    298299            $cache_folder = PAGE_OPTIMIZE_CACHE_DIR;
    299300        }
    300    
    301301        page_optimize_cache_cleanup( $cache_folder, 0 /* max file age in seconds */ );
    302302    }
    303 
    304303}
    305304
     
    324323    // Update stored version.
    325324    update_option( 'fffg_version', FRESH_FORMS_FOR_GRAVITY_VERSION );
    326 
    327325}
  • fresh-forms-for-gravity/trunk/readme.txt

    r3044601 r3075001  
    44Requires at least: 4.9
    55Tested up to: 6.4.3
    6 Stable tag: 1.4.17
     6Stable tag: 1.5
    77Requires PHP: 7.0
    88License: GPLv3
    99License URI: http://www.gnu.org/licenses/gpl-3.0.en.html
    1010
    11 Exclude pages from cache when a Gravity Forms shortcode or block is detected. Also deals with issues caused by some automatic JS optimizations.
     11Prevent supported caching and JS optimization plugins breaking Gravity Forms.
    1212
    1313== Description ==
     
    2626
    2727* **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**.
    2929* **Avada**. The following elements has been proven to work: Content Boxes, "Gravity Form", Modal, Text Block. Other elements could work too, but not tested.
    3030* **Beaver Builder**. It will detect Gravity Forms shortcodes added to a Text Editor module.
     
    9393= Usage =
    9494
    95 Just install and activate, no settings page.
     95Just install and activate. No settings required except for ACF support (see FAQ).
    9696
    9797== Frequently Asked Questions ==
     
    103103= I want to enable ACF support =
    104104
    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' );`
     105ACF 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
     107To enable ACF support go to the settings page at Forms > Settings > Fresh Forms.
    110108
    111109= I want Fresh Forms to run for certain posts where I'm embedding forms using an embed method that is not supported. =
    112110
    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.
     111Starting 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
     113You 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.
    114114
    115115The following example would exclude posts with ID 1 and 8:
     
    162162
    163163== 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.
    164170
    165171= 1.4.17 =
Note: See TracChangeset for help on using the changeset viewer.