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

Yoast / wordpress-seo / 23a72bf1994dab30060181382d0556bd26d909a7

21 Oct 2024 12:22PM UTC coverage: 54.571% (+0.002%) from 54.569%
23a72bf1994dab30060181382d0556bd26d909a7

Pull #21691

github

web-flow
Merge 6fe61e5b5 into 8a4aceaf1
Pull Request #21691: Remove conditional and rename dashboard to general page.

7549 of 13564 branches covered (55.65%)

Branch coverage included in aggregate %.

14 of 35 new or added lines in 17 files covered. (40.0%)

538 existing lines in 3 files now uncovered.

29672 of 54642 relevant lines covered (54.3%)

41714.17 hits per line

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

0.0
/src/integrations/admin/first-time-configuration-integration.php
1
<?php
2

3
namespace Yoast\WP\SEO\Integrations\Admin;
4

5
use WP_User;
6
use WPSEO_Addon_Manager;
7
use WPSEO_Admin_Asset_Manager;
8
use WPSEO_Option_Tab;
9
use WPSEO_Shortlinker;
10
use Yoast\WP\SEO\Conditionals\Admin_Conditional;
11
use Yoast\WP\SEO\Context\Meta_Tags_Context;
12
use Yoast\WP\SEO\General\User_Interface\General_Page_Integration;
13
use Yoast\WP\SEO\Helpers\Options_Helper;
14
use Yoast\WP\SEO\Helpers\Product_Helper;
15
use Yoast\WP\SEO\Helpers\Social_Profiles_Helper;
16
use Yoast\WP\SEO\Integrations\Integration_Interface;
17
use Yoast\WP\SEO\Routes\Indexing_Route;
18

19
/**
20
 * First_Time_Configuration_Integration class
21
 */
