Skip to content

Commit

Permalink
Fix recursion in ACF fields with GravityView shortcodes (#1998)
Browse files Browse the repository at this point in the history
This PR adresses #1812. 

It looks like a recursion is going on when trying to retrieve the meta
fields for a post. It used the `get_field_objects()` method of ACF.
Apparently they are right when they say:

> The function is not very elegant and wastes a lot of PHP memory / SQL
queries if you are not using all the fields / values

So I've replaced it with half the internal method, retrieving the meta
keys for ACF only, and microcaching the result.

This fixes the recursion for me, and I'm able to show the view when
rendering `the_field('content');`.
  • Loading branch information
zackkatz authored Feb 29, 2024
2 parents 60ee45d + f5957b7 commit 31916de
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -47,22 +56,52 @@ 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 [];
}

// Can never be too careful: double-check that ACF is active and the function exists
if ( ! function_exists( 'get_field_objects' ) ) {
return $meta_keys;
if ( isset( $this->keys[ $post_id ] ) ) {
return $this->keys[ $post_id ];
}

$acf_keys = get_field_objects( $post->ID, array( 'load_value' => false ) );
$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 ];
}

/**
* @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;
Expand Down
4 changes: 4 additions & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 31916de

Please sign in to comment.