Skip to content

Commit

Permalink
Merge pull request #2752 from justlevine/fix/handle-404s-in-node-reso…
Browse files Browse the repository at this point in the history
…lver

fix: handle 404s in NodeResolver.php
  • Loading branch information
jasonbahl committed Mar 8, 2023
2 parents ead0acb + f7315e1 commit f73eaa0
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 29 deletions.
79 changes: 50 additions & 29 deletions src/Data/NodeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace WPGraphQL\Data;

use Exception;
use GraphQL\Deferred;
use WP;
use WP_Post;
use WPGraphQL\AppContext;
Expand Down Expand Up @@ -131,6 +132,15 @@ public function resolve_uri( string $uri, $extra_query_vars = '' ) {
// Parse the URI and sets the $wp->query_vars property.
$uri = $this->parse_request( $uri, $extra_query_vars );

/**
* If the URI is '/', we can resolve it now.
*
* We don't rely on $this->parse_request(), since the home page doesn't get a rewrite rule.
*/
if ( '/' === $uri ) {
return $this->resolve_home_page();
}

/**
* Filter the query class used to resolve the URI. By default this is WP_Query.
*
Expand Down Expand Up @@ -182,32 +192,6 @@ public function resolve_uri( string $uri, $extra_query_vars = '' ) {
return $node;
}

// Resolve the home page.
if ( $query->is_home() ) {
$page_id = get_option( 'page_on_front', 0 );
$show_on_front = get_option( 'show_on_front', 'posts' );

// If the homepage is a static page, return the page.
if ( 'page' === $show_on_front && ! empty( $page_id ) ) {

$page = get_post( $page_id );

if ( empty( $page ) ) {
return null;
}

return $this->context->get_loader( 'post' )->load_deferred( $page->ID );
}

// If the homepage is set to latest posts, we need to make sure not to resolve it when when for other types.
if ( ! $this->is_valid_node_type( 'ContentType' ) ) {
return null;
}

// We dont have an 'Archive' type, so we resolve to the ContentType.
return $this->context->get_loader( 'post_type' )->load_deferred( 'post' );
}

// Resolve Post Objects.
if ( $queried_object instanceof WP_Post ) {
// If Page for Posts is set, we need to return the Page archive, not the page.
Expand Down Expand Up @@ -355,11 +339,9 @@ public function parse_request( string $uri, $extra_query_vars = '' ) {

// Fetch the rewrite rules.
$rewrite = $wp_rewrite->wp_rewrite_rules();

$error = '404';
if ( ! empty( $rewrite ) ) {
// If we match a rewrite rule, this will be cleared.
$error = null;
$error = '404';
$this->wp->did_permalink = true;

$pathinfo = ! empty( $uri ) ? $uri : '';
Expand Down Expand Up @@ -460,9 +442,16 @@ public function parse_request( string $uri, $extra_query_vars = '' ) {
// Substitute the substring matches into the query.
$query = addslashes( \WP_MatchesMapRegex::apply( $query, $matches ) ); // @phpstan-ignore-line

$this->wp->matched_query = $query;

// Parse the query.
parse_str( $query, $perma_query_vars );

// If we're processing a 404 request, clear the error var since we found something.
// @phpstan-ignore-next-line
if ( '404' == $error ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
unset( $error );
}
}
}

Expand Down Expand Up @@ -576,4 +565,36 @@ public function parse_request( string $uri, $extra_query_vars = '' ) {
protected function is_valid_node_type( string $node_type ) : bool {
return ! isset( $this->wp->query_vars['nodeType'] ) || $this->wp->query_vars['nodeType'] === $node_type;
}

/**
* Resolves the home page.
*
* If the homepage is a static page, return the page, otherwise we return the Posts `ContentType`.
*
* @todo Replace `ContentType` with an `Archive` type.
*/
protected function resolve_home_page() : ?Deferred {
$page_id = get_option( 'page_on_front', 0 );
$show_on_front = get_option( 'show_on_front', 'posts' );

// If the homepage is a static page, return the page.
if ( 'page' === $show_on_front && ! empty( $page_id ) ) {

$page = get_post( $page_id );

if ( empty( $page ) ) {
return null;
}

return $this->context->get_loader( 'post' )->load_deferred( $page->ID );
}

// If the homepage is set to latest posts, we need to make sure not to resolve it when when for other types.
if ( ! $this->is_valid_node_type( 'ContentType' ) ) {
return null;
}

// We dont have an 'Archive' type, so we resolve to the ContentType.
return $this->context->get_loader( 'post_type' )->load_deferred( 'post' );
}
}
76 changes: 76 additions & 0 deletions tests/wpunit/NodeByUriTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1820,4 +1820,80 @@ public function assertValidURIResolution( string $uri, string $expected_graphql_
$this->assertSame( $uri, $actual['data']['nodeByUri']['uri'], 'The uri should match the expected URI' );
}

/**
* @see: https://github.com/wp-graphql/wp-graphql/issues/2751
*/
public function testNodeByUriWithCustomPermalinkStructure() {

$this->set_permalink_structure( '/posts/%postname%/' );

$query = '
query NodeByUri($uri:String!) {
nodeByUri( uri: $uri ) {
__typename
uri
}
}
';

$actual = $this->graphql([
'query' => $query,
'variables' => [
'uri' => '/whatever (something non-existing)'
]
]);

// The query should succeed
self::assertQuerySuccessful( $actual, [
// the query should return a null value as the uri
// cannot be found
$this->expectedField( 'nodeByUri', self::IS_NULL ),
] );

}

/**
* @see: https://github.com/wp-graphql/wp-graphql/issues/2751
*/
public function testNodeByUriWithCustomPermalinkStructureAndFrontPageSet() {

$page_id = $this->factory()->post->create([
'post_type' => 'page',
'post_status' => 'publish',
]);

update_option( 'page_on_front', $page_id );
update_option( 'show_on_front', 'page' );

$this->set_permalink_structure( '/posts/%postname%/' );

$query = '
query NodeByUri($uri:String!) {
nodeByUri( uri: $uri ) {
__typename
uri
}
}
';

$actual = $this->graphql([
'query' => $query,
'variables' => [
'uri' => '/whatever (something non-existing)'
]
]);

// The query should succeed
self::assertQuerySuccessful( $actual, [
// the query should return a null value as the uri
// cannot be found
$this->expectedField( 'nodeByUri', self::IS_NULL ),
] );

// cleanup
update_option( 'page_on_front', 0 );
update_option( 'show_on_front', 0 );

}

}

0 comments on commit f73eaa0

Please sign in to comment.