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

Yoast / wordpress-seo / e7606b2c7c941e9278931b2ecc427452c366faf0

25 Mar 2025 09:32AM UTC coverage: 41.43% (-7.3%) from 48.71%
e7606b2c7c941e9278931b2ecc427452c366faf0

Pull #22125

github

web-flow
Merge 16c76f3aa into facbdded4
Pull Request #22125: Add tracking of user progress in the Site Kit setup widged

2067 of 7841 branches covered (26.36%)

Branch coverage included in aggregate %.

92 of 122 new or added lines in 8 files covered. (75.41%)

1446 existing lines in 50 files now uncovered.

20534 of 46711 relevant lines covered (43.96%)

4.28 hits per line

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

89.33
/src/dashboard/infrastructure/integrations/site-kit.php
1
<?php
2
// phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure.
3
namespace Yoast\WP\SEO\Dashboard\Infrastructure\Integrations;
4

5
use Google\Site_Kit\Core\Authentication\Authentication;
6
use Google\Site_Kit\Plugin;
7
use Yoast\WP\SEO\Conditionals\Google_Site_Kit_Feature_Conditional;
8
use Yoast\WP\SEO\Dashboard\Infrastructure\Analytics_4\Site_Kit_Analytics_4_Adapter;
9
use Yoast\WP\SEO\Dashboard\Infrastructure\Configuration\Permanently_Dismissed_Site_Kit_Configuration_Repository_Interface as Configuration_Repository;
10
use Yoast\WP\SEO\Dashboard\Infrastructure\Configuration\Site_Kit_Consent_Repository_Interface;
11
use Yoast\WP\SEO\Dashboard\Infrastructure\Tracking\Site_Kit_Usage_Tracking_Repository_Interface;
12

13
/**
14
 * Describes if the Site kit integration is enabled and configured.
15
 */
