diff --git a/.env.dist b/.env.dist
index be67c60..6f08155 100644
--- a/.env.dist
+++ b/.env.dist
@@ -53,5 +53,4 @@ ACF_PRO=false
# ACF Extended
# ACF_EXTENDED_LICENSE_KEY="Your License Key"
-ACF_EXTENDED_PRO=false
ACF_EXTENDED_VERSION="latest"
diff --git a/.github/workflows/testing-integration.yml b/.github/workflows/testing-integration.yml
index 9108c24..8478b85 100644
--- a/.github/workflows/testing-integration.yml
+++ b/.github/workflows/testing-integration.yml
@@ -22,7 +22,6 @@ jobs:
wordpress: [ '6.1', '5.9' ]
acf_pro: [ true, false ]
acf_version: [ 5.12.4, 6.1.6 ]
- acf_extended_pro: [ true, false ]
include:
- php: '8.1'
wordpress: '6.1'
@@ -86,7 +85,6 @@ jobs:
-e ACF_PRO=${{matrix.acf_pro }} \
-e ACF_LICENSE_KEY=${{secrets.ACF_LICENSE_KEY}} \
-e ACF_VERSION=${{matrix.ACF_VERSION}} \
- -e ACF_EXTENDED_PRO=${{matrix.acf_extended_pro}} \
-e ACF_EXTENDED_LICENSE_KEY=${{secrets.ACF_EXTENDED_LICENSE_KEY}} \
testing
diff --git a/docker/app.setup.sh b/docker/app.setup.sh
index f0746bb..49bb5f2 100644
--- a/docker/app.setup.sh
+++ b/docker/app.setup.sh
@@ -73,7 +73,7 @@ else
fi
# If ACF_EXTENDED_PRO is not true, or the license key is a default value, we'll be using the FREE version of ACF EXTENDED
-if [[ true != ${ACF_EXTENDED_PRO} || '.' == ${ACF_EXTENDED_LICENSE_KEY} || 'Your License Key' == ${ACF_EXTENDED_LICENSE_KEY} ]]; then
+if [[ true != ${ACF_PRO} || '.' == ${ACF_EXTENDED_LICENSE_KEY} || 'Your License Key' == ${ACF_EXTENDED_LICENSE_KEY} ]]; then
echo "ACF EXTENDED Version: " ${ACF_EXTENDED_VERSION}
ACF_EXTENDED_PLUGIN_SLUG="acf-extended/acf-extended.php"
diff --git a/src/Admin/Settings.php b/src/Admin/Settings.php
index 6448a68..14de7b2 100644
--- a/src/Admin/Settings.php
+++ b/src/Admin/Settings.php
@@ -136,6 +136,8 @@ public function graphql_types_ajax_callback(): void {
if ( ! isset( $_POST['data'] ) ) {
echo esc_html( __( 'No location rules were found', 'wp-graphql-acf' ) );
+
+ /** @noinspection ForgottenDebugOutputInspection */
wp_die();
}
@@ -208,7 +210,7 @@ public function display_graphql_field_group_fields( $field_group ): void {
'type' => 'true_false',
'name' => 'show_in_graphql',
'prefix' => 'acf_field_group',
- 'value' => isset( $field_group['show_in_graphql'] ) && (bool) $field_group['show_in_graphql'],
+ 'value' => isset( $field_group['show_in_graphql'] ) ? (bool) $field_group['show_in_graphql'] : 1,
'ui' => 1,
],
'div',
diff --git a/src/Data/Loader/AcfOptionsPageLoader.php b/src/Data/Loader/AcfOptionsPageLoader.php
new file mode 100644
index 0000000..bc0bc0b
--- /dev/null
+++ b/src/Data/Loader/AcfOptionsPageLoader.php
@@ -0,0 +1,36 @@
+get_registry()->get_fields_for_field_group( $layout );
+ $layout['fields'] = [
+ 'fieldGroupName' => [
+ 'type' => 'String',
+ 'description' => __( 'The name of the ACF Flex Field Layout', 'wp-graphql-acf' ),
+ 'deprecationReason' => __( 'Use __typename instead', 'wp-graphql-acf' ),
+ ],
+ ];
$layout['interfaces'] = $interfaces;
$layouts[ $layout_name ] = $layout;
}
diff --git a/src/LocationRules.php b/src/LocationRules.php
index 6f53342..18e8412 100644
--- a/src/LocationRules.php
+++ b/src/LocationRules.php
@@ -962,10 +962,11 @@ public function determine_options_rules( string $field_group_name, string $param
$options_page = acf_get_options_page( $value );
- if ( ! isset( $options_page['show_in_graphql'] ) || false === (bool) $options_page['show_in_graphql'] ) {
+ if ( empty( $options_page ) || ! \WPGraphQLAcf\Utils::should_field_group_show_in_graphql( $options_page ) ) {
return;
}
- $type_name = isset( $options_page['graphql_field_name'] ) ? Utils::format_type_name( $options_page['graphql_field_name'] ) : Utils::format_type_name( $options_page['menu_slug'] );
+
+ $type_name = \WPGraphQLAcf\Utils::get_field_group_name( $options_page );
$this->set_graphql_type( $field_group_name, $type_name );
}
diff --git a/src/Model/AcfOptionsPage.php b/src/Model/AcfOptionsPage.php
new file mode 100644
index 0000000..5deb1fc
--- /dev/null
+++ b/src/Model/AcfOptionsPage.php
@@ -0,0 +1,63 @@
+data = $options_page;
+ parent::__construct();
+ }
+
+ /**
+ * @return array
+ */
+ public function get_data(): array {
+ return $this->data;
+ }
+
+ /**
+ * @return void
+ */
+ protected function init(): void {
+ if ( empty( $this->fields ) ) {
+ $this->fields = [
+ 'slug' => $this->data['menu_slug'] ?? null,
+ 'pageTitle' => $this->data['page_title'] ?? null,
+ 'menuTitle' => $this->data['menu_title'] ?? null,
+ 'parentId' => function () {
+ $type_name = Utils::format_type_name( \WPGraphQLAcf\Utils::get_field_group_name( $this->data ) );
+ return ! empty( $this->data['parent_slug'] ) ? Relay::toGlobalId( 'acf_options_page', $this->data['parent_slug'] ) : null;
+ },
+ 'id' => function () {
+ return Relay::toGlobalId( 'acf_options_page', $this->data['menu_slug'] );
+ },
+ 'acfId' => 'options',
+ ];
+ }
+ }
+}
diff --git a/src/Registry.php b/src/Registry.php
index 65dd991..653710c 100644
--- a/src/Registry.php
+++ b/src/Registry.php
@@ -4,8 +4,12 @@
use Exception;
use GraphQL\Error\Error;
+use GraphQL\Type\Definition\ResolveInfo;
+use WPGraphQL\AppContext;
use WPGraphQL\Registry\TypeRegistry;
use WPGraphQL\Utils\Utils;
+use WPGraphQLAcf\Data\Loader\AcfOptionsPageLoader;
+use WPGraphQLAcf\Model\AcfOptionsPage;
class Registry {
@@ -76,24 +80,7 @@ public function has_registered_field_group( string $key ): bool {
* @return bool
*/
public function should_field_group_show_in_graphql( array $acf_field_group ): bool {
-
- $should = true;
-
- if ( isset( $acf_field_group['active'] ) && false === $acf_field_group['active'] ) {
- $should = false;
- }
-
- // if the field group was configured with no "show_in_graphql" value, default to the "show_in_rest" value
- // to determine if the group should be available in an API
- if ( ! isset( $acf_field_group['show_in_graphql'] ) ) {
- $acf_field_group['show_in_graphql'] = $acf_field_group['show_in_rest'] ?? false;
- }
-
- if ( isset( $acf_field_group['show_in_graphql'] ) && false === $acf_field_group['show_in_graphql'] ) {
- $should = false;
- }
-
- return (bool) apply_filters( 'graphql_acf_should_field_group_show_in_graphql', $should, $acf_field_group );
+ return \WPGraphQLAcf\Utils::should_field_group_show_in_graphql( $acf_field_group );
}
/**
@@ -269,6 +256,26 @@ public function register_initial_graphql_types(): void {
],
],
] );
+
+ register_graphql_interface_type( 'AcfOptionsPage', [
+ 'interfaces' => [ 'Node' ],
+ 'description' => __( 'Options Page registered by ACF', 'wp-graphql-acf' ),
+ 'fields' => [
+ 'id' => [
+ 'type' => [ 'non_null' => 'ID' ],
+ ],
+ 'pageTitle' => [
+ 'type' => 'String',
+ ],
+ 'menuTitle' => [
+ 'type' => 'String',
+ ],
+ 'parentId' => [
+ 'type' => 'String',
+ ],
+ ],
+ ] );
+
}
/**
@@ -277,6 +284,7 @@ public function register_initial_graphql_types(): void {
* @param array $acf_field_group The ACF Field Group config
*
* @return array
+ * @throws Error
*/
public function get_field_group_interfaces( array $acf_field_group ): array {
@@ -307,6 +315,76 @@ public function get_field_group_interfaces( array $acf_field_group ): array {
}
+ /**
+ * @return void
+ * @throws Error
+ * @throws Exception
+ */
+ public function register_options_pages():void {
+
+ if ( ! function_exists( 'acf_get_options_pages' ) ) {
+ return;
+ }
+
+ $graphql_options_pages = acf_get_options_pages();
+
+ if ( empty( $graphql_options_pages ) ) {
+ return;
+ }
+
+ foreach ( $graphql_options_pages as $graphql_options_page ) {
+ if ( ! $this->should_field_group_show_in_graphql( $graphql_options_page ) ) {
+ continue;
+ }
+
+ $type_name = $this->get_field_group_graphql_type_name( $graphql_options_page );
+
+ if ( empty( $type_name ) ) {
+ continue;
+ }
+
+ register_graphql_object_type( $type_name, [
+ 'interfaces' => [ 'AcfOptionsPage' ],
+ 'model' => AcfOptionsPage::class,
+ 'fields' => [
+ 'id' => [
+ 'type' => [ 'non_null' => 'ID' ],
+ ],
+ 'pageTitle' => [
+ 'type' => 'String',
+ ],
+ ],
+ ] );
+
+ $field_name = Utils::format_field_name( $type_name );
+
+ $interface_name = 'WithAcfOptionsPage' . $type_name;
+
+ register_graphql_interface_type( $interface_name, [
+ 'description' => sprintf( __( 'Access point for the "%s" ACF Options Page', 'wp-graphql-acf' ), $type_name ),
+ 'fields' => [
+ $field_name => [
+ 'type' => $type_name,
+ 'resolve' => function ( $source, $args, AppContext $context, ResolveInfo $info ) use ( $graphql_options_page ) {
+
+ $loader = $context->get_loader( 'acf_options_page' );
+
+ if ( ! $loader instanceof AcfOptionsPageLoader ) {
+ return 'null';
+ }
+
+ return $context->get_loader( 'acf_options_page' )->load_deferred( $graphql_options_page['menu_slug'] );
+ },
+ ],
+ ],
+ ]);
+
+ register_graphql_interfaces_to_types( [ $interface_name ], [ 'RootQuery' ] );
+
+ }
+
+ }
+
/**
* @param array $acf_field_group
*
@@ -391,42 +469,7 @@ public function map_acf_field_to_graphql( array $acf_field, array $acf_field_gro
* @throws \GraphQL\Error\Error
*/
public function get_field_group_name( array $field_group ): string {
-
- $field_group_name = '';
-
-
-
- if ( ! empty( $field_group['graphql_field_name'] ) ) {
- $field_group_name = $field_group['graphql_field_name'];
- $field_group_name = preg_replace( '/[^0-9a-zA-Z_\s]/i', '', $field_group_name );
- } else {
- if ( ! empty( $field_group['name'] ) ) {
- $field_group_name = $field_group['name'];
- } elseif ( ! empty( $field_group['title'] ) ) {
- $field_group_name = $field_group['title'];
- } elseif ( ! empty( $field_group['label'] ) ) {
- $field_group_name = $field_group['label'];
- }
- $field_group_name = preg_replace( '/[^0-9a-zA-Z_\s]/i', ' ', $field_group_name );
- // if the graphql_field_name isn't explicitly defined, we'll format it without underscores
- $field_group_name = Utils::format_field_name( $field_group_name, false );
- }
-
- if ( empty( $field_group_name ) ) {
- return $field_group_name;
- }
-
- $starts_with_string = is_numeric( substr( $field_group_name, 0, 1 ) );
-
- if ( $starts_with_string ) {
- graphql_debug( __( 'The ACF Field or Field Group could not be added to the schema. GraphQL Field and Type names cannot start with a number', 'wp-graphql-acf' ), [
- 'invalid' => $field_group,
- ] );
- return '';
- }
-
- return $field_group_name;
-
+ return \WPGraphQLAcf\Utils::get_field_group_name( $field_group );
}
/**
@@ -507,6 +550,10 @@ public function get_location_rules( array $acf_field_groups = [] ): array {
*/
public function get_graphql_locations_for_field_group( array $field_group, array $acf_field_groups ): array {
+ if ( ! $this->should_field_group_show_in_graphql( $field_group ) ) {
+ return [];
+ }
+
$graphql_types = $field_group['graphql_types'] ?? [];
$field_group_name = $field_group['graphql_field_name'] ?? $field_group['title'];
diff --git a/src/ThirdParty.php b/src/ThirdParty.php
index c62fe45..44118ec 100644
--- a/src/ThirdParty.php
+++ b/src/ThirdParty.php
@@ -12,6 +12,10 @@ public function init(): void {
$acfe = new ThirdParty\AcfExtended\AcfExtended();
$acfe->init();
+ // Initialize support for WPGraphQL Smart Cache
+ $smart_cache = new ThirdParty\WPGraphQLSmartCache\WPGraphQLSmartCache();
+ $smart_cache->init();
+
}
}
diff --git a/src/ThirdParty/WPGraphQLSmartCache/WPGraphQLSmartCache.php b/src/ThirdParty/WPGraphQLSmartCache/WPGraphQLSmartCache.php
new file mode 100644
index 0000000..dd41a0c
--- /dev/null
+++ b/src/ThirdParty/WPGraphQLSmartCache/WPGraphQLSmartCache.php
@@ -0,0 +1,72 @@
+invalidation = $invalidation;
+
+ add_action( 'updated_option', [ $this, 'updated_acf_option_cb' ], 10, 4 );
+
+ }
+
+ /**
+ * Purge Cache after ACF Option Page is updated
+ *
+ * @param string $option The name of the option being updated
+ * @param mixed $value The value of the option being updated
+ * @param mixed $original_value The original / previous value of the option
+ *
+ * @return void
+ */
+ public function updated_acf_option_cb( string $option, $value, $original_value ): void {
+
+ // phpcs:ignore
+ if ( ! isset( $_POST['_acf_screen'] ) || 'options' !== $_POST['_acf_screen'] ) {
+ return;
+ }
+
+ // phpcs:ignore
+ $options_page = $_GET['page'] ?? null;
+
+ if ( empty( $options_page ) ) {
+ return;
+ }
+
+ $id = \GraphQLRelay\Relay::toGlobalId( 'acf_options_page', $options_page );
+
+ // @phpstan-ignore-next-line
+ $this->invalidation->purge( $id, sprintf( 'update_acf_options_page ( "%s" )', $options_page ) );
+
+ }
+
+}
diff --git a/src/Utils.php b/src/Utils.php
index d263308..d1826e5 100644
--- a/src/Utils.php
+++ b/src/Utils.php
@@ -8,6 +8,7 @@
use WPGraphQL\Model\Post;
use WPGraphQL\Model\Term;
use WPGraphQL\Model\User;
+use WPGraphQLAcf\Model\AcfOptionsPage;
class Utils {
@@ -49,6 +50,9 @@ public static function get_node_acf_id( $node ) {
case is_array( $node ) && isset( $node['post_id'] ) && 'options' === $node['post_id']:
$id = $node['post_id'];
break;
+ case $node instanceof AcfOptionsPage:
+ $id = $node->acfId;
+ break;
default:
$id = 0;
break;
@@ -146,6 +150,10 @@ public static function get_all_graphql_types(): array {
'label' => __( 'Page Template', 'wp-graphql-acf' ),
'plural_label' => __( 'All Templates Assignable to Content', 'wp-graphql-acf' ),
],
+ 'AcfOptionsPage' => [
+ 'label' => __( 'ACF Options Page', 'wp-graphql-acf' ),
+ 'plural_label' => __( 'All Options Pages registered by ACF', 'wp-graphql-acf' ),
+ ],
];
foreach ( $interfaces as $interface_name => $config ) {
@@ -194,12 +202,8 @@ public static function get_all_graphql_types(): array {
*/
$graphql_types['User'] = __( 'User', 'wp-graphql-acf' );
- /**
- * Add options pages to GraphQL types
- */
- global $acf_options_page;
+ if ( function_exists( 'acf_get_options_pages' ) ) {
- if ( isset( $acf_options_page ) && function_exists( 'acf_get_options_pages' ) ) {
// Get a list of post types that have been registered to show in graphql
$graphql_options_pages = acf_get_options_pages();
@@ -211,13 +215,13 @@ public static function get_all_graphql_types(): array {
/**
* Prepare type key prefix and label surfix
*/
- $label = ' (' . __( 'ACF Options Page', 'wp-graphql-acf' ) . ')';
+ $label = '(' . __( 'ACF Options Page', 'wp-graphql-acf' ) . ')';
/**
* Loop over the post types exposed to GraphQL
*/
foreach ( $graphql_options_pages as $options_page_key => $options_page ) {
- if ( ! isset( $options_page['show_in_graphql'] ) || false === (bool) $options_page['show_in_graphql'] ) {
+ if ( isset( $options_page['show_in_graphql'] ) && ! $options_page['show_in_graphql'] ) {
continue;
}
@@ -225,7 +229,7 @@ public static function get_all_graphql_types(): array {
* Get options page properties.
*/
$page_title = $options_page['page_title'];
- $type_label = $page_title . $label;
+ $type_label = $page_title . ' ' . $label;
$type_name = isset( $options_page['graphql_field_name'] ) ? \WPGraphQL\Utils\Utils::format_type_name( $options_page['graphql_field_name'] ) : \WPGraphQL\Utils\Utils::format_type_name( $options_page['menu_slug'] );
$graphql_types[ $type_name ] = $type_label;
@@ -236,6 +240,98 @@ public static function get_all_graphql_types(): array {
return $graphql_types;
}
+ /**
+ * Whether the ACF Field Group should show in the GraphQL Schema
+ *
+ * @param array $acf_field
+ *
+ * @return bool
+ */
+ public static function should_field_show_in_graphql( array $acf_field ): bool {
+ return self::should_field_group_show_in_graphql( $acf_field );
+ }
+
+ /**
+ * Whether the ACF Field Group should show in the GraphQL Schema
+ *
+ * @param array $acf_field_group
+ *
+ * @return bool
+ */
+ public static function should_field_group_show_in_graphql( array $acf_field_group ): bool {
+
+ $should = true;
+
+ if ( isset( $acf_field_group['active'] ) && false === $acf_field_group['active'] ) {
+ $should = false;
+ }
+
+ $show_in_rest = $acf_field_group['show_in_rest'] ?? false;
+
+
+ // if the field group was configured with no "show_in_graphql" value, default to the "show_in_rest" value
+ // to determine if the group should be available in an API
+ if (
+ ( isset( $acf_field_group['post_id'] ) && 'options' !== $acf_field_group['post_id'] ) &&
+ ! isset( $acf_field_group['show_in_graphql'] ) ) {
+ $acf_field_group['show_in_graphql'] = $show_in_rest ?? false;
+ }
+
+ if ( isset( $acf_field_group['show_in_graphql'] ) && false === $acf_field_group['show_in_graphql'] ) {
+ $should = false;
+ }
+
+ return (bool) apply_filters( 'graphql_acf_should_field_group_show_in_graphql', $should, $acf_field_group );
+
+ }
+
+ /**
+ * Given a field group config, return the name of the field group to be used in the GraphQL
+ * Schema
+ *
+ * @param array $field_group The field group config array
+ *
+ * @return string
+ */
+ public static function get_field_group_name( array $field_group ): string {
+
+ $field_group_name = '';
+
+ if ( ! empty( $field_group['graphql_field_name'] ) ) {
+ $field_group_name = $field_group['graphql_field_name'];
+ $field_group_name = preg_replace( '/[^0-9a-zA-Z_\s]/i', '', $field_group_name );
+ } else {
+ if ( ! empty( $field_group['name'] ) ) {
+ $field_group_name = $field_group['name'];
+ } elseif ( ! empty( $field_group['title'] ) ) {
+ $field_group_name = $field_group['title'];
+ } elseif ( ! empty( $field_group['label'] ) ) {
+ $field_group_name = $field_group['label'];
+ } elseif ( ! empty( $field_group['page_title'] ) ) {
+ $field_group_name = $field_group['page_title'];
+ }
+ $field_group_name = preg_replace( '/[^0-9a-zA-Z_\s]/i', ' ', $field_group_name );
+ // if the graphql_field_name isn't explicitly defined, we'll format it without underscores
+ $field_group_name = \WPGraphQL\Utils\Utils::format_field_name( $field_group_name, false );
+ }
+
+ if ( empty( $field_group_name ) ) {
+ return $field_group_name;
+ }
+
+ $starts_with_string = is_numeric( substr( $field_group_name, 0, 1 ) );
+
+ if ( $starts_with_string ) {
+ graphql_debug( __( 'The ACF Field or Field Group could not be added to the schema. GraphQL Field and Type names cannot start with a number', 'wp-graphql-acf' ), [
+ 'invalid' => $field_group,
+ ] );
+ return '';
+ }
+
+ return $field_group_name;
+
+ }
+
/**
* Returns string of the items in the array list. Limit allows string to be limited length.
*
@@ -244,7 +340,7 @@ public static function get_all_graphql_types(): array {
*
* @return string
*/
- public static function array_list_by_limit( array $list, $limit = 5 ): string {
+ public static function array_list_by_limit( array $list, int $limit = 5 ): string {
$flat_list = '';
$total = count( $list );
diff --git a/src/WPGraphQLAcf.php b/src/WPGraphQLAcf.php
index 22818f4..0423704 100644
--- a/src/WPGraphQLAcf.php
+++ b/src/WPGraphQLAcf.php
@@ -37,6 +37,11 @@ public function init(): void {
add_action( 'admin_init', [ $this, 'init_admin_settings' ] );
add_action( 'after_setup_theme', [ $this, 'cpt_tax_registration' ] );
add_action( 'graphql_register_types', [ $this, 'init_registry' ] );
+
+ add_filter( 'graphql_data_loaders', [ $this, 'register_loaders' ], 10, 2 );
+ add_filter( 'graphql_resolve_node_type', [ $this, 'resolve_acf_options_page_node' ], 10, 2 );
+
+
do_action( 'graphql_acf_init' );
}
@@ -85,6 +90,7 @@ public function init_registry( TypeRegistry $type_registry ): void {
// of the specific fields and field groups registered by ACF
$registry = new Registry( $type_registry );
$registry->register_initial_graphql_types();
+ $registry->register_options_pages();
// Get the field groups that should be mapped to the Schema
$acf_field_groups = $registry->get_acf_field_groups();
@@ -161,6 +167,31 @@ function () use ( $can_load_messages ) {
);
}
+ /**
+ * @param mixed $type The GraphQL Type to return based on the resolving node
+ * @param mixed $node The Node being resolved
+ *
+ * @return mixed
+ */
+ public function resolve_acf_options_page_node( $type, $node ) {
+ if ( $node instanceof \WPGraphQLAcf\Model\AcfOptionsPage ) {
+ return \WPGraphQLAcf\Utils::get_field_group_name( $node->get_data() );
+ }
+ return $type;
+ }
+
+ /**
+ * @param array $loaders
+ * @param \WPGraphQL\AppContext $context
+ *
+ * @return array
+ */
+ public function register_loaders( array $loaders, \WPGraphQL\AppContext $context ): array {
+ $loaders['acf_options_page'] = new \WPGraphQLAcf\Data\Loader\AcfOptionsPageLoader( $context );
+ return $loaders;
+ }
+
+
/**
* Output graphql debug messages if the plugin cannot load properly.
*
diff --git a/tests/_support/WPUnit/AcfFieldTestCase.php b/tests/_support/WPUnit/AcfFieldTestCase.php
index cd20167..2625678 100644
--- a/tests/_support/WPUnit/AcfFieldTestCase.php
+++ b/tests/_support/WPUnit/AcfFieldTestCase.php
@@ -12,10 +12,13 @@
*/
abstract class AcfFieldTestCase extends WPGraphQLAcfTestCase {
+ public $acf_plugin_version;
+
/**
* @return void
*/
public function setUp(): void {
+ $this->acf_plugin_version = $_ENV['ACF_VERSION'] ?? 'latest';
$this->clearSchema();
parent::setUp();
}
diff --git a/tests/_support/WPUnit/AcfeFieldTestCase.php b/tests/_support/WPUnit/AcfeFieldTestCase.php
index aa65426..55fd98d 100644
--- a/tests/_support/WPUnit/AcfeFieldTestCase.php
+++ b/tests/_support/WPUnit/AcfeFieldTestCase.php
@@ -6,8 +6,8 @@ abstract class AcfeFieldTestCase extends \Tests\WPGraphQLAcf\WPUnit\AcfFieldTest
public function _setUp() {
// if the plugin version is before 6.1, we're not testing this functionality
- if ( ! isset( $_ENV['ACF_PRO'] ) || true !== (bool) $_ENV['ACF_PRO'] || version_compare( $this->acf_plugin_version, '6.1', 'lt' ) ) {
- $this->markTestSkipped( sprintf( 'Version "%s" does not include the ability to register custom post types, so we do not need to test the extensions of the feature', $this->acf_plugin_version ) );
+ if ( ! class_exists( 'ACFE_PRO' ) ) {
+ $this->markTestSkipped( 'ACF Extended Pro is not active so this test will not run.' );
}
parent::_setUp(); // TODO: Change the autogenerated stub
diff --git a/tests/wpunit/FieldTypes/AcfeAdvancedLinkFieldTest.php b/tests/wpunit/FieldTypes/AcfeAdvancedLinkFieldTest.php
index fc8ffd7..abb603a 100644
--- a/tests/wpunit/FieldTypes/AcfeAdvancedLinkFieldTest.php
+++ b/tests/wpunit/FieldTypes/AcfeAdvancedLinkFieldTest.php
@@ -6,12 +6,6 @@ class AcfeAdvancedLinkFieldTest extends \Tests\WPGraphQLAcf\WPUnit\AcfeFieldTest
* @return void
*/
public function setUp(): void {
-
- // if the plugin version is before 6.1, we're not testing this functionality
- if ( ! isset( $_ENV['ACF_PRO'] ) || true !== (bool) $_ENV['ACF_PRO'] || version_compare( $this->acf_plugin_version, '6.1', 'lt' ) ) {
- $this->markTestSkipped( sprintf( 'Version "%s" does not include the ability to register custom post types, so we do not need to test the extensions of the feature', $this->acf_plugin_version ) );
- }
-
parent::setUp();
}
diff --git a/tests/wpunit/OptionsPageTest.php b/tests/wpunit/OptionsPageTest.php
new file mode 100644
index 0000000..52b76cf
--- /dev/null
+++ b/tests/wpunit/OptionsPageTest.php
@@ -0,0 +1,290 @@
+markTestSkipped( 'ACF Options Pages are not available in this test environment' );
+ }
+
+ parent::setUp();
+ }
+
+ public function tearDown(): void {
+ parent::tearDown();
+ }
+
+ public function registerOptionsPage( $title = 'My Options Page', $config = [] ) {
+
+
+ // register options page
+ acf_add_options_page(
+ array_merge( [
+ 'page_title' => $title,
+ 'menu_title' => __( 'My Options Page' ),
+ 'menu_slug' => 'my-options-page',
+ 'capability' => 'edit_posts',
+ // options pages will show in the Schema unless set to false
+ // 'show_in_graphql' => false,
+ ], $config )
+ );
+ }
+
+ public function testAcfOptionsPageIsQueryableInSchema() {
+
+ $this->registerOptionsPage();
+
+ $expected_value = uniqid( 'test', true );
+
+ // Save a value to the ACF Option Field
+ // see: https://www.advancedcustomfields.com/resources/update_field/#update-a-value-from-different-objects
+ if ( function_exists( 'update_field' ) ) {
+ update_field( 'text', $expected_value, 'option' );
+ }
+
+ $this->register_acf_field( [], [
+ 'graphql_field_name' => 'OptionsFields',
+ 'location' => [
+ [
+ [
+ 'param' => 'options_page',
+ 'operator' => '==',
+ 'value' => 'my-options-page',
+ ],
+ ],
+ ],
+ ]);
+
+ $query = '
+ {
+ myOptionsPage {
+ optionsFields {
+ text
+ }
+ }
+ }
+ ';
+
+ $actual = $this->graphql([
+ 'query' => $query,
+ ]);
+
+ self::assertQuerySuccessful( $actual, [
+ // the instructions should be used for the description
+ $this->expectedField( 'myOptionsPage.optionsFields.text', $expected_value ),
+ ] );
+
+ $query = '
+ query GetType( $name: String! ) {
+ __type( name: $name ) {
+ name
+ }
+ }
+ ';
+
+ $actual = $this->graphql( [
+ 'query' => $query,
+ 'variables' => [
+ 'name' => 'MyOptionsPage',
+ ]
+ ]);
+
+ self::assertQuerySuccessful( $actual, [
+ $this->expectedField( '__type.name', 'MyOptionsPage' )
+ ]);
+
+ }
+
+ // @todo:
+ // - options page not in Schema if "show_in_graphql" set to false
+ /**
+ * @throws Exception
+ */
+ public function testOptionsPageNotInSchemaIfShowInGraphqlIsFalse() {
+
+ acf_add_options_page(
+ [
+ 'page_title' => 'ShowInGraphQLFalse',
+ 'menu_title' => __( 'Show in GraphQL False' ),
+ 'menu_slug' => 'show-in-graphql-false',
+ 'capability' => 'edit_posts',
+ // options pages will show in the Schema unless set to false
+ 'show_in_graphql' => false,
+ ]
+ );
+
+ $options_pages = acf_get_options_pages();
+
+ codecept_debug( [
+ '$pages' => $options_pages,
+ ]);
+
+ $this->register_acf_field( [], [
+ 'graphql_field_name' => 'showInGraphqlFields',
+ 'location' => [
+ [
+ [
+ 'param' => 'options_page',
+ 'operator' => '==',
+ 'value' => 'show-in-graphql-false',
+ ],
+ ],
+ ],
+ ]);
+
+ // Ensure the options page was registered to ACF Options Pages properly
+ $this->assertTrue( array_key_exists( 'show-in-graphql-false', $options_pages ) );
+
+ $query = '
+ {
+ showInGraphQLFalse {
+ showInGraphqlFields {
+ text
+ }
+ }
+ }
+ ';
+
+ $actual = $this->graphql([
+ 'query' => $query,
+ ]);
+
+ $this->assertArrayHasKey( 'errors', $actual );
+
+ $query = '
+ query GetType( $name: String! ) {
+ __type( name: $name ) {
+ name
+ }
+ }
+ ';
+
+ $actual = $this->graphql( [
+ 'query' => $query,
+ 'variables' => [
+ 'name' => 'ShowInGraphQLFalse',
+ ]
+ ]);
+
+ $this->assertQueryError( $actual, [
+ $this->expectedField( '__type', self::IS_NULL )
+ ]);
+
+ }
+
+ // - options page shows with different name if "graphql_field_name" is set
+ public function testOptionsPageRespectsGraphqlFieldName() {
+ acf_add_options_page(
+ [
+ 'page_title' => 'CustomGraphqlName',
+ 'menu_title' => __( 'Show in GraphQL False' ),
+ 'menu_slug' => 'custom-graphql-name',
+ 'capability' => 'edit_posts',
+ // options pages will show in the Schema unless set to false
+ 'graphql_field_name' => 'MyCustomOptionsName',
+ ]
+ );
+
+ $expected_value = uniqid( 'test', true );
+
+ // Save a value to the ACF Option Field
+ // see: https://www.advancedcustomfields.com/resources/update_field/#update-a-value-from-different-objects
+ if ( function_exists( 'update_field' ) ) {
+ update_field( 'text', $expected_value, 'option' );
+ }
+
+ $this->register_acf_field( [], [
+ 'graphql_field_name' => 'OptionsFields',
+ 'location' => [
+ [
+ [
+ 'param' => 'options_page',
+ 'operator' => '==',
+ 'value' => 'custom-graphql-name',
+ ],
+ ],
+ ],
+ ]);
+
+ $query = '
+ {
+ myCustomOptionsName {
+ optionsFields {
+ text
+ }
+ }
+ }
+ ';
+
+ $actual = $this->graphql([
+ 'query' => $query,
+ ]);
+
+ self::assertQuerySuccessful( $actual, [
+ // the instructions should be used for the description
+ $this->expectedField( 'myCustomOptionsName.optionsFields.text', $expected_value ),
+ ] );
+
+ $query = '
+ query GetType( $name: String! ) {
+ __type( name: $name ) {
+ name
+ }
+ }
+ ';
+
+ $actual = $this->graphql( [
+ 'query' => $query,
+ 'variables' => [
+ 'name' => 'MyCustomOptionsName',
+ ]
+ ]);
+
+ self::assertQuerySuccessful( $actual, [
+ $this->expectedField( '__type.name', 'MyCustomOptionsName' )
+ ]);
+ }
+
+ public function testQueryOptionsPageAsNode() {
+
+ acf_add_options_page(
+ [
+ 'page_title' => 'OptionsPageNode',
+ 'menu_title' => __( 'Options Page Node' ),
+ 'menu_slug' => 'options-page-node',
+ 'capability' => 'edit_posts',
+ // options pages will show in the Schema unless set to false
+ 'graphql_field_name' => 'OptionsPageNode',
+ ]
+ );
+
+ $query = '
+ query GetOptionsPage($id: ID!) {
+ node(id:$id) {
+ id
+ __typename
+ ...on AcfOptionsPage {
+ menuTitle
+ }
+ }
+ }
+ ';
+
+ $id = \GraphQLRelay\Relay::toGlobalId( 'acf_options_page', 'options-page-node' );
+
+ $actual = $this->graphql([
+ 'query' => $query,
+ 'variables' => [
+ 'id' => $id
+ ]
+ ]);
+
+ self::assertQuerySuccessful( $actual, [
+ $this->expectedField( 'node.__typename', 'OptionsPageNode' ),
+ $this->expectedField( 'node.id', $id )
+ ]);
+
+ }
+
+}