PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 27.9
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v27.9
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 / commands / index-command.php

index-command.php in Yoast SEO – Advanced SEO with real-time guidance and built-in AI 27.9, at src/commands/index-command.php

297 lines 9.9 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\Commands;
4
5 use WP_CLI;
6 use WP_CLI\Utils;
7 use Yoast\WP\Lib\Model;
8 use Yoast\WP\SEO\Actions\Indexing\Indexable_General_Indexation_Action;
9 use Yoast\WP\SEO\Actions\Indexing\Indexable_Indexing_Complete_Action;
10 use Yoast\WP\SEO\Actions\Indexing\Indexable_Post_Indexation_Action;
11 use Yoast\WP\SEO\Actions\Indexing\Indexable_Post_Type_Archive_Indexation_Action;
12 use Yoast\WP\SEO\Actions\Indexing\Indexable_Term_Indexation_Action;
13 use Yoast\WP\SEO\Actions\Indexing\Indexation_Action_Interface;
14 use Yoast\WP\SEO\Actions\Indexing\Indexing_Prepare_Action;
15 use Yoast\WP\SEO\Actions\Indexing\Post_Link_Indexing_Action;
16 use Yoast\WP\SEO\Actions\Indexing\Term_Link_Indexing_Action;
17 use Yoast\WP\SEO\Helpers\Indexable_Helper;
18 use Yoast\WP\SEO\Main;
19
20 /**
21 * Command to generate indexables for all posts and terms.
22 */
23 class Index_Command implements Command_Interface {
24
25 /**
26 * The post indexation action.
27 *
28 * @var Indexable_Post_Indexation_Action
29 */
30 private $post_indexation_action;
31
32 /**
33 * The term indexation action.
34 *
35 * @var Indexable_Term_Indexation_Action
36 */
37 private $term_indexation_action;
38
39 /**
40 * The post type archive indexation action.
41 *
42 * @var Indexable_Post_Type_Archive_Indexation_Action
43 */
44 private $post_type_archive_indexation_action;
45
46 /**
47 * The general indexation action.
48 *
49 * @var Indexable_General_Indexation_Action
50 */
51 private $general_indexation_action;
52
53 /**
54 * The term link indexing action.
55 *
56 * @var Term_Link_Indexing_Action
57 */
58 private $term_link_indexing_action;
59
60 /**
61 * The post link indexing action.
62 *
63 * @var Post_Link_Indexing_Action
64 */
65 private $post_link_indexing_action;
66
67 /**
68 * The complete indexation action.
69 *
70 * @var Indexable_Indexing_Complete_Action
71 */
72 private $complete_indexation_action;
73
74 /**
75 * The indexing prepare action.
76 *
77 * @var Indexing_Prepare_Action
78 */
79 private $prepare_indexing_action;
80
81 /**
82 * Represents the indexable helper.
83 *
84 * @var Indexable_Helper
85 */
86 protected $indexable_helper;
87
88 /**
89 * Generate_Indexables_Command constructor.
90 *
91 * @param Indexable_Post_Indexation_Action $post_indexation_action The post indexation
92 * action.
93 * @param Indexable_Term_Indexation_Action $term_indexation_action The term indexation
94 * action.
95 * @param Indexable_Post_Type_Archive_Indexation_Action $post_type_archive_indexation_action The post type archive
96 * indexation action.
97 * @param Indexable_General_Indexation_Action $general_indexation_action The general indexation
98 * action.
99 * @param Indexable_Indexing_Complete_Action $complete_indexation_action The complete indexation
100 * action.
101 * @param Indexing_Prepare_Action $prepare_indexing_action The prepare indexing
102 * action.
103 * @param Post_Link_Indexing_Action $post_link_indexing_action The post link indexation
104 * action.
105 * @param Term_Link_Indexing_Action $term_link_indexing_action The term link indexation
106 * action.
107 * @param Indexable_Helper $indexable_helper The indexable helper.
108 */
109 public function __construct(
110 Indexable_Post_Indexation_Action $post_indexation_action,
111 Indexable_Term_Indexation_Action $term_indexation_action,
112 Indexable_Post_Type_Archive_Indexation_Action $post_type_archive_indexation_action,
113 Indexable_General_Indexation_Action $general_indexation_action,
114 Indexable_Indexing_Complete_Action $complete_indexation_action,
115 Indexing_Prepare_Action $prepare_indexing_action,
116 Post_Link_Indexing_Action $post_link_indexing_action,
117 Term_Link_Indexing_Action $term_link_indexing_action,
118 Indexable_Helper $indexable_helper
119 ) {
120 $this->post_indexation_action = $post_indexation_action;
121 $this->term_indexation_action = $term_indexation_action;
122 $this->post_type_archive_indexation_action = $post_type_archive_indexation_action;
123 $this->general_indexation_action = $general_indexation_action;
124 $this->complete_indexation_action = $complete_indexation_action;
125 $this->prepare_indexing_action = $prepare_indexing_action;
126 $this->post_link_indexing_action = $post_link_indexing_action;
127 $this->term_link_indexing_action = $term_link_indexing_action;
128 $this->indexable_helper = $indexable_helper;
129 }
130
131 /**
132 * Gets the namespace.
133 *
134 * @return string
135 */
136 public static function get_namespace() {
137 return Main::WP_CLI_NAMESPACE;
138 }
139
140 /**
141 * Indexes all your content to ensure the best performance.
142 *
143 * ## OPTIONS
144 *
145 * [--network]
146 * : Performs the indexation on all sites within the network.
147 *
148 * [--reindex]
149 * : Removes all existing indexables and then reindexes them.
150 *
151 * [--skip-confirmation]
152 * : Skips the confirmations (for automated systems).
153 *
154 * [--interval=<interval>]
155 * : The number of microseconds (millionths of a second) to wait between index actions.
156 * ---
157 * default: 500000
158 * ---
159 *
160 * ## EXAMPLES
161 *
162 * wp yoast index
163 *
164 * @when after_wp_load
165 *
166 * @param array|null $args The arguments.
167 * @param array|null $assoc_args The associative arguments.
168 *
169 * @return void
170 */
171 public function index( $args = null, $assoc_args = null ) {
172 if ( ! $this->indexable_helper->should_index_indexables() ) {
173 WP_CLI::log(
174 \__( 'Your WordPress environment is running on a non-production site. Indexables can only be created on production environments. Please check your `WP_ENVIRONMENT_TYPE` settings.', 'wordpress-seo' ),
175 );
176
177 return;
178 }
179
180 if ( ! isset( $assoc_args['network'] ) ) {
181 $this->run_indexation_actions( $assoc_args );
182
183 return;
184 }
185
186 $criteria = [
187 'fields' => 'ids',
188 'spam' => 0,
189 'deleted' => 0,
190 'archived' => 0,
191 ];
192 $blog_ids = \get_sites( $criteria );
193
194 foreach ( $blog_ids as $blog_id ) {
195 \switch_to_blog( $blog_id );
196 \do_action( '_yoast_run_migrations' );
197 $this->run_indexation_actions( $assoc_args );
198 \restore_current_blog();
199 }
200 }
201
202 /**
203 * Runs all indexation actions.
204 *
205 * @param array $assoc_args The associative arguments.
206 *
207 * @return void
208 */
209 protected function run_indexation_actions( $assoc_args ) {
210 // See if we need to clear all indexables before repopulating.
211 if ( isset( $assoc_args['reindex'] ) ) {
212
213 // Argument --skip-confirmation to prevent confirmation (for automated systems).
214 if ( ! isset( $assoc_args['skip-confirmation'] ) ) {
215 WP_CLI::confirm( 'This will clear all previously indexed objects. Are you certain you wish to proceed?' );
216 }
217
218 // Truncate the tables.
219 $this->clear();
220
221 // Delete the transients to make sure re-indexing runs every time.
222 \delete_transient( Indexable_Post_Indexation_Action::UNINDEXED_COUNT_TRANSIENT );
223 \delete_transient( Indexable_Post_Type_Archive_Indexation_Action::UNINDEXED_COUNT_TRANSIENT );
224 \delete_transient( Indexable_Term_Indexation_Action::UNINDEXED_COUNT_TRANSIENT );
225 }
226
227 $indexation_actions = [
228 'posts' => $this->post_indexation_action,
229 'terms' => $this->term_indexation_action,
230 'post type archives' => $this->post_type_archive_indexation_action,
231 'general objects' => $this->general_indexation_action,
232 'post links' => $this->post_link_indexing_action,
233 'term links' => $this->term_link_indexing_action,
234 ];
235
236 $this->prepare_indexing_action->prepare();
237
238 $interval = (int) $assoc_args['interval'];
239 foreach ( $indexation_actions as $name => $indexation_action ) {
240 $this->run_indexation_action( $name, $indexation_action, $interval );
241 }
242
243 $this->complete_indexation_action->complete();
244 }
245
246 /**
247 * Runs an indexation action.
248 *
249 * @param string $name The name of the object to be indexed.
250 * @param Indexation_Action_Interface $indexation_action The indexation action.
251 * @param int $interval Number of microseconds (millionths of a second) to wait between index actions.
252 *
253 * @return void
254 */
255 protected function run_indexation_action( $name, Indexation_Action_Interface $indexation_action, $interval ) {
256 $total = $indexation_action->get_total_unindexed();
257 if ( $total > 0 ) {
258 $limit = $indexation_action->get_limit();
259 $progress = Utils\make_progress_bar( 'Indexing ' . $name, $total );
260 do {
261 $indexables = $indexation_action->index();
262 $count = \count( $indexables );
263 $progress->tick( $count );
264 \usleep( $interval );
265 Utils\wp_clear_object_cache();
266 } while ( $count >= $limit );
267 $progress->finish();
268 }
269 }
270
271 /**
272 * Clears the database related to the indexables.
273 *
274 * @return void
275 */
276 protected function clear() {
277 global $wpdb;
278
279 // For the PreparedSQLPlaceholders issue, see: https://github.com/WordPress/WordPress-Coding-Standards/issues/1903.
280 // For the DirectDBQuery issue, see: https://github.com/WordPress/WordPress-Coding-Standards/issues/1947.
281 // phpcs:disable WordPress.DB -- Table names should not be quoted and truncate queries can not be cached.
282 $wpdb->query(
283 $wpdb->prepare(
284 'TRUNCATE TABLE %1$s',
285 Model::get_table_name( 'Indexable' ),
286 ),
287 );
288 $wpdb->query(
289 $wpdb->prepare(
290 'TRUNCATE TABLE %1$s',
291 Model::get_table_name( 'Indexable_Hierarchy' ),
292 ),
293 );
294 // phpcs:enable
295 }
296 }
297