Skip to content

Commit 6f8216f

Browse files
Return expected data when querying seo data of custom taxonomy (#57)
* Update shim to work with custom taxonomies * Update CHANGELOG.md * dev: revert and use local parse_query * dev: move breadcrumb generation to model * tests: Test custom tax term seo * fix: reset global authordata on Model::tear_down() * chore: update changelog --------- Co-authored-by: David Levine <[email protected]>
1 parent 9a0f046 commit 6f8216f

File tree

7 files changed

+268
-51
lines changed

7 files changed

+268
-51
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Changelog
22

33
## Unreleased
4+
- fix: Fetch the correct SEO data when resolving custom taxonomy terms. Props @lucguerraz
5+
- dev!: Move `SEO::$global_authordata` property to the `UserSeo` model and make nullable.
6+
- dev: Move `seo.breadcrumbs` resolution from the `RankMathSeo` interface to the `SEO` model.
47

58
## v0.0.13
69
- feat: Expose Redirections to the GraphQL schema.

src/Model/Seo.php

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
namespace WPGraphQL\RankMath\Model;
99

10+
use RankMath\Frontend\Breadcrumbs as RMBreadcrumbs;
1011
use RankMath\Helper as RMHelper;
1112
use RankMath\Paper\Paper;
1213
use WPGraphQL\Model\Model;
@@ -63,13 +64,6 @@ abstract class Seo extends Model {
6364
*/
6465
protected $global_post;
6566

66-
/**
67-
* The global authordata at time of Model generation
68-
*
69-
* @var \WP_User
70-
*/
71-
protected $global_authordata;
72-
7367
/**
7468
* Constructor.
7569
*
@@ -83,6 +77,7 @@ public function __construct( $object, $capability = '', $allowed_fields = [] ) {
8377

8478
$allowed_fields = array_merge(
8579
[
80+
'breadcrumbs',
8681
'title',
8782
'description',
8883
'robots',
@@ -119,6 +114,7 @@ public function setup(): void {
119114
protected function init() {
120115
if ( empty( $this->fields ) ) {
121116
$this->fields = [
117+
'breadcrumbs' => fn (): ?array => $this->get_breadcrumbs(),
122118
'title' => function (): ?string {
123119
$title = $this->helper->get_title();
124120

@@ -165,6 +161,34 @@ protected function init() {
165161
}
166162
}
167163

164+
/**
165+
* Gets and parses the breadcrumbs for the object.
166+
*
167+
* @return ?array<string, string|mixed>[] The breadcrumbs.
168+
*/
169+
protected function get_breadcrumbs(): ?array {
170+
// Get the crumbs and shape them.
171+
$crumbs = RMBreadcrumbs::get()->get_crumbs();
172+
$breadcrumbs = array_map(
173+
static function ( $crumb ) {
174+
return [
175+
'text' => $crumb[0] ?? null,
176+
'url' => $crumb[1] ?? null,
177+
'isHidden' => ! empty( $crumb['hide_in_schema'] ),
178+
];
179+
},
180+
$crumbs
181+
);
182+
183+
// Pop the current item's title.
184+
$remove_title = ( is_single( $this->database_id ) || is_page( $this->database_id ) ) && RMHelper::get_settings( 'general.breadcrumbs_remove_post_title' );
185+
if ( $remove_title ) {
186+
array_pop( $breadcrumbs );
187+
}
188+
189+
return ! empty( $breadcrumbs ) ? $breadcrumbs : null;
190+
}
191+
168192
/**
169193
* Gets the hydrated meta, falling back to default settings.
170194
*

src/Model/TermNodeSeo.php

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@ public function __construct( int $term_id ) {
6060
public function setup(): void {
6161
global $wp_query, $post;
6262

63-
/**
64-
* Store the global post before overriding
65-
*/
63+
// Store the global post before overriding.
6664
$this->global_post = $post;
6765

68-
if ( $this->data instanceof WP_Term ) {
66+
// Denylist globally-cached replacements.
67+
add_filter( 'rank_math/replacements/non_cacheable', [ $this, 'non_cacheable_replacements' ] );
6968

69+
if ( $this->data instanceof WP_Term ) {
7070
/**
7171
* Reset global post
7272
*/
@@ -88,6 +88,12 @@ public function setup(): void {
8888
'tag' => $this->data->slug,
8989
]
9090
);
91+
} else {
92+
$wp_query->parse_query(
93+
[
94+
$this->data->taxonomy => $this->data->slug,
95+
]
96+
);
9197
}
9298

9399
$wp_query->queried_object_id = $this->data->term_id;
@@ -104,7 +110,10 @@ public function setup(): void {
104110
* @return void
105111
*/
106112
public function tear_down() {
113+
remove_filter( 'rank_math/replacements/non_cacheable', [ $this, 'non_cacheable_replacements' ] );
114+
107115
$GLOBALS['post'] = $this->global_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride
116+
108117
wp_reset_postdata();
109118
}
110119

@@ -150,4 +159,20 @@ protected function get_object_url(): string {
150159
}
151160
return $term_link;
152161
}
162+
163+
/**
164+
* Adds SEO keys that should not be cached by the Rank Math replacements cache.
165+
*
166+
* @uses rank_math/replacements/non_cacheable
167+
*
168+
* @param string[] $args The keys that should not be cached.
169+
*
170+
* @return string[]
171+
*/
172+
public function non_cacheable_replacements( array $args ): array {
173+
// This is necessary because RM (as of 1.0.117) does not set `term_description` to nocache.
174+
$args[] = 'term_description';
175+
176+
return $args;
177+
}
153178
}

src/Model/UserSeo.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ class UserSeo extends Seo {
2222
*/
2323
protected $data;
2424

25+
/**
26+
* The global authordata at time of Model generation
27+
*
28+
* @var ?\WP_User
29+
*/
30+
protected $global_authordata;
31+
2532
/**
2633
* The settings prefix
2734
*
@@ -56,7 +63,7 @@ public function __construct( int $user_id ) {
5663
* {@inheritDoc}
5764
*/
5865
public function setup(): void {
59-
global $wp_query, $post, $authordata;
66+
global $wp_query, $post, $author, $authordata;
6067

6168
// Store variables for resetting at tear down.
6269
$this->global_post = $post;
@@ -77,7 +84,8 @@ public function setup(): void {
7784
// Setup globals.
7885
$wp_query->is_author = true;
7986
$GLOBALS['authordata'] = $this->data; // phpcs:ignore WordPress.WP.GlobalVariablesOverride
80-
$wp_query->queried_object = get_user_by( 'id', $this->data->ID );
87+
$author = $this->data->ID; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound,SlevomatCodingStandard.Variables.UnusedVariable.UnusedVariable
88+
$wp_query->queried_object = $this->data;
8189
$wp_query->queried_object_id = $this->data->ID;
8290
}
8391

@@ -91,8 +99,13 @@ public function setup(): void {
9199
* @return void
92100
*/
93101
public function tear_down() {
94-
$GLOBALS['authordata'] = $this->global_authordata; // phpcs:ignore WordPress.WP.GlobalVariablesOverride
95-
$GLOBALS['post'] = $this->global_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride
102+
global $author;
103+
if ( $this->data instanceof \WP_User ) {
104+
$author = isset( $this->global_authordata ) ? $this->global_authordata->ID : null; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals
105+
$GLOBALS['authordata'] = $this->global_authordata; // phpcs:ignore WordPress.WP.GlobalVariablesOverride
106+
$GLOBALS['post'] = $this->global_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride
107+
}
108+
96109
wp_reset_postdata();
97110
}
98111

src/Type/WPInterface/Seo.php

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
namespace WPGraphQL\RankMath\Type\WPInterface;
1010

11-
use RankMath\Frontend\Breadcrumbs as RMBreadcrumbs;
1211
use RankMath\Helper;
1312
use WPGraphQL\RankMath\Model\ContentNodeSeo;
1413
use WPGraphQL\RankMath\Model\ContentTypeSeo;
@@ -89,36 +88,6 @@ public static function get_fields(): array {
8988
$fields['breadcrumbs'] = [
9089
'type' => [ 'list_of' => Breadcrumbs::get_type_name() ],
9190
'description' => __( 'The breadcrumbs trail for the given object', 'wp-graphql-rank-math' ),
92-
'resolve' => static function ( $source ) {
93-
if ( $source instanceof UserSeo ) {
94-
// RankMath uses the global $author for generating crumbs.
95-
global $author;
96-
97-
// phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound
98-
$author = $source->ID;
99-
}
100-
101-
// Get the crumbs and shape them.
102-
$crumbs = RMBreadcrumbs::get()->get_crumbs();
103-
$breadcrumbs = array_map(
104-
static function ( $crumb ) {
105-
return [
106-
'text' => $crumb[0] ?? null,
107-
'url' => $crumb[1] ?? null,
108-
'isHidden' => ! empty( $crumb['hide_in_schema'] ),
109-
];
110-
},
111-
$crumbs
112-
);
113-
114-
// Pop the current item's title.
115-
$remove_title = ( is_single( $source->database_id ) || is_page( $source->database_id ) ) && Helper::get_settings( 'general.breadcrumbs_remove_post_title' );
116-
if ( $remove_title ) {
117-
array_pop( $breadcrumbs );
118-
}
119-
120-
return ! empty( $breadcrumbs ) ? $breadcrumbs : null;
121-
},
12291
];
12392
}
12493

0 commit comments

Comments
 (0)