PluginProbe
Yoast SEO – Advanced SEO with real-time guidance and built-in AI / 18.3
Yoast SEO – Advanced SEO with real-time guidance and built-in AI v18.3
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 18.3, at src/commands/index-command.php

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