PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 18.5
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v18.5
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 / actions / indexing / indexable-term-indexation-action.php

indexable-term-indexation-action.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 18.5, at src/actions/indexing/indexable-term-indexation-action.php

190 lines 5.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Yoast\WP\SEO\Actions\Indexing;
4
5 use wpdb;
6 use Yoast\WP\Lib\Model;
7 use Yoast\WP\SEO\Helpers\Taxonomy_Helper;
8 use Yoast\WP\SEO\Models\Indexable;
9 use Yoast\WP\SEO\Repositories\Indexable_Repository;
10 use Yoast\WP\SEO\Values\Indexables\Indexable_Builder_Versions;
11
12 /**
13 * Reindexing action for term indexables.
14 *
15 * @phpcs:disable Yoast.NamingConventions.ObjectNameDepth.MaxExceeded
16 */
17 class Indexable_Term_Indexation_Action extends Abstract_Indexing_Action {
18
19 /**
20 * The transient cache key.
21 */
22 const UNINDEXED_COUNT_TRANSIENT = 'wpseo_total_unindexed_terms';
23
24 /**
25 * The transient cache key for limited counts.
26 *
27 * @var string
28 */
29 const UNINDEXED_LIMITED_COUNT_TRANSIENT = self::UNINDEXED_COUNT_TRANSIENT . '_limited';
30
31 /**
32 * The post type helper.
33 *
34 * @var Taxonomy_Helper
35 */
36 protected $taxonomy;
37
38 /**
39 * The indexable repository.
40 *
41 * @var Indexable_Repository
42 */
43 protected $repository;
44
45 /**
46 * The WordPress database instance.
47 *
48 * @var wpdb
49 */
50 protected $wpdb;
51
52 /**
53 * The latest version of the Indexable term builder
54 *
55 * @var int
56 */
57 protected $version;
58
59 /**
60 * Indexable_Term_Indexation_Action constructor
61 *
62 * @param Taxonomy_Helper $taxonomy The taxonomy helper.
63 * @param Indexable_Repository $repository The indexable repository.
64 * @param wpdb $wpdb The WordPress database instance.
65 * @param Indexable_Builder_Versions $builder_versions The latest versions of all indexable builders.
66 */
67 public function __construct(
68 Taxonomy_Helper $taxonomy,
69 Indexable_Repository $repository,
70 wpdb $wpdb,
71 Indexable_Builder_Versions $builder_versions
72 ) {
73 $this->taxonomy = $taxonomy;
74 $this->repository = $repository;
75 $this->wpdb = $wpdb;
76 $this->version = $builder_versions->get_latest_version_for_type( 'term' );
77 }
78
79 /**
80 * Creates indexables for unindexed terms.
81 *
82 * @return Indexable[] The created indexables.
83 */
84 public function index() {
85 $query = $this->get_select_query( $this->get_limit() );
86
87 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Function get_select_query returns a prepared query.
88 $term_ids = $this->wpdb->get_col( $query );
89
90 $indexables = [];
91 foreach ( $term_ids as $term_id ) {
92 $indexables[] = $this->repository->find_by_id_and_type( (int) $term_id, 'term' );
93 }
94
95 if ( \count( $indexables ) > 0 ) {
96 \delete_transient( static::UNINDEXED_COUNT_TRANSIENT );
97 \delete_transient( static::UNINDEXED_LIMITED_COUNT_TRANSIENT );
98 }
99
100 return $indexables;
101 }
102
103 /**
104 * Returns the number of terms that will be indexed in a single indexing pass.
105 *
106 * @return int The limit.
107 */
108 public function get_limit() {
109 /**
110 * Filter 'wpseo_term_indexation_limit' - Allow filtering the number of terms indexed during each indexing pass.
111 *
112 * @api int The maximum number of terms indexed.
113 */
114 $limit = \apply_filters( 'wpseo_term_indexation_limit', 25 );
115
116 if ( ! \is_int( $limit ) || $limit < 1 ) {
117 $limit = 25;
118 }
119
120 return $limit;
121 }
122
123 /**
124 * Builds a query for counting the number of unindexed terms.
125 *
126 * @return string The prepared query string.
127 */
128 protected function get_count_query() {
129 $indexable_table = Model::get_table_name( 'Indexable' );
130 $taxonomy_table = $this->wpdb->term_taxonomy;
131 $public_taxonomies = \array_keys( $this->taxonomy->get_public_taxonomies() );
132 $taxonomies_placeholders = \implode( ', ', \array_fill( 0, \count( $public_taxonomies ), '%s' ) );
133
134 $replacements = [ $this->version ];
135 \array_push( $replacements, ...$public_taxonomies );
136
137 // Warning: If this query is changed, makes sure to update the query in get_count_query as well.
138 return $this->wpdb->prepare(
139 "
140 SELECT COUNT(term_id)
141 FROM {$taxonomy_table} AS T
142 LEFT JOIN $indexable_table AS I
143 ON T.term_id = I.object_id
144 AND I.object_type = 'term'
145 AND I.version = %d
146 WHERE I.object_id IS NULL
147 AND taxonomy IN ($taxonomies_placeholders)",
148 $replacements
149 );
150 }
151
152 /**
153 * Builds a query for selecting the ID's of unindexed terms.
154 *
155 * @param bool $limit The maximum number of term IDs to return.
156 *
157 * @return string The prepared query string.
158 */
159 protected function get_select_query( $limit = false ) {
160 $indexable_table = Model::get_table_name( 'Indexable' );
161 $taxonomy_table = $this->wpdb->term_taxonomy;
162 $public_taxonomies = \array_keys( $this->taxonomy->get_public_taxonomies() );
163 $placeholders = \implode( ', ', \array_fill( 0, \count( $public_taxonomies ), '%s' ) );
164
165 $replacements = [ $this->version ];
166 \array_push( $replacements, ...$public_taxonomies );
167
168 $limit_query = '';
169 if ( $limit ) {
170 $limit_query = 'LIMIT %d';
171 $replacements[] = $limit;
172 }
173
174 // Warning: If this query is changed, makes sure to update the query in get_count_query as well.
175 return $this->wpdb->prepare(
176 "
177 SELECT term_id
178 FROM {$taxonomy_table} AS T
179 LEFT JOIN $indexable_table AS I
180 ON T.term_id = I.object_id
181 AND I.object_type = 'term'
182 AND I.version = %d
183 WHERE I.object_id IS NULL
184 AND taxonomy IN ($placeholders)
185 $limit_query",
186 $replacements
187 );
188 }
189 }
190