16
class Site_Kit {
17

18
        private const SITE_KIT_FILE = 'google-site-kit/google-site-kit.php';
19

20
        /**
21
         * The Site Kit consent repository.
22
         *
23
         * @var Site_Kit_Consent_Repository_Interface
24
         */
25
        private $site_kit_consent_repository;
26

27
        /**
28
         * The Site Kit usage tracking repository.
29
         *
30
         * @var Site_Kit_Usage_Tracking_Repository_Interface
31
         */
32
        private $site_kit_usage_tracking_repository;
33

34
        /**
35
         * The Site Kit consent repository.
36
         *
37
         * @var Configuration_Repository
38
         */
39
        private $permanently_dismissed_site_kit_configuration_repository;
40

41
        /**
42
         * The Site Kit adapter.
43
         *
44
         * @var Site_Kit_Analytics_4_Adapter
45
         */
46
        private $site_kit_analytics_4_adapter;
47

48
        /**
49
         * The constructor.
50
         *
51
         * @param Site_Kit_Consent_Repository_Interface        $site_kit_consent_repository        The Site Kit consent repository.
52
         * @param Site_Kit_Usage_Tracking_Repository_Interface $site_kit_usage_tracking_repository The Site Kit usage tracking repository.
53
         * @param Configuration_Repository                     $configuration_repository           The Site Kit permanently dismissed
54
         *                                                                                         configuration repository.
55
         * @param Site_Kit_Analytics_4_Adapter                 $site_kit_analytics_4_adapter       The Site Kit adapter. Used to
56
         *                                                                                         determine if the setup is completed.
57
         */
58
        public function __construct(
12✔
59
                Site_Kit_Consent_Repository_Interface $site_kit_consent_repository,
60
                Site_Kit_Usage_Tracking_Repository_Interface $site_kit_usage_tracking_repository,
61
                Configuration_Repository $configuration_repository,
62
                Site_Kit_Analytics_4_Adapter $site_kit_analytics_4_adapter
63
        ) {
64
                $this->site_kit_consent_repository                             = $site_kit_consent_repository;
12✔
65
                $this->site_kit_usage_tracking_repository                      = $site_kit_usage_tracking_repository;
12✔
66
                $this->permanently_dismissed_site_kit_configuration_repository = $configuration_repository;
12✔
67
                $this->site_kit_analytics_4_adapter                            = $site_kit_analytics_4_adapter;
12✔
68
        }
2✔
69

70
        /**
71
         * If the integration is activated.
72
         *
73
         * @return bool If the integration is activated.
74
         */
75
        public function is_enabled(): bool {
16✔
76
                return \is_plugin_active( self::SITE_KIT_FILE );
16✔
77
        }
78

79
        /**
80
         * If the Google site kit setup has been completed.
81
         *
82
         * @return bool If the Google site kit setup has been completed.
83
         */
84
        private function is_setup_completed(): bool {
20✔
85
                if ( \class_exists( 'Google\Site_Kit\Plugin' ) ) {
20✔
86
                        $site_kit_plugin = Plugin::instance();
8✔
87
                        $authentication  = new Authentication( $site_kit_plugin->context() );
8✔
88
                        return $authentication->is_setup_completed();
8✔
89
                }
90

91
                return false;
12✔
92
        }
93

94
        /**
95
         * If consent has been granted.
96
         *
97
         * @return bool If consent has been granted.
98
         */
99
        private function is_connected() {
16✔
100
                return $this->site_kit_consent_repository->is_consent_granted();
16✔
101
        }
102

103
        /**
104
         * If Google analytics is connected.
105
         *
106
         * @return bool If Google analytics is connected.
107
         */
108
        public function is_ga_connected() {
16✔
109
                return $this->site_kit_analytics_4_adapter->is_connected();
16✔
110
        }
111

112
        /**
113
         * If the Site Kit plugin is installed. This is needed since we cannot check with `is_plugin_active` in rest
114
         * requests. `Plugin.php` is only loaded on admin pages.
115
         *
116
         * @return bool If the Site Kit plugin is installed.
117
         */
118
        private function is_site_kit_installed() {
12✔
119
                return \class_exists( 'Google\Site_Kit\Plugin' );
12✔
120
        }
121

122
        /**
123
         * If the entire onboarding has been completed.
124
         *
125
         * @return bool If the entire onboarding has been completed.
126
         */
127
        public function is_onboarded() {
12✔
128
                return ( $this->is_site_kit_installed() && $this->is_setup_completed() && $this->is_connected() );
12✔
129
        }
130

131
        /**
132
         * Checks is current user can view dashboard data, which can the owner who set it up,
133
         * or user with one of the shared roles.
134
         *
135
         * @param string $key The key of the data.
136
         * @return bool If the user can read the data.
137
         */
138
        private function can_read_data( $key ) {
12✔
139
                $current_user = \wp_get_current_user();
12✔
140
                // Check if the current user has one of the shared roles.
141
                $dashboard_sharing  = \get_option( 'googlesitekit_dashboard_sharing' );
12✔
142
                $shared_roles       = isset( $dashboard_sharing[ $key ] ) ? $dashboard_sharing[ $key ]['sharedRoles'] : [];
12✔
143
                $has_viewing_rights = \array_intersect( $current_user->roles, $shared_roles );
12✔
144

145
                // Check if the current user is the owner.
146
                $site_kit_settings = \get_option( 'googlesitekit_' . $key . '_settings' );
12✔
147
                $is_owner          = ( $site_kit_settings['ownerID'] ?? '' ) === $current_user->ID;
12✔
148

149
                return $is_owner || $has_viewing_rights;
12✔
150
        }
151

152
        /**
153
         * If the Site Kit setup widget has been loaded.
154
         *
155
         * @return string "yes" on "no".
156
         */
NEW
157
        public function get_setup_widget_loaded(): string {
×
NEW
158
                return $this->site_kit_usage_tracking_repository->get_site_kit_usage_tracking( 'setup_widget_loaded' );
×
159
        }
160

161
        /**
162
         * Gets the stage of the first interaction.
163
         *
164
         * @return string The stage name.
165
         */
NEW
166
        public function get_first_interaction_stage(): string {
×
NEW
167
                return $this->site_kit_usage_tracking_repository->get_site_kit_usage_tracking( 'first_interaction_stage' );
×
168
        }
169

170
        /**
171
         * Gets the stage of the last interaction.
172
         *
173
         * @return string The stage name.
174
         */
NEW
175
        public function get_last_interaction_stage(): string {
×
NEW
176
                return $this->site_kit_usage_tracking_repository->get_site_kit_usage_tracking( 'last_interaction_stage' );
×
177
        }
178

179
        /**
180
         * If the setup widget has been dismissed.
181
         *
182
         * @return string "yes" , "no", or "permanently".
183
         */
NEW
184
        public function get_setup_widget_dismissed(): string {
×
NEW
185
                return $this->site_kit_usage_tracking_repository->get_site_kit_usage_tracking( 'setup_widget_dismissed' );
×
186
        }
187

188
        /**
189
         * Return this object represented by a key value array.
190
         *
191
         * @return array<string, bool> Returns the name and if the feature is enabled.
192
         */
193
        public function to_array(): array {
12✔
194
                $site_kit_activate_url = \html_entity_decode(
12✔
195
                        \wp_nonce_url(
12✔
196
                                \self_admin_url( 'plugins.php?action=activate&plugin=' . self::SITE_KIT_FILE ),
12✔
197
                                'activate-plugin_' . self::SITE_KIT_FILE
12✔
198
                        )
6✔
199
                );
6✔
200

201
                $site_kit_install_url = \html_entity_decode(
12✔
202
                        \wp_nonce_url(
12✔
203
                                \self_admin_url( 'update.php?action=install-plugin&plugin=google-site-kit' ),
12✔
204
                                'install-plugin_google-site-kit'
12✔
205
                        )
6✔
206
                );
6✔
207

208
                $site_kit_setup_url = \self_admin_url( 'admin.php?page=googlesitekit-splash' );
12✔
209

210
                return [
6✔
211
                        'installUrl'               => $site_kit_install_url,
12✔
212
                        'activateUrl'              => $site_kit_activate_url,
12✔
213
                        'setupUrl'                 => $site_kit_setup_url,
12✔
214
                        'isAnalyticsConnected'     => $this->is_ga_connected(),
12✔
215
                        'isFeatureEnabled'         => ( new Google_Site_Kit_Feature_Conditional() )->is_met(),
12✔
216
                        'isConfigurationDismissed' => $this->permanently_dismissed_site_kit_configuration_repository->is_site_kit_configuration_dismissed(),
12✔
217
                        'setupWidgetLoaded'        => $this->get_setup_widget_loaded(),
12✔
218
                        'firstInteractionStage'    => $this->get_first_interaction_stage(),
12✔
219
                        'lastInteractionStage'     => $this->get_last_interaction_stage(),
12✔
220
                        'setupWidgetDismissed'     => $this->get_setup_widget_dismissed(),
12✔
221
                        'capabilities'             => [
6✔
222
                                'installPlugins'        => \current_user_can( 'install_plugins' ),
12✔
223
                                'viewSearchConsoleData' => $this->can_read_data( 'search-console' ),
12✔
224
                                'viewAnalyticsData'     => $this->can_read_data( 'analytics-4' ),
12✔
225
                        ],
6✔
226
                        'connectionStepsStatuses'  => [
6✔
227
                                'isInstalled'      => \file_exists( \WP_PLUGIN_DIR . '/' . self::SITE_KIT_FILE ),
12✔
228
                                'isActive'         => $this->is_enabled(),
12✔
229
                                'isSetupCompleted' => $this->is_setup_completed(),
12✔
230
                                'isConsentGranted' => $this->is_connected(),
12✔
231
                        ],
6✔
232
                ];
6✔
233
        }
234

235
        /**
236
         * Return this object represented by a key value array. This is not used yet.
237
         *
238
         * @codeCoverageIgnore
239
         *
240
         * @return array<string, bool> Returns the name and if the feature is enabled.
241
         */
242
        public function to_legacy_array(): array {
243
                return $this->to_array();
244
        }
245
}
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