Search
Search
Search
Search
Information
Information
Light
Dark
Open actions menu
Basic upload method
Bypass upload method
Tips!
If you encounter an error (by firewall) while uploading using both methods,
try changing extension of the file before uploading it and rename it right after.
This uploader supports multiple file upload.
Submit
~
var
www
nea-dev.wpress.dk
httpdocs
wp-content
plugins
wpgraphql-acf
src
File Content:
FieldConfig.php
<?php namespace WPGraphQL\Acf; use GraphQL\Type\Definition\ResolveInfo; use WPGraphQL\AppContext; class FieldConfig { /** * @var array<mixed> */ protected $acf_field; /** * @var array<mixed> */ protected $raw_field; /** * @var array<mixed> */ protected $acf_field_group; /** * @var string|null */ protected $graphql_field_group_type_name; /** * @var string */ protected $graphql_field_name; /** * @var \WPGraphQL\Acf\AcfGraphQLFieldType|null */ protected $graphql_field_type; /** * @var \WPGraphQL\Acf\Registry */ protected $registry; /** * @var string */ protected $graphql_parent_type_name; /** * @param array<mixed> $acf_field The ACF Field being mapped to the GraphQL Schema * @param array<mixed> $acf_field_group The ACF Field Group the field belongs to * @param \WPGraphQL\Acf\Registry $registry The WPGraphQL for ACF Type Registry * * @throws \GraphQL\Error\Error */ public function __construct( array $acf_field, array $acf_field_group, Registry $registry ) { $this->raw_field = $acf_field; $this->acf_field = ! empty( $acf_field['key'] ) && acf_get_field( $acf_field['key'] ) ? acf_get_field( $acf_field['key'] ) : $acf_field; $this->acf_field_group = $acf_field_group; $this->registry = $registry; $this->graphql_field_group_type_name = $this->registry->get_field_group_graphql_type_name( $this->acf_field_group ); $this->graphql_field_name = $this->registry->get_graphql_field_name( $this->acf_field ); $this->graphql_field_type = Utils::get_graphql_field_type( $this->raw_field['type'] ); } /** * Get the WPGraphQL for ACF TypeRegistry instance */ public function get_registry(): Registry { return $this->registry; } /** * Get the GraphQL Type Name for the current ACF Field Group */ public function get_graphql_field_group_type_name(): ?string { return $this->graphql_field_group_type_name; } /** * Get the AcfGraphQLFieldType definition for an ACF Field */ public function get_graphql_field_type(): ?AcfGraphQLFieldType { return $this->graphql_field_type; } /** * @param array<mixed> $acf_field * @param string|null $prepend * * @throws \GraphQL\Error\Error */ public function get_parent_graphql_type_name( array $acf_field, ?string $prepend = '' ): string { $type_name = ''; if ( ! empty( $acf_field['parent_layout_group'] ) ) { $type_name = $this->registry->get_field_group_graphql_type_name( $acf_field['parent_layout_group'] ); } elseif ( ! empty( $acf_field['parent'] ) ) { $parent_field = acf_get_field( $acf_field['parent'] ); $parent_group = acf_get_field_group( $acf_field['parent'] ); if ( ! empty( $parent_field ) ) { $type_name = $this->registry->get_field_group_graphql_type_name( $parent_field ); $type_name = $this->get_parent_graphql_type_name( $parent_field, $type_name ); } elseif ( ! empty( $parent_group ) ) { $type_name = $this->registry->get_field_group_graphql_type_name( $parent_group ); $type_name = $this->get_parent_graphql_type_name( $parent_group, $type_name ); } } return $type_name . $prepend; } /** * Get the GraphQL field name of the ACF Field */ public function get_graphql_field_name(): string { return $this->graphql_field_name; } /** * Determine whether an ACF Field is supported by GraphQL */ protected function is_supported_field_type(): bool { $supported_types = Utils::get_supported_acf_fields_types(); return ! empty( $this->acf_field['type'] ) && in_array( $this->acf_field['type'], $supported_types, true ); } /** * Get the description of the field for the GraphQL Schema * * @throws \GraphQL\Error\Error */ public function get_field_description(): string { $graphql_field_type = $this->get_graphql_field_type(); $field_type_config = ( $graphql_field_type instanceof AcfGraphQLFieldType ) ? $graphql_field_type->get_config() : []; // Use the explicit graphql_description, if set if ( ! empty( $this->acf_field['graphql_description'] ) ) { $description = $this->acf_field['graphql_description']; // else use the instructions, if set } elseif ( ! empty( $this->acf_field['instructions'] ) ) { $description = $this->acf_field['instructions']; } else { // Fallback description // translators: %s is the name of the ACF Field Group $description = sprintf( // translators: %1$s is the ACF Field Type and %2$s is the name of the ACF Field Group __( 'Field of the "%1$s" Field Type added to the schema as part of the "%2$s" Field Group', 'wpgraphql-acf' ), $this->acf_field['type'] ?? '', $this->registry->get_field_group_graphql_type_name( $this->acf_field_group ) ); } if ( isset( $field_type_config['graphql_description_after'] ) ) { if ( is_callable( $field_type_config['graphql_description_after'] ) ) { $description .= ' ' . call_user_func( $field_type_config['graphql_description_after'], $this ); } else { $description .= ' ' . $field_type_config['graphql_description_after']; } } return $description; } /** * @return array<mixed> */ public function get_acf_field(): array { return $this->acf_field; } /** * @return array<mixed> */ public function get_raw_acf_field(): array { return $this->raw_field; } /** * @return array<mixed> */ public function get_acf_field_group(): array { return $this->acf_field_group; } /** * @return array<mixed>|null * @throws \GraphQL\Error\Error * @throws \Exception */ public function get_graphql_field_config(): ?array { // if the field is explicitly set to not show in graphql, leave it out of the schema // if the field is explicitly set to not show in graphql, leave it out of the schema if ( isset( $this->acf_field['show_in_graphql'] ) && false === (bool) $this->acf_field['show_in_graphql'] ) { return null; } // if the field is not a supported type, don't add it to the schema if ( ! $this->is_supported_field_type() ) { return null; } if ( empty( $this->graphql_field_group_type_name ) || empty( $this->graphql_field_name ) ) { return null; } $field_config = [ 'type' => 'String', 'name' => $this->graphql_field_name, 'description' => $this->get_field_description(), 'acf_field' => $this->get_acf_field(), 'acf_field_group' => $this->acf_field_group, 'resolve' => function ( $root, $args, AppContext $context, ResolveInfo $info ) { return $this->resolve_field( $root, $args, $context, $info ); }, ]; if ( ! empty( $this->acf_field['type'] ) ) { $graphql_field_type = $this->get_graphql_field_type(); // If the field type overrode the resolver, use it if ( null !== $graphql_field_type && method_exists( $graphql_field_type, 'get_resolver' ) ) { $resolver = function ( $root, $args, AppContext $context, ResolveInfo $info ) use ( $graphql_field_type ) { return $graphql_field_type->get_resolver( $root, $args, $context, $info, $graphql_field_type, $this ); }; $field_config['resolve'] = $resolver; } if ( $graphql_field_type instanceof AcfGraphQLFieldType ) { $field_type = $graphql_field_type->get_resolve_type( $this ); } if ( empty( $field_type ) ) { $field_type = 'String'; } // if the field type returns a connection, // bail and let the connection handle registration to the schema // and resolution if ( 'connection' === $field_type ) { $this->registry->register_field( $this->acf_field ); return null; } // if the field type returns a NULL type, // bail and prevent the field from being directly mapped to the Schema if ( 'NULL' === $field_type ) { return null; } switch ( $this->acf_field['type'] ) { case 'color_picker': case 'number': case 'range': case 'group': case 'wysiwyg': case 'google_map': case 'link': case 'oembed': case 'radio': case 'date_picker': case 'date_time_picker': case 'time_picker': case 'flexible_content': case 'button_group': case 'repeater': $field_config['type'] = $field_type; break; case 'true_false': $field_config['type'] = $field_type; $field_config['resolve'] = function ( $node, array $args, AppContext $context, ResolveInfo $info ) { $value = $this->resolve_field( $node, $args, $context, $info ); return (bool) $value; }; break; case 'checkbox': case 'select': $field_config['type'] = $field_type; $field_config['resolve'] = function ( $node, array $args, AppContext $context, ResolveInfo $info ) { $value = $this->resolve_field( $node, $args, $context, $info ); if ( empty( $value ) && ! is_array( $value ) ) { return null; } return is_array( $value ) ? $value : [ $value ]; }; break; default: $field_config['type'] = $field_type; break; } } /** * Filter the graphql_field_config for an ACF Field * * @param array|null $field_config The field config array passed to the schema registration * @param \WPGraphQL\Acf\FieldConfig $instance Instance of the FieldConfig class */ return apply_filters( 'wpgraphql/acf/get_graphql_field_config', $field_config, $this ); } /** * Determine if the field should ask ACF to format the response when retrieving * the field using get_field() * * @param string $field_type The ACF Field Type of field being resolved */ public function should_format_field_value( string $field_type ): bool { // @todo: filter this? And it should be done at the registry level once, not the per-field level $types_to_format = [ 'select', 'wysiwyg', 'repeater', 'flexible_content', 'oembed', 'clone', ]; return in_array( $field_type, $types_to_format, true ); } /** * @param string $selector * @param string|null $parent_field_name * @param string|int|null $post_id * @param bool $should_format * * @return false|mixed */ protected function get_field( string $selector, ?string $parent_field_name = null, $post_id = null, bool $should_format = false ) { if ( ! empty( $parent_field_name ) ) { $value = get_sub_field( $selector, $should_format ); } else { $value = get_field( $selector, $post_id, $should_format ); } return $value; } /** * @param mixed $root * @param array<mixed> $args * @param \WPGraphQL\AppContext $context * @param \GraphQL\Type\Definition\ResolveInfo $info * @param array<mixed> $acf_field The ACF Field to resolve for * * @return mixed */ public function resolve_field( $root, array $args, AppContext $context, ResolveInfo $info, $acf_field = [] ) { $field_config = $info->fieldDefinition->config['acf_field'] ?? $this->acf_field; // merge the field config and the acf_field passed in $field_config = array_merge( $field_config, $acf_field ); $node = $root['node'] ?? null; $node_id = $node ? Utils::get_node_acf_id( $node ) : null; $return_value = null; $field_key = null; $is_cloned = false; if ( ! empty( $field_config['__key'] ) ) { $field_key = $field_config['__key']; $is_cloned = true; } elseif ( ! empty( $field_config['key'] ) ) { $field_key = $field_config['key']; } if ( empty( $field_key ) ) { return null; } if ( $is_cloned ) { if ( isset( $field_config['_name'] ) && ! empty( $node_id ) ) { $field_key = $field_config['_name']; } elseif ( ! empty( $field_config['__key'] ) ) { $field_key = $field_config['__key']; } } $should_format_value = false; if ( ! empty( $field_config['type'] ) && $this->should_format_field_value( $field_config['type'] ) ) { $should_format_value = true; } if ( empty( $field_key ) ) { return null; } // if the field_config is empty or not an array, set it as an empty array as a fallback $field_config = ! empty( $field_config ) ? $field_config : []; // If the root being passed down already has a value // for the field key, let's use it to resolve if ( isset( $field_config['key'] ) && ! empty( $root[ $field_config['key'] ] ) ) { return $this->prepare_acf_field_value( $root[ $field_config['key'] ], $node, $node_id, $field_config ); } // Check if the cloned field key is being used to pass values down if ( isset( $field_config['__key'] ) && ! empty( $root[ $field_config['__key'] ] ) ) { return $this->prepare_acf_field_value( $root[ $field_config['__key'] ], $node, $node_id, $field_config ); } // Else check if the values are being passed down via the name if ( isset( $field_config['name'] ) && ! empty( $root[ '_' . $field_config['name'] ] ) ) { return $this->prepare_acf_field_value( $root[ '_' . $field_config['name'] ], $node, $node_id, $field_config ); } // Else check if the values are being passed down via the name if ( isset( $field_config['name'] ) && ! empty( $root[ $field_config['name'] ] ) ) { return $this->prepare_acf_field_value( $root[ $field_config['name'] ], $node, $node_id, $field_config ); } /** * Filter the field value before resolving. * * @param mixed $value The value of the ACF Field stored on the node * @param mixed $node The object the field is connected to * @param mixed|string|int $node_id The ACF ID of the node to resolve the field with * @param array $acf_field The ACF Field config * @param bool $format Whether to apply formatting to the field * @param string $field_key The key of the field being resolved */ $pre_value = apply_filters( 'wpgraphql/acf/pre_resolve_acf_field', null, $root, $node_id, $field_config, $should_format_value, $field_key ); // If the filter has returned a value, we can return the value that was returned. if ( null !== $pre_value ) { return $pre_value; } $parent_field_name = null; if ( ! empty( $field_config['parent'] ) ) { $parent_field = acf_get_field( $field_config['parent'] ); if ( ! empty( $parent_field['name'] ) ) { $parent_field_name = $parent_field['name']; } } // resolve block field if ( is_array( $node ) && isset( $node['blockName'], $node['attrs'] ) ) { $block = $node['attrs']; // Ensure the block has an ID if ( ! isset( $block['id'] ) ) { $block['id'] = uniqid( 'block_', true ); } $block = acf_prepare_block( $block ); $block_id = acf_get_block_id( $node['attrs'] ); $block_id = acf_ensure_block_id_prefix( $block_id ); acf_setup_meta( $block['data'], $block_id, true ); $return_value = $this->get_field( $field_config['name'], $parent_field_name, $block_id, $should_format_value ); acf_reset_meta( $block_id ); if ( empty( $return_value ) && isset( $node['attrs']['data'][ $field_config['name'] ] ) ) { $return_value = $node['attrs']['data'][ $field_config['name'] ]; } if ( empty( $return_value ) && ( ! empty( $parent_field_name ) && ! empty( $node['attrs']['data'][ $parent_field_name . '_' . $field_config['name'] ] ) ) ) { $return_value = $node['attrs']['data'][ $parent_field_name . '_' . $field_config['name'] ]; } } // If there's no node_id at this point, we can return null if ( empty( $return_value ) && empty( $node_id ) ) { return null; } // if a value hasn't been set yet, use the get_field() function to get the value if ( empty( $return_value ) ) { $return_value = $this->get_field( $field_key, $parent_field_name, $node_id, $should_format_value ); } // Prepare the value for response $prepared_value = $this->prepare_acf_field_value( $return_value, $root, $node_id, $field_config ); // Empty values are set to null if ( empty( $prepared_value ) ) { $prepared_value = null; } /** * Filter the value before returning * * @param mixed $value * @param array $field_config The ACF Field Config for the field being resolved * @param mixed $root The Root node or object of the field being resolved * @param mixed $node_id The ID of the node being resolved */ return apply_filters( 'wpgraphql/acf/field_value', $prepared_value, $field_config, $root, $node_id ); } /** * Given a value of an ACF Field, this prepares it for response by applying formatting, etc based on * the field type. * * @param mixed $value The value of the ACF field to return * @param mixed $root The root node/object the field belongs to * @param mixed|string|int $node_id The ID of the node the field belongs to * @param ?array $acf_field_config The ACF Field Config for the field being resolved * * @return mixed */ public function prepare_acf_field_value( $value, $root, $node_id, ?array $acf_field_config = [] ) { if ( empty( $acf_field_config ) || ! is_array( $acf_field_config ) ) { return $value; } // if the value is an array and the field return format is set to array, // map over the array to get the return values if ( isset( $acf_field_config['return_format'] ) && 'array' === $acf_field_config['return_format'] && is_array( $value ) ) { $value = array_map( static function ( $opt ) { if ( ! is_array( $opt ) ) { return $opt; } return $opt['value'] ?? null; }, $value ); } if ( isset( $acf_field_config['new_lines'] ) ) { if ( 'wpautop' === $acf_field_config['new_lines'] ) { $value = wpautop( $value ); } if ( 'br' === $acf_field_config['new_lines'] ) { $value = nl2br( $value ); } } // @todo: This was ported over, but I'm not 💯 sure what this is solving and // why it's only applied on options pages and not other pages 🤔 if ( 'wysiwyg' === $acf_field_config['type'] ) { $value = apply_filters( 'the_content', $value ); } if ( ! empty( $acf_field_config['type'] ) && in_array( $acf_field_config['type'], [ 'date_picker', 'time_picker', 'date_time_picker', ], true ) ) { if ( ! empty( $value ) && ! empty( $acf_field_config['return_format'] ) ) { $value = gmdate( $acf_field_config['return_format'], strtotime( $value ) ); } } if ( ! empty( $acf_field_config['type'] ) && in_array( $acf_field_config['type'], [ 'number', 'range' ], true ) ) { $value = (float) $value ?: null; } return $value; } /** * @param string $to_type */ public function get_connection_name( string $to_type ): string { return \WPGraphQL\Utils\Utils::format_type_name( 'Acf' . ucfirst( $to_type ) . 'Connection' ); } /** * @param array<mixed> $config The Connection Config to use * * @throws \Exception */ public function register_graphql_connections( array $config ): void { $type_name = $this->get_graphql_field_group_type_name(); $to_type = $config['toType'] ?? null; // If there's no to_type or type_name, we can't proceed if ( empty( $to_type ) || empty( $type_name ) ) { return; } $connection_name = $this->get_connection_name( $to_type ); $connection_config = array_merge( [ 'description' => $this->get_field_description(), 'acf_field' => $this->get_acf_field(), 'acf_field_group' => $this->get_acf_field_group(), 'fromType' => $type_name, 'toType' => $to_type, 'connectionTypeName' => $connection_name, 'fromFieldName' => $this->get_graphql_field_name(), 'allowFieldUnderscores' => true, ], $config ); $connection_key = $this->get_graphql_field_name() . ':' . $type_name . ':' . $to_type; if ( $this->registry->has_registered_field_group( $connection_key ) ) { return; } // Register the connection to the Field Group Type if ( defined( 'WPGRAPHQL_VERSION' ) && version_compare( WPGRAPHQL_VERSION, '1.23.0', '<=' ) ) { register_graphql_connection( $connection_config ); } // Register the connection to the Field Group Fields Interface register_graphql_connection( array_merge( $connection_config, [ 'fromType' => $type_name . '_Fields' ] ) ); $this->registry->register_field_group( $connection_key, $connection_config ); } }
Edit
Download
Unzip
Chmod
Delete