Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 0.3.0 doesn't work with PageLink, PostObject or Relationship fields #25

Open
pablo-tapia opened this issue Dec 10, 2020 · 7 comments

Comments

@pablo-tapia
Copy link

This new version seems like it doesn't show the acf key anymore but rather display an attributes property, trying to get the ACF field group data seems to happen through the data property that returns a JSON string. So far so good the data property shows all the fields declared inside the ACF Field Group.

The problem is that when the field type is either PageLink, PostObject or Relationship the data showed only includes the Post/Page ID and nothing else. This query for example:

query MyQuery {
  page(id: "/", idType: URI) {
    title(format: RENDERED)
    blocks {
      ... on AcfPostGridBlock {
        attributes {
          data
        }
      }
    }
  }
}

The resulting data looks something like this:

{
  "data": {
    "page": {
      "title": "Home",
      "blocks": [
        {},
        {},
        {},
        {},
        {
          "attributes": {
            "data": "{\"title\":\"Blog \\/ News Feed\",\"_title\":\"field_5fc829b845e30\",\"button\":{\"title\":\"See All Posts\",\"url\":\"https:\\/\\/develop-fluttr.pantheonsite.io\\/get-started\\/\",\"target\":\"\"},\"_button\":\"field_5fc829de45e32\",\"style\":\"blog\",\"_style\":\"field_5fc82a0445e33\",\"blog_posts\":[\"1\"],\"_blog_posts\":\"field_5fc82a3445e34\"}"
          }
        },
        {},
        {}
      ]
    }
  },
  "extensions": {
    "debug": []
  }
}

blog_posts is a Relationship field and no matter if I choose to get the Post Object or the Post ID it always returns the ID. I need to get the data from the related Posts to display it on a page.

Is my query wrong or is there a way for me to obtain the related Post data without having to execute a second query?

Any advice or guidance is greatly appreciated.

Thanks!

@pablo-tapia
Copy link
Author

BTW this works perfectly on version 0.2.1, so I'm rolling back to using that version.

@pablo-tapia
Copy link
Author

Actually, I just noticed that in version 0.2.1 is very simple to query the fields inside a block using the acf property but the property is missing in version 0.3.0. Is this supposed to happen?

Also, version 0.2.1 has a small bug which can be fixed by simply changing this chunk of code:

return array_map(function ($id) use (&$context, &$resolve) {
                        $id = $id['ID'];
                        return $resolve($id, $context);
                    }, $value);

to this:

return array_map(function ($id) use (&$context, &$resolve) {
                        $id = $id->ID;
                        return $resolve($id, $context);
                    }, $value);

Otherwise, you'll get an error like this Cannot use object of type WP_Post as array when using Relationship or PostObject fields.

@pablo-tapia
Copy link
Author

pablo-tapia commented Jan 22, 2021

Hey, it's me again!

So I was able to found the issue with v0.3.0 and I must say the fact that it uses the ACF plugin makes it work beautifully. The main issue was the way the filters are applied in the code, the class uses a Singleton approach that adds the filter during the instantiation of the class and the init action is applied to the init method of the class (which applies the singleton).

The issue with that is that the filters are called only once and never again, so the filters are never called when the GraphQL tree/schema is built and thus we don't have the ACF fields inside the Gutenberg block.

I made some changes to the code, for example, I remove adding the filters using the constructor and instead move them to the init function like this:

function init()
{
    /**
     * If dependencies are missing, do not initialize the code
     */
    if (false === can_load_plugin()) {
        // Show the admin notice
        add_action('admin_init', __NAMESPACE__ . '\show_admin_notice');
        // Bail
        return;
    }

    add_filter(
        'graphql_acf_get_root_id',
        function ($id, $root) {
            return  WPGraphQLGutenbergACF::instance()->get_root_id($id, $root);
        },
        10,
        2
    );

    add_filter(
        'graphql_gutenberg_block_type_fields',
        function ($fields, $block_type, $type_registry) {
            return WPGraphQLGutenbergACF::instance()->block_type_fields($fields, $block_type, $type_registry);
        },
        10,
        3
    );
}

and modified the init function like this:

add_action('acf/init', '\WPGraphQLGutenbergACF\init', 100);

After doing those changes the plugin added the ACF fields to the Gutenberg block and everything else worked beautifully.

@Dsmitheo
Copy link

Dsmitheo commented Feb 26, 2021

I suspect I may have the same issue here, after installing wp-graphql-gutenberg-acf, No changes are made to the schema and I cannot see any fields when I drill into the ACF block. Can you share a full copy of the modifications you made to the file?

@pablo-tapia
Copy link
Author

@Dsmitheo sure, here's the full file:

<?php
/**
 * Plugin Name: WP GraphQL Gutenberg ACF
 * Plugin URI: https://github.com/pristas-peter/wp-graphql-gutenberg-acf
 * Description: Enable acf blocks in WP GraphQL.
 * Author: pristas-peter
 * Author URI:
 * Version: 0.3.0
 * License: GPL-3
 * License URI: https://www.gnu.org/licenses/gpl-3.0.html
 */

namespace WPGraphQLGutenbergACF;

use GraphQL\Type\Definition\Type;
use WPGraphQL\Data\DataSource;
use GraphQL\Type\Definition\CustomScalarType;
use GraphQL\Executor\Executor;
use WPGraphQL\ACF\Config;
use WPGraphQLGutenberg\Blocks\Block;
use WPGraphQLGutenberg\Schema\Types\BlockTypes;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit();
}

