PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / trunk
Yoast SEO – Advanced SEO with real-time guidance and built-in AI vtrunk
28.5 28.4 28.3 28.2 28.1 28.0 27.9 27.8 27.7 27.6 27.5 trunk 18.0 18.1 18.2 18.3 18.4 18.4.1 18.5 18.5.1 18.6 18.7 18.8 18.9 19.0 All 129 releases
wordpress-seo / src / schema-aggregator / infrastructure / schema-pieces / wordpress-global-state-adapter.php

wordpress-global-state-adapter.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI trunk, at src/schema-aggregator/infrastructure/schema-pieces/wordpress-global-state-adapter.php

137 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
3 namespace Yoast\WP\SEO\Schema_Aggregator\Infrastructure\Schema_Pieces;
4
5 use WP_Post;
6 use Yoast\WP\SEO\Context\Meta_Tags_Context;
7 use Yoast\WP\SEO\Memoizers\Meta_Tags_Context_Memoizer;
8 use Yoast\WP\SEO\Models\Indexable;
9 /**
10 * Helper class to set and reset WordPress global state.
11 */
12 class WordPress_Global_State_Adapter {
13
14 /**
15 * The meta tags context memoizer.
16 *
17 * @var Meta_Tags_Context_Memoizer
18 */
19 private $memoizer;
20
21 /**
22 * Previous global $post
23 *
24 * @var WP_Post|null
25 */
26 private $previous_post;
27
28 /**
29 * Previous global $wp_query->queried_object
30 *
31 * @var WP_Post|null
32 */
33 private $previous_queried_object;
34
35 /**
36 * Previous global $wp_query->queried_object_id
37 *
38 * @var int|string|null
39 */
40 private $previous_queried_object_id;
41
42 /**
43 * Previous query flags
44 *
45 * @var array<string, bool>
46 */
47 private $previous_query_flags;
48
49 /**
50 * Constructor.
51 *
52 * @param Meta_Tags_Context_Memoizer $memoizer The meta tags context memoizer.
53 */
54 public function __construct( Meta_Tags_Context_Memoizer $memoizer ) {
55 $this->memoizer = $memoizer;
56 }
57
58 /**
59 * Set WordPress global state
60 *
61 * Helper method to set $post and $wp_query globals based on the given indexable, and
62 * prime the memoizer's current_page slot with the indexable's context so external schema
63 * generators (e.g. WPSEO_WooCommerce_Schema) read the correct per-indexable values.
64 * This is critical to ensure that schema pieces relying on global state function correctly.
65 *
66 * @param Indexable $indexable The indexable to set the global state for.
67 * @param Meta_Tags_Context $context The indexable's context, installed as the current_page slot.
68 *
69 * @return void
70 */
71 public function set_global_state( Indexable $indexable, Meta_Tags_Context $context ): void {
72 global $post, $wp_query;
73 $this->previous_post = $post;
74 $this->previous_queried_object = ( $wp_query->queried_object ?? null );
75 $this->previous_queried_object_id = ( $wp_query->queried_object_id ?? null );
76
77 $this->previous_query_flags = [
78 'is_single' => ( $wp_query->is_single ?? false ),
79 'is_page' => ( $wp_query->is_page ?? false ),
80 'is_singular' => ( $wp_query->is_singular ?? false ),
81 ];
82
83 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- To setup the post we need to do this explicitly.
84 $post = \get_post( $indexable->object_id );
85 $wp_query->queried_object = \get_post( $indexable->object_id );
86 $wp_query->queried_object_id = $indexable->object_id;
87
88 $wp_query->is_single = false;
89 $wp_query->is_page = false;
90 $wp_query->is_singular = true;
91
92 if ( $indexable->object_sub_type === 'page' ) {
93 $wp_query->is_page = true;
94 }
95 else {
96 $wp_query->is_single = true;
97
98 }
99
100 \setup_postdata( $post );
101
102 // Make for_current_page() resolve to the indexable being processed, so external schema
103 // generators (e.g. WPSEO_WooCommerce_Schema) read the correct per-indexable canonical /
104 // main_schema_id. reset_global_state() clears this slot at the end of the iteration.
105 $this->memoizer->set_for_current_page( $context );
106 }
107
108 /**
109 * Restore WordPress global state
110 *
111 * Helper method to restore $post and $wp_query globals after schema collection.
112 * This is critical to prevent side effects that could corrupt WordPress's global context.
113 *
114 * @return void
115 */
116 public function reset_global_state(): void {
117 global $post, $wp_query;
118
119 \wp_reset_postdata();
120
121 // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- To reset the post we need to do this explicitly.
122 $post = $this->previous_post;
123
124 if ( isset( $wp_query ) && \is_object( $wp_query ) ) {
125 $wp_query->queried_object = $this->previous_queried_object;
126 $wp_query->queried_object_id = $this->previous_queried_object_id;
127 $wp_query->is_single = $this->previous_query_flags['is_single'];
128 $wp_query->is_page = $this->previous_query_flags['is_page'];
129 $wp_query->is_singular = $this->previous_query_flags['is_singular'];
130 }
131
132 // Drop the per-iteration current_page context primed by Schema_Piece_Repository::get(),
133 // so the next iteration re-resolves cleanly.
134 $this->memoizer->clear_for_current_page();
135 }
136 }
137