22
class First_Time_Configuration_Integration implements Integration_Interface {
23

24
        /**
25
         * The admin asset manager.
26
         *
27
         * @var WPSEO_Admin_Asset_Manager
28
         */
29
        private $admin_asset_manager;
30

31
        /**
32
         * The addon manager.
33
         *
34
         * @var WPSEO_Addon_Manager
35
         */
36
        private $addon_manager;
37

38
        /**
39
         * The shortlinker.
40
         *
41
         * @var WPSEO_Shortlinker
42
         */
43
        private $shortlinker;
44

45
        /**
46
         * The options' helper.
47
         *
48
         * @var Options_Helper
49
         */
50
        private $options_helper;
51

52
        /**
53
         * The social profiles helper.
54
         *
55
         * @var Social_Profiles_Helper
56
         */
57
        private $social_profiles_helper;
58

59
        /**
60
         * The product helper.
61
         *
62
         * @var Product_Helper
63
         */
64
        private $product_helper;
65

66
        /**
67
         * The meta tags context helper.
68
         *
69
         * @var Meta_Tags_Context
70
         */
71
        private $meta_tags_context;
72

73
        /**
74
         * {@inheritDoc}
75
         */
76
        public static function get_conditionals() {
×
77
                return [ Admin_Conditional::class ];
×
78
        }
79

80
        /**
81
         * First_Time_Configuration_Integration constructor.
82
         *
83
         * @param WPSEO_Admin_Asset_Manager $admin_asset_manager    The admin asset manager.
84
         * @param WPSEO_Addon_Manager       $addon_manager          The addon manager.
85
         * @param WPSEO_Shortlinker         $shortlinker            The shortlinker.
86
         * @param Options_Helper            $options_helper         The options helper.
87
         * @param Social_Profiles_Helper    $social_profiles_helper The social profile helper.
88
         * @param Product_Helper            $product_helper         The product helper.
89
         * @param Meta_Tags_Context         $meta_tags_context      The meta tags context helper.
90
         */
91
        public function __construct(
×
92
                WPSEO_Admin_Asset_Manager $admin_asset_manager,
93
                WPSEO_Addon_Manager $addon_manager,
94
                WPSEO_Shortlinker $shortlinker,
95
                Options_Helper $options_helper,
96
                Social_Profiles_Helper $social_profiles_helper,
97
                Product_Helper $product_helper,
98
                Meta_Tags_Context $meta_tags_context
99
        ) {
100
                $this->admin_asset_manager    = $admin_asset_manager;
×
101
                $this->addon_manager          = $addon_manager;
×
102
                $this->shortlinker            = $shortlinker;
×
103
                $this->options_helper         = $options_helper;
×
104
                $this->social_profiles_helper = $social_profiles_helper;
×
105
                $this->product_helper         = $product_helper;
×
106
                $this->meta_tags_context      = $meta_tags_context;
×
107
        }
108

109
        /**
110
         * {@inheritDoc}
111
         */
112
        public function register_hooks() {
×
113
                \add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
×
114
                \add_action( 'wpseo_settings_tabs_dashboard', [ $this, 'add_first_time_configuration_tab' ] );
×
115
        }
116

117
        /**
118
         * Adds a dedicated tab in the General sub-page.
119
         *
120
         * @param WPSEO_Options_Tabs $dashboard_tabs Object representing the tabs of the General sub-page.
121
         *
122
         * @return void
123
         */
124
        public function add_first_time_configuration_tab( $dashboard_tabs ) {
×
125
                $dashboard_tabs->add_tab(
×
126
                        new WPSEO_Option_Tab(
×
127
                                'first-time-configuration',
×
128
                                \__( 'First-time configuration', 'wordpress-seo' ),
×
129
                                [ 'save_button' => false ]
×
130
                        )
131
                );
132
        }
133

134
        /**
135
         * Adds the data for the first-time configuration to the wpseoFirstTimeConfigurationData object.
136
         *
137
         * @return void
138
         */
139
        public function enqueue_assets() {
×
140
                // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Date is not processed or saved.
NEW
141
                if ( ! isset( $_GET['page'] ) || ( $_GET['page'] !== 'wpseo_dashboard' && $_GET['page'] !== General_Page_Integration::PAGE ) || \is_network_admin() ) {
×
142
                        return;
×
143
                }
144

145
                $this->admin_asset_manager->enqueue_script( 'indexation' );
×
146
                $this->admin_asset_manager->enqueue_script( 'first-time-configuration' );
×
147
                $this->admin_asset_manager->enqueue_style( 'first-time-configuration' );
×
148
                $this->admin_asset_manager->enqueue_style( 'admin-css' );
×
149
                $this->admin_asset_manager->enqueue_style( 'monorepo' );
×
150

151
                $data = [
152
                        'disabled'     => ! \YoastSEO()->helpers->indexable->should_index_indexables(),
×
153
                        'amount'       => \YoastSEO()->helpers->indexing->get_filtered_unindexed_count(),
×
154
                        'firstTime'    => ( \YoastSEO()->helpers->indexing->is_initial_indexing() === true ),
×
155
                        'errorMessage' => '',
×
156
                        'restApi'      => [
157
                                'root'               => \esc_url_raw( \rest_url() ),
×
158
                                'indexing_endpoints' => $this->get_endpoints(),
×
159
                                'nonce'              => \wp_create_nonce( 'wp_rest' ),
×
160
                        ],
161
                ];
162

163
                /**
164
                 * Filter: 'wpseo_indexing_data' Filter to adapt the data used in the indexing process.
165
                 *
166
                 * @param array $data The indexing data to adapt.
167
                 */
168
                $data = \apply_filters( 'wpseo_indexing_data', $data );
×
169

170
                $this->admin_asset_manager->localize_script( 'indexation', 'yoastIndexingData', $data );
×
171

172
                $person_id       = $this->get_person_id();
×
173
                $social_profiles = $this->get_social_profiles();
×
174

175
                // This filter is documented in admin/views/tabs/metas/paper-content/general/knowledge-graph.php.
176
                $knowledge_graph_message = \apply_filters( 'wpseo_knowledge_graph_setting_msg', '' );
×
177

178
                $finished_steps        = $this->get_finished_steps();
×
179
                $options               = $this->get_company_or_person_options();
×
180
                $selected_option_label = '';
×
181
                $filtered_options      = \array_filter(
×
182
                        $options,
×
183
                        function ( $item ) {
184
                                return $item['value'] === $this->is_company_or_person();
×
185
                        }
186
                );
187
                $selected_option       = \reset( $filtered_options );
×
188
                if ( \is_array( $selected_option ) ) {
×
189
                        $selected_option_label = $selected_option['label'];
190
                }
191

192
                $data_ftc = [
193
                        'canEditUser'                => $this->can_edit_profile( $person_id ),
×
194
                        'companyOrPerson'            => $this->is_company_or_person(),
×
195
                        'companyOrPersonLabel'       => $selected_option_label,
×
196
                        'companyName'                => $this->get_company_name(),
×
197
                        'fallbackCompanyName'        => $this->get_fallback_company_name( $this->get_company_name() ),
×
198
                        'websiteName'                => $this->get_website_name(),
×
199
                        'fallbackWebsiteName'        => $this->get_fallback_website_name( $this->get_website_name() ),
×
200
                        'companyLogo'                => $this->get_company_logo(),
×
201
                        'companyLogoFallback'        => $this->get_company_fallback_logo( $this->get_company_logo() ),
×
202
                        'companyLogoId'              => $this->get_person_logo_id(),
×
203
                        'finishedSteps'              => $finished_steps,
×
204
                        'personId'                   => (int) $person_id,
×
205
                        'personName'                 => $this->get_person_name(),
×
206
                        'personLogo'                 => $this->get_person_logo(),
×
207
                        'personLogoFallback'         => $this->get_person_fallback_logo( $this->get_person_logo() ),
×
208
                        'personLogoId'               => $this->get_person_logo_id(),
×
209
                        'siteTagline'                => $this->get_site_tagline(),
210
                        'socialProfiles'             => [
211
                                'facebookUrl'     => $social_profiles['facebook_site'],
×
212
                                'twitterUsername' => $social_profiles['twitter_site'],
×
213
                                'otherSocialUrls' => $social_profiles['other_social_urls'],
214
                        ],
215
                        'isPremium'                  => $this->product_helper->is_premium(),
×
216
                        'tracking'                   => $this->has_tracking_enabled(),
×
217
                        'isTrackingAllowedMultisite' => $this->is_tracking_enabled_multisite(),
×
218
                        'isMainSite'                 => $this->is_main_site(),
×
219
                        'companyOrPersonOptions'     => $options,
×
220
                        'shouldForceCompany'         => $this->should_force_company(),
×
221
                        'knowledgeGraphMessage'      => $knowledge_graph_message,
222
                        'shortlinks'                 => [
223
                                'gdpr'                     => $this->shortlinker->build_shortlink( 'https://yoa.st/gdpr-config-workout' ),
×
224
                                'configIndexables'         => $this->shortlinker->build_shortlink( 'https://yoa.st/config-indexables' ),
×
225
                                'configIndexablesBenefits' => $this->shortlinker->build_shortlink( 'https://yoa.st/config-indexables-benefits' ),
226
                        ],
227
                ];
228

229
                $this->admin_asset_manager->localize_script( 'first-time-configuration', 'wpseoFirstTimeConfigurationData', $data_ftc );
×
230
        }
231

232
        /**
233
         * Retrieves a list of the endpoints to use.
234
         *
235
         * @return array The endpoints.
236
         */
237
        protected function get_endpoints() {
238
                $endpoints = [
239
                        'prepare'            => Indexing_Route::FULL_PREPARE_ROUTE,
240
                        'terms'              => Indexing_Route::FULL_TERMS_ROUTE,
241
                        'posts'              => Indexing_Route::FULL_POSTS_ROUTE,
242
                        'archives'           => Indexing_Route::FULL_POST_TYPE_ARCHIVES_ROUTE,
243
                        'general'            => Indexing_Route::FULL_GENERAL_ROUTE,
244
                        'indexablesComplete' => Indexing_Route::FULL_INDEXABLES_COMPLETE_ROUTE,
245
                        'post_link'          => Indexing_Route::FULL_POST_LINKS_INDEXING_ROUTE,
246
                        'term_link'          => Indexing_Route::FULL_TERM_LINKS_INDEXING_ROUTE,
247
                ];
248

249
                $endpoints = \apply_filters( 'wpseo_indexing_endpoints', $endpoints );
250

251
                $endpoints['complete'] = Indexing_Route::FULL_COMPLETE_ROUTE;
252

253
                return $endpoints;
254
        }
255

256
        // ** Private functions ** //
257

258
        /**
259
         * Returns the finished steps array.
260
         *
261
         * @return array An array with the finished steps.
262
         */
263
        private function get_finished_steps() {
264
                return $this->options_helper->get( 'configuration_finished_steps', [] );
265
        }
266

267
        /**
268
         * Returns the entity represented by the site.
269
         *
270
         * @return string The entity represented by the site.
271
         */
272
        private function is_company_or_person() {
273
                return $this->options_helper->get( 'company_or_person', '' );
274
        }
275

276
        /**
277
         * Gets the company name from the option in the database.
278
         *
279
         * @return string The company name.
280
         */
281
        private function get_company_name() {
282
                return $this->options_helper->get( 'company_name', '' );
283
        }
284

285
        /**
286
         * Gets the fallback company name from the option in the database if there is no company name.
287
         *
288
         * @param string $company_name The given company name by the user, default empty string.
289
         *
290
         * @return string|false The company name.
291
         */
292
        private function get_fallback_company_name( $company_name ) {
×
293
                if ( $company_name ) {
×
294
                        return false;
295
                }
296

297
                return \get_bloginfo( 'name' );
298
        }
299

300
        /**
301
         * Gets the website name from the option in the database.
302
         *
303
         * @return string The website name.
304
         */
305
        private function get_website_name() {
306
                return $this->options_helper->get( 'website_name', '' );
307
        }
308

309
        /**
310
         * Gets the fallback website name from the option in the database if there is no website name.
311
         *
312
         * @param string $website_name The given website name by the user, default empty string.
313
         *
314
         * @return string|false The website name.
315
         */
316
        private function get_fallback_website_name( $website_name ) {
×
317
                if ( $website_name ) {
×
318
                        return false;
319
                }
320

321
                return \get_bloginfo( 'name' );
322
        }
323

324
        /**
325
         * Gets the company logo from the option in the database.
326
         *
327
         * @return string The company logo.
328
         */
329
        private function get_company_logo() {
330
                return $this->options_helper->get( 'company_logo', '' );
331
        }
332

333
        /**
334
         * Gets the company logo id from the option in the database.
335
         *
336
         * @return string The company logo id.
337
         */
338
        private function get_company_logo_id() {
339
                return $this->options_helper->get( 'company_logo_id', '' );
340
        }
341

342
        /**
343
         * Gets the company logo url from the option in the database.
344
         *
345
         * @param string $company_logo The given company logo by the user, default empty.
346
         *
347
         * @return string|false The company logo URL.
348
         */
349
        private function get_company_fallback_logo( $company_logo ) {
×
350
                if ( $company_logo ) {
×
351
                        return false;
352
                }
353
                $logo_id = $this->meta_tags_context->fallback_to_site_logo();
354

355
                return \esc_url( \wp_get_attachment_url( $logo_id ) );
356
        }
357

358
        /**
359
         * Gets the person id from the option in the database.
360
         *
361
         * @return int|null The person id, null if empty.
362
         */
363
        private function get_person_id() {
364
                return $this->options_helper->get( 'company_or_person_user_id' );
365
        }
366

367
        /**
368
         * Gets the person id from the option in the database.
369
         *
370
         * @return int|null The person id, null if empty.
371
         */
372
        private function get_person_name() {
×
373
                $user = \get_userdata( $this->get_person_id() );
×
374
                if ( $user instanceof WP_User ) {
×
375
                        return $user->get( 'display_name' );
376
                }
377

378
                return '';
379
        }
380

381
        /**
382
         * Gets the person avatar from the option in the database.
383
         *
384
         * @return string The person logo.
385
         */
386
        private function get_person_logo() {
387
                return $this->options_helper->get( 'person_logo', '' );
388
        }
389

390
        /**
391
         * Gets the person logo url from the option in the database.
392
         *
393
         * @param string $person_logo The given person logo by the user, default empty.
394
         *
395
         * @return string|false The person logo URL.
396
         */
397
        private function get_person_fallback_logo( $person_logo ) {
×
398
                if ( $person_logo ) {
×
399
                        return false;
400
                }
401
                $logo_id = $this->meta_tags_context->fallback_to_site_logo();
402

403
                return \esc_url( \wp_get_attachment_url( $logo_id ) );
404
        }
405

406
        /**
407
         * Gets the person logo id from the option in the database.
408
         *
409
         * @return string The person logo id.
410
         */
411
        private function get_person_logo_id() {
412
                return $this->options_helper->get( 'person_logo_id', '' );
413
        }
414

415
        /**
416
         * Gets the site tagline.
417
         *
418
         * @return string The site tagline.
419
         */
420
        private function get_site_tagline() {
421
                return \get_bloginfo( 'description' );
422
        }
423

424
        /**
425
         * Gets the social profiles stored in the database.
426
         *
427
         * @return string[] The social profiles.
428
         */
429
        private function get_social_profiles() {
430
                return $this->social_profiles_helper->get_organization_social_profiles();
431
        }
432

433
        /**
434
         * Checks whether tracking is enabled.
435
         *
436
         * @return bool True if tracking is enabled, false otherwise, null if in Free and conf. workout step not finished.
437
         */
438
        private function has_tracking_enabled() {
×
439
                $default = false;
440

441
                if ( $this->product_helper->is_premium() ) {
×
442
                        $default = true;
443
                }
444

445
                return $this->options_helper->get( 'tracking', $default );
446
        }
447

448
        /**
449
         * Checks whether tracking option is allowed at network level.
450
         *
451
         * @return bool True if option change is allowed, false otherwise.
452
         */
453
        private function is_tracking_enabled_multisite() {
×
454
                $default = true;
455

456
                if ( ! \is_multisite() ) {
×
457
                        return $default;
458
                }
459

460
                return $this->options_helper->get( 'allow_tracking', $default );
461
        }
462

463
        /**
464
         * Checks whether we are in a main site.
465
         *
466
         * @return bool True if it's the main site or a single site, false if it's a subsite.
467
         */
468
        private function is_main_site() {
469
                return \is_main_site();
470
        }
471

472
        /**
473
         * Gets the options for the Company or Person select.
474
         * Returns only the company option if it is forced (by Local SEO), otherwise returns company and person option.
475
         *
476
         * @return array The options for the company-or-person select.
477
         */
478
        private function get_company_or_person_options() {
×
479
                $options = [
480
                        [
481
                                'label' => \__( 'Organization', 'wordpress-seo' ),
×
482
                                'value' => 'company',
×
483
                                'id'    => 'company',
484
                        ],
485
                        [
486
                                'label' => \__( 'Person', 'wordpress-seo' ),
×
487
                                'value' => 'person',
×
488
                                'id'    => 'person',
489
                        ],
490
                ];
491
                if ( $this->should_force_company() ) {
492
                        $options = [
493
                                [
494
                                        'label' => \__( 'Organization', 'wordpress-seo' ),
×
495
                                        'value' => 'company',
×
496
                                        'id'    => 'company',
497
                                ],
498
                        ];
499
                }
500

501
                return $options;
502
        }
503

504
        /**
505
         * Checks whether we should force "Organization".
506
         *
507
         * @return bool
508
         */
509
        private function should_force_company() {
510
                return $this->addon_manager->is_installed( WPSEO_Addon_Manager::LOCAL_SLUG );
511
        }
512

513
        /**
514
         * Checks if the current user has the capability to edit a specific user.
515
         *
516
         * @param int $person_id The id of the person to edit.
517
         *
518
         * @return bool
519
         */
520
        private function can_edit_profile( $person_id ) {
521
                return \current_user_can( 'edit_user', $person_id );
522
        }
523
}
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