if ( ! class_exists( 'WPGraphQLGutenbergACF' ) && class_exists( 'WPGraphQL\ACF\Config' ) ) {
	final class WPGraphQLGutenbergACF extends \WPGraphQL\ACF\Config {

		private static $instance;

		public static function instance() {
			if ( ! isset( self::$instance ) ) {
				self::$instance = new WPGraphQLGutenbergACF();
			}

			return self::$instance;
		}

		public static function format_graphql_block_type_acf_name( $block_name ) {
			return \WPGraphQLGutenberg\Schema\Types\BlockTypes::format_block_name(
				$block_name
			) . 'Fields';
		}

		protected function add_acf_fields_to_block( $block_type ) {
			$field_groups = acf_get_field_groups(
				array(
					'block' => $block_type['name'],
				)
			);

			if ( empty( $field_groups ) || ! is_array( $field_groups ) ) {
				return;
			}

			$type_name = BlockTypes::format_block_name( $block_type['name'] );

			foreach ( $field_groups as $field_group ) {
				$field_name = isset( $field_group['graphql_field_name'] )
					? $field_group['graphql_field_name']
					: Config::camel_case( $field_group['title'] );

				$field_group['type'] = 'group';
				$field_group['name'] = $field_name;
				$config              = array(
					'name'            => $field_name,
					'description'     => $field_group['description'],
					'acf_field'       => $field_group,
					'acf_field_group' => null,
					'resolve'         => function ( $root ) use ( $field_group ) {
						return isset( $root ) ? $root : null;
					},
				);

				$this->register_graphql_field( $type_name, $field_name, $config );
			}
		}

		public function get_root_id( $id, $root ) {
			if ( $root instanceof Block ) {
				acf_setup_meta(
					$root['attributes']['data'],
					$root['attributes']['id'],
					false
				);

				return $root['attributes']['id'];
			} // end if

			return $id;
		}

		public function block_type_fields( $fields, $block_type, $type_registry ) {
			 $this->type_registry = $type_registry;

			if ( substr( $block_type['name'], 0, 4 ) === 'acf/' ) {
				$this->add_acf_fields_to_block( $block_type );
			}

			return $fields;
		}
	}
}


/**
 * Initialize the plugin
 *
 * @return WPGraphQLGutenbergACF|void
 */
function init() {
	/**
	  * If dependencies are missing, do not initialize the code
	  */
	if ( false === can_load_plugin() ) {
		// Show the admin notice
		add_action( 'admin_init', __NAMESPACE__ . '\show_admin_notice' );
		// Bail
		return;
	}

	add_filter(
		'graphql_acf_get_root_id',
		function ( $id, $root ) {
			return WPGraphQLGutenbergACF::instance()->get_root_id( $id, $root );
		},
		10,
		2
	);

	add_filter(
		'graphql_gutenberg_block_type_fields',
		function ( $fields, $block_type, $type_registry ) {
			return WPGraphQLGutenbergACF::instance()->block_type_fields( $fields, $block_type, $type_registry );
		},
		10,
		3
	);
}

add_action( 'acf/init', '\WPGraphQLGutenbergACF\init', 100 );

/**
 * Show admin notice to admins if this plugin is active but dependencies are missing
 * are not active
 *
 * @return bool
 */
function show_admin_notice() {
	/**
	   * For users with lower capabilities, don't show the notice
	   */
	if ( ! current_user_can( 'manage_options' ) ) {
		return false;
	}

	add_action(
		'admin_notices',
		function () {
			?>
<div class="error notice">
	<p><?php esc_html_e( 'WPGraphQL, Advanced Custom Fields, WPGraphQL for Advanced Custom Fields and  WPGraphQL Gutenberg must be active for "wp-graphql-gutenberg-acf" to work.', 'wp-graphql-gutenberg-acf' ); ?>
	</p>
</div>
			<?php
		}
	);
}

/**
 * Check whether ACF, WPGraphQL, WPGraphQlACF and WPGraphQLGutenberg are active
 *
 * @return bool
 * @since 0.3
 */
function can_load_plugin() {
	// Is ACF active?
	if ( ! class_exists( 'ACF' ) ) {
		return false;
	}

	// Is WPGraphQL active?
	if ( ! class_exists( 'WPGraphQL' ) ) {
		return false;
	}

	// is WPGraphQLACF active?
	if ( ! class_exists( 'WPGraphQL\ACF\ACF' ) ) {
		return false;
	}

	// is WPGraphQLGutenberg active?
	if ( ! class_exists( 'WPGraphQLGutenberg\WPGraphQLGutenberg' ) ) {
		return false;
	}

	return true;
}

@pristas-peter
Copy link
Owner

Hi @pablo-tapia, would you be able to commit those changes into a PR?
Thanks

@pablo-tapia
Copy link
Author

Sure, I'll get do that @pristas-peter

ThyNameIsMud added a commit to ThyNameIsMud/wp-graphql-gutenberg-acf that referenced this issue May 7, 2021
pristas-peter pushed a commit that referenced this issue May 8, 2021
ThyNameIsMud added a commit to ThyNameIsMud/wp-graphql-gutenberg-acf that referenced this issue May 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants