From ee36636967941d2310353ce6786fabe1ba8d8acc Mon Sep 17 00:00:00 2001 From: Doeke Norg Date: Tue, 27 Feb 2024 10:24:10 +0100 Subject: [PATCH 1/2] Fix recursion in ACF fields with GravityView shortcodes --- .../class-gravityview-plugin-hooks-acf.php | 55 ++++++++++++++++--- readme.txt | 4 ++ 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/includes/plugin-and-theme-hooks/class-gravityview-plugin-hooks-acf.php b/includes/plugin-and-theme-hooks/class-gravityview-plugin-hooks-acf.php index d7ad6a94d..4f0c0ff0d 100644 --- a/includes/plugin-and-theme-hooks/class-gravityview-plugin-hooks-acf.php +++ b/includes/plugin-and-theme-hooks/class-gravityview-plugin-hooks-acf.php @@ -35,6 +35,15 @@ class GravityView_Plugin_Hooks_ACF extends GravityView_Plugin_and_Theme_Hooks { */ protected $style_handles = array( 'acf-global' ); + /** + * Microcache for keys by post id. + * + * @since $ver$ + * + * @var array{int, mixed} + */ + private $keys = []; + /** * @since 1.16.5 */ @@ -47,22 +56,50 @@ protected function add_hooks() { } /** - * @param array $meta_keys Existing meta keys to parse for [gravityview] shortcode - * @param \WP_Post $post Current post ID + * Retrieve the "Advanced Custom Field" field keys for the post. * - * @return array + * @since $ver$ + * + * @param int $post_id The post id. + * + * @return array The ACF field keys. */ - function add_meta_keys_from_post( $meta_keys = array(), $post = null ) { + private function get_acf_keys( int $post_id ): array { + // Can never be too careful: double-check that ACF is active and the functions exist. + if ( ! function_exists( 'acf_get_meta' ) || ! function_exists( 'acf_get_valid_post_id' ) || ! $post_id ) { + return []; + } + + if ( ! isset( $this->keys[ $post_id ] ) ) { + $post_id = acf_get_valid_post_id( $post_id ); + $meta = acf_get_meta( $post_id ); - // Can never be too careful: double-check that ACF is active and the function exists - if ( ! function_exists( 'get_field_objects' ) ) { - return $meta_keys; + /** + * Filter non ACF keys. {@see get_field_objects}. + * We use this instead of `get_field_objects` to prevent circular reference and save memory. + */ + $this->keys[ $post_id ] = array_filter( + array_keys( $meta ), + static function ( string $key ) use ( $meta ) { + return isset( $meta[ '_' . $key ] ); + } + ); } - $acf_keys = get_field_objects( $post->ID, array( 'load_value' => false ) ); + return $this->keys[ $post_id ]; + } + + /** + * @param array $meta_keys Existing meta keys to parse for [gravityview] shortcode + * @param \WP_Post $post Current post ID + * + * @return array + */ + public function add_meta_keys_from_post( $meta_keys = array(), $post = null ) { + $acf_keys = $this->get_acf_keys( (int) $post->ID ); if ( $acf_keys ) { - return array_merge( array_keys( $acf_keys ), $meta_keys ); + return array_merge( $acf_keys, $meta_keys ); } return $meta_keys; diff --git a/readme.txt b/readme.txt index e44d32340..1af8aeb9e 100644 --- a/readme.txt +++ b/readme.txt @@ -21,6 +21,10 @@ Beautifully display your Gravity Forms entries. Learn more on [gravitykit.com](h == Changelog == += develop = + +* Fixed: Possible recursion timeout using GravityView shortcodes in "Advanced Custom Fields"-fields. + = 2.20 on February 22, 2024 = This release introduces new settings for better control over View caching, adds support for the Advanced Post Creation Add-On when editing entries, fixes a fatal error when exporting entries to CSV, and updates internal components for better performance and compatibility. From f5957b7a33d4a4ce2ef61e0cab9d25d4d6fb18e6 Mon Sep 17 00:00:00 2001 From: Doeke Norg Date: Tue, 27 Feb 2024 15:10:46 +0100 Subject: [PATCH 2/2] early return --- .../class-gravityview-plugin-hooks-acf.php | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/includes/plugin-and-theme-hooks/class-gravityview-plugin-hooks-acf.php b/includes/plugin-and-theme-hooks/class-gravityview-plugin-hooks-acf.php index 4f0c0ff0d..a1c56da4c 100644 --- a/includes/plugin-and-theme-hooks/class-gravityview-plugin-hooks-acf.php +++ b/includes/plugin-and-theme-hooks/class-gravityview-plugin-hooks-acf.php @@ -70,22 +70,24 @@ private function get_acf_keys( int $post_id ): array { return []; } - if ( ! isset( $this->keys[ $post_id ] ) ) { - $post_id = acf_get_valid_post_id( $post_id ); - $meta = acf_get_meta( $post_id ); - - /** - * Filter non ACF keys. {@see get_field_objects}. - * We use this instead of `get_field_objects` to prevent circular reference and save memory. - */ - $this->keys[ $post_id ] = array_filter( - array_keys( $meta ), - static function ( string $key ) use ( $meta ) { - return isset( $meta[ '_' . $key ] ); - } - ); + if ( isset( $this->keys[ $post_id ] ) ) { + return $this->keys[ $post_id ]; } + $post_id = acf_get_valid_post_id( $post_id ); + $meta = acf_get_meta( $post_id ); + + /** + * Filter non ACF keys. {@see get_field_objects}. + * We use this instead of `get_field_objects` to prevent circular reference and save memory. + */ + $this->keys[ $post_id ] = array_filter( + array_keys( $meta ), + static function ( string $key ) use ( $meta ) { + return isset( $meta[ '_' . $key ] ); + } + ); + return $this->keys[ $post_id ]; }