• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Yoast / wordpress-seo / 5066322038

pending completion
5066322038

push

github

GitHub
Merge pull request #20316 from Yoast/JRF/ghactions-run-more-selectively

2550 of 29012 relevant lines covered (8.79%)

0.32 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/commands/index-command.php
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
        protected function clear() {
275
                global $wpdb;
×
276

277
                // For the PreparedSQLPlaceholders issue, see: https://github.com/WordPress/WordPress-Coding-Standards/issues/1903.
278
                // For the DirectDBQuery issue, see: https://github.com/WordPress/WordPress-Coding-Standards/issues/1947.
279
                // phpcs:disable WordPress.DB -- Table names should not be quoted and truncate queries can not be cached.
280
                $wpdb->query(
×
281
                        $wpdb->prepare(
×
282
                                'TRUNCATE TABLE %1$s',
×
283
                                Model::get_table_name( 'Indexable' )
×
284
                        )
×
285
                );
×
286
                $wpdb->query(
×
287
                        $wpdb->prepare(
×
288
                                'TRUNCATE TABLE %1$s',
×
289
                                Model::get_table_name( 'Indexable_Hierarchy' )
×
290
                        )
×
291
                );
×
292
                // phpcs:enable
293
        }
294
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc