Skip to content

Commit

Permalink
feat!: refactor AbstractConnectionResolver v2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
justlevine committed Feb 10, 2024
1 parent afe6a52 commit fb3ddfc
Show file tree
Hide file tree
Showing 19 changed files with 1,693 additions and 1,068 deletions.
1,545 changes: 935 additions & 610 deletions src/Data/Connection/AbstractConnectionResolver.php

Large diffs are not rendered by default.

73 changes: 21 additions & 52 deletions src/Data/Connection/CommentConnectionResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@

use GraphQL\Error\UserError;
use WPGraphQL\Utils\Utils;
use WP_Comment_Query;

/**
* Class CommentConnectionResolver
*
* @package WPGraphQL\Data\Connection
*/
class CommentConnectionResolver extends AbstractConnectionResolver {

/**
* {@inheritDoc}
*
Expand All @@ -23,15 +21,14 @@ class CommentConnectionResolver extends AbstractConnectionResolver {
/**
* {@inheritDoc}
*
* @throws \GraphQL\Error\UserError If there is a problem with the $args.
* @throws \GraphQL\Error\UserError
*/
public function get_query_args() {

protected function prepare_query_args( array $args ): array {
/**
* Prepare for later use
*/
$last = ! empty( $this->args['last'] ) ? $this->args['last'] : null;
$first = ! empty( $this->args['first'] ) ? $this->args['first'] : null;
$last = ! empty( $args['last'] ) ? $args['last'] : null;
$first = ! empty( $args['first'] ) ? $args['first'] : null;

$query_args = [];

Expand All @@ -58,18 +55,18 @@ public function get_query_args() {
$query_args['orderby'] = 'comment_date';

/**
* Take any of the $this->args that were part of the GraphQL query and map their
* Take any of the $args that were part of the GraphQL query and map their
* GraphQL names to the WP_Term_Query names to be used in the WP_Term_Query
*
* @since 0.0.5
*/
$input_fields = [];
if ( ! empty( $this->args['where'] ) ) {
$input_fields = $this->sanitize_input_fields( $this->args['where'] );
if ( ! empty( $args['where'] ) ) {
$input_fields = $this->sanitize_input_fields( $args['where'] );
}

/**
* Merge the default $query_args with the $this->args that were entered
* Merge the default $query_args with the $args that were entered
* in the query.
*
* @since 0.0.5
Expand Down Expand Up @@ -115,14 +112,14 @@ public function get_query_args() {
$query_args['graphql_before_cursor'] = $this->get_before_offset();

/**
* Pass the graphql $this->args to the WP_Query
* Pass the graphql $args to the WP_Query
*/
$query_args['graphql_args'] = $this->args;
$query_args['graphql_args'] = $args;

// encode the graphql args as a cache domain to ensure the
// graphql_args are used to identify different queries.
// see: https://core.trac.wordpress.org/ticket/35075
$encoded_args = wp_json_encode( $this->args );
$encoded_args = wp_json_encode( $args );
$query_args['cache_domain'] = ! empty( $encoded_args ) ? 'graphql:' . md5( $encoded_args ) : 'graphql';

/**
Expand All @@ -132,41 +129,33 @@ public function get_query_args() {
$query_args['fields'] = 'ids';

/**
* Filter the query_args that should be applied to the query. This filter is applied AFTER the input args from
* the GraphQL Query have been applied and has the potential to override the GraphQL Query Input Args.
* Filters the query args used by the connection.
*
* @param array<string,mixed> $query_args array of query_args being passed to the
* @param mixed $source source passed down from the resolve tree
* @param array<string,mixed> $args array of arguments input in the field as part of the GraphQL query
* @param \WPGraphQL\AppContext $context object passed down the resolve tree
* @param \GraphQL\Type\Definition\ResolveInfo $info info about fields passed down the resolve tree
* @param array<string,mixed> $query_args The query args to be used with the executable query to get data.
* @param self $resolver The ConnectionResolver instance.
*
* @since 0.0.6
*/
return apply_filters( 'graphql_comment_connection_query_args', $query_args, $this->source, $this->args, $this->context, $this->info );
return apply_filters( 'graphql_comment_connection_query_args', $query_args, $this );
}

/**
* {@inheritDoc}
*
* @return \WP_Comment_Query
* @throws \Exception
*/
public function get_query() {
return new WP_Comment_Query( $this->query_args );
protected function query_class(): string {
return 'WP_Comment_Query';
}

/**
* {@inheritDoc}
*/
public function get_loader_name() {
public function loader_name(): string {
return 'comment';
}

/**
* {@inheritDoc}
*/
public function get_ids_from_query() {
public function get_ids_from_query(): array {
/** @var int[]|string[] $ids */
$ids = ! empty( $this->query->get_comments() ) ? $this->query->get_comments() : [];

Expand All @@ -180,27 +169,8 @@ public function get_ids_from_query() {

/**
* {@inheritDoc}
*
* For example, if the $source were a post_type that didn't support comments, we could prevent
* the connection query from even executing. In our case, we prevent comments from even showing
* in the Schema for post types that don't have comment support, so we don't need to worry
* about that, but there may be other situations where we'd need to prevent it.
*
* @return bool
*/
public function should_execute() {
return true;
}


/**
* Filters the GraphQL args before they are used in get_query_args().
*
* @return array<string,mixed>
*/
public function get_args(): array {
$args = $this->args;

protected function prepare_args( array $args ): array {
if ( ! empty( $args['where'] ) ) {
// Ensure all IDs are converted to database IDs.
foreach ( $args['where'] as $input_key => $input_value ) {
Expand Down Expand Up @@ -253,7 +223,6 @@ static function ( $id ) {
}

/**
*
* Filters the GraphQL args before they are used in get_query_args().
*
* @param array<string,mixed> $args The GraphQL args passed to the resolver.
Expand Down Expand Up @@ -326,7 +295,7 @@ public function sanitize_input_fields( array $args ) {
*
* @param int $offset The ID of the node used for the cursor offset.
*/
public function is_valid_offset( $offset ) {
public function is_valid_offset( $offset ): bool {
return ! empty( get_comment( $offset ) );
}
}
212 changes: 212 additions & 0 deletions src/Data/Connection/ConnectionResolverShim.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
<?php

namespace WPGraphQL\Data\Connection;

use Exception;
use GraphQL\Type\Definition\ResolveInfo;
use WPGraphQL\AppContext;

/**
* Class ConnectionResolverShim - Shim for ConnectionResolver 2.0
*
* Note: This is NOT a true shim, but rather illustrates the changes that need to be made to convert classes to use the new ConnectionResolver.
*
* Issues like changes in method signatures (visibility, arg/return types, etc) are not addressed here.
*
* @package WPGraphQL\Data\Connection
*/
abstract class ConnectionResolverShim extends AbstractConnectionResolver {

/**
* Returns the source of the connection
*
* @deprecated @todo
* @return mixed
*
* @codeCoverageIgnore
*/
public function getSource() {
_deprecated_function( __METHOD__, '@todo', parent::class . '::get_source()' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
return $this->get_source();
}

/**
* Get the loader name
*
* @deprecated @todo
*
* @return \WPGraphQL\Data\Loader\AbstractDataLoader
*
* @codeCoverageIgnore
*/
protected function getLoader() {
_deprecated_function( __METHOD__, '@todo', parent::class . '::get_loader()' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped

return $this->get_loader();
}

/**
* Returns the $args passed to the connection
*
* @deprecated @todo
*
* @return array<string,mixed>
*
* @codeCoverageIgnore
*/
public function getArgs(): array {
_deprecated_function( __METHOD__, '1.11.0', static::class . '::get_args()' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
return $this->get_args();
}

/**
* Returns the AppContext of the connection
*
* @deprecated @todo
*
* @codeCoverageIgnore
*/
public function getContext(): AppContext {
_deprecated_function( __METHOD__, '@todo', parent::class . '::get_context()' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
return $this->get_context();
}

/**
* Returns the ResolveInfo of the connection
*
* @deprecated @todo
*
* @codeCoverageIgnore
*/
public function getInfo(): ResolveInfo {
_deprecated_function( __METHOD__, '@todo', parent::class . '::get_info()' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
return $this->get_info();
}

/**
* Returns whether the connection should execute
*
* @deprecated @todo
*
* @codeCoverageIgnore
*/
public function getShouldExecute(): bool {
_deprecated_function( __METHOD__, '@todo', parent::class . '::get_should_execute()' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
return $this->get_should_execute();
}

/**
* @param string $key The key of the query arg to set
* @param mixed $value The value of the query arg to set
*
* @return \WPGraphQL\Data\Connection\AbstractConnectionResolver
*
* @deprecated 0.3.0
*
* @codeCoverageIgnore
*/
public function setQueryArg( $key, $value ) {
_deprecated_function( __METHOD__, '0.3.0', static::class . '::set_query_arg()' );

return $this->set_query_arg( $key, $value );
}

/**
* {@inheritDoc}
*
* Method `get_loader_name()` is no longer abstract.
*
* Overloading should be done via `loader_name()`.
*
* @throws \Exception
*/
protected function loader_name(): string {
throw new Exception(
sprintf(
// translators: %s is the name of the connection resolver class.
esc_html__( 'Class %s does not implement a valid method `loader_name()`.', 'wp-graphql' ),
static::class
)
);
}

/**
* {@inheritDoc}
*
* Method `get_query_args()` is no longer abstract.
*
* Overloading should be done via `prepare_query_args()`.
*
* @throws \Exception
*/
protected function prepare_query_args( array $args ): array {
throw new Exception(
sprintf(
// translators: %s is the name of the connection resolver class.
esc_html__( 'Class %s does not implement a valid method `prepare_query_args()`.', 'wp-graphql' ),
static::class
)
);
}

/**
* Method `get_query()` is no longer abstract. Overloading (if necesary) should be done via `query()` and `query_class()`.
*/

/**
* Method `should_execute()` is now protected and no longer abstract. It defaults to `true`.
*
* Overload `should_execute()` or `pre_should_execute()` should only occur if there is a reason the connecton should not always execute..
*/

/**
* This method is now abstract.
*
* {@inheritDoc}
*
* @throws \Exception
*/
public function get_ids_from_query(): array {
throw new Exception(
sprintf(
// translators: %s is the name of the connection resolver class.
esc_html__( 'Class %s does not implement a valid method `get_ids_from_query()`.', 'wp-graphql' ),
static::class
)
);
}

/**
* Get_offset
*
* This returns the offset to be used in the $query_args based on the $args passed to the
* GraphQL query.
*
* @deprecated 1.9.0
*
* @codeCoverageIgnore
*
* @return int|mixed
*/
public function get_offset() {
_deprecated_function( __METHOD__, '1.9.0', static::class . '::get_offset_for_cursor()' );

// Using shorthand since this is for deprecated code.
$cursor = $this->args['after'] ?? null;
$cursor = $cursor ?: ( $this->args['before'] ?? null );

return $this->get_offset_for_cursor( $cursor );
}

/**
* Method get_nodes()should now be overloaded `prepare_nodes()`.
*/

/**
* Method `get_edges()` should be overloaded `prepare_edges()`.
*/

/**
* Method `get_page_info()` should now be overloaded via `prepare_page_info()`.
*/
}

0 comments on commit fb3ddfc

Please sign in to comment.