<?php // phpcs:disable Yoast.NamingConventions.NamespaceName.TooLong -- Needed in the folder structure. namespace Yoast\WP\SEO\Dashboard\Infrastructure\Integrations; use Google\Site_Kit\Core\Authentication\Authentication; use Google\Site_Kit\Plugin; use Yoast\WP\SEO\Conditionals\Google_Site_Kit_Feature_Conditional; use Yoast\WP\SEO\Dashboard\Infrastructure\Analytics_4\Site_Kit_Analytics_4_Adapter; use Yoast\WP\SEO\Dashboard\Infrastructure\Configuration\Permanently_Dismissed_Site_Kit_Configuration_Repository_Interface as Configuration_Repository; use Yoast\WP\SEO\Dashboard\Infrastructure\Configuration\Site_Kit_Consent_Repository_Interface; /** * Describes if the Site kit integration is enabled and configured. */ class Site_Kit { private const SITE_KIT_FILE = 'google-site-kit/google-site-kit.php'; /** * The Site Kit consent repository. * * @var Site_Kit_Consent_Repository_Interface */ private $site_kit_consent_repository; /** * The Site Kit consent repository. * * @var Configuration_Repository */ private $permanently_dismissed_site_kit_configuration_repository; /** * The Site Kit adapter. * * @var Site_Kit_Analytics_4_Adapter */ private $site_kit_analytics_4_adapter; /** * The constructor. * * @param Site_Kit_Consent_Repository_Interface $site_kit_consent_repository The Site Kit consent repository. * @param Configuration_Repository $configuration_repository The Site Kit permanently dismissed * configuration repository. * @param Site_Kit_Analytics_4_Adapter $site_kit_analytics_4_adapter The Site Kit adapter. Used to * determine if the setup is completed. */ public function __construct( Site_Kit_Consent_Repository_Interface $site_kit_consent_repository, Configuration_Repository $configuration_repository, Site_Kit_Analytics_4_Adapter $site_kit_analytics_4_adapter ) { $this->site_kit_consent_repository = $site_kit_consent_repository; $this->permanently_dismissed_site_kit_configuration_repository = $configuration_repository; $this->site_kit_analytics_4_adapter = $site_kit_analytics_4_adapter; } /** * If the integration is activated. * * @return bool If the integration is activated. */ public function is_enabled(): bool { return \is_plugin_active( self::SITE_KIT_FILE ); } /** * If the Google site kit setup has been completed. * * @return bool If the Google site kit setup has been completed. */ private function is_setup_completed(): bool { if ( \class_exists( 'Google\Site_Kit\Plugin' ) ) { $site_kit_plugin = Plugin::instance(); $authentication = new Authentication( $site_kit_plugin->context() ); return $authentication->is_setup_completed(); } return false; } /** * If consent has been granted. * * @return bool If consent has been granted. */ private function is_connected() { return $this->site_kit_consent_repository->is_consent_granted(); } /** * If Google analytics is connected. * * @return bool If Google analytics is connected. */ public function is_ga_connected() { return $this->site_kit_analytics_4_adapter->is_connected(); } /** * If the Site Kit plugin is installed. This is needed since we cannot check with `is_plugin_active` in rest * requests. `Plugin.php` is only loaded on admin pages. * * @return bool If the Site Kit plugin is installed. */ private function is_site_kit_installed() { return \class_exists( 'Google\Site_Kit\Plugin' ); } /** * If the entire onboarding has been completed. * * @return bool If the entire onboarding has been completed. */ public function is_onboarded() { return ( $this->is_site_kit_installed() && $this->is_setup_completed() && $this->is_connected() ); } /** * Checks is current user can view dashboard data, which can the owner who set it up, * or user with one of the shared roles. * * @param string $key The key of the data. * @return bool If the user can read the data. */ private function can_read_data( $key ) { $current_user = \wp_get_current_user(); // Check if the current user has one of the shared roles. $dashboard_sharing = \get_option( 'googlesitekit_dashboard_sharing' ); $shared_roles = ( isset( $dashboard_sharing[ $key ]['sharedRoles'] ) ) ? $dashboard_sharing[ $key ]['sharedRoles'] : []; $has_viewing_rights = ( \is_array( $shared_roles ) ) ? \array_intersect( $current_user->roles, $shared_roles ) : false; // Check if the current user is the owner. $site_kit_settings = \get_option( 'googlesitekit_' . $key . '_settings' ); $is_owner = ( $site_kit_settings['ownerID'] ?? '' ) === $current_user->ID; return $is_owner || $has_viewing_rights; } /** * Return this object represented by a key value array. * * @return array<string, bool> Returns the name and if the feature is enabled. */ public function to_array(): array { $site_kit_activate_url = \html_entity_decode( \wp_nonce_url( \self_admin_url( 'plugins.php?action=activate&plugin=' . self::SITE_KIT_FILE ), 'activate-plugin_' . self::SITE_KIT_FILE ) ); $site_kit_install_url = \html_entity_decode( \wp_nonce_url( \self_admin_url( 'update.php?action=install-plugin&plugin=google-site-kit' ), 'install-plugin_google-site-kit' ) ); $site_kit_update_url = \html_entity_decode( \wp_nonce_url( \self_admin_url( 'update.php?action=upgrade-plugin&plugin=' . self::SITE_KIT_FILE ), 'upgrade-plugin_' . self::SITE_KIT_FILE ) ); $site_kit_setup_url = \self_admin_url( 'admin.php?page=googlesitekit-splash' ); return [ 'installUrl' => $site_kit_install_url, 'activateUrl' => $site_kit_activate_url, 'setupUrl' => $site_kit_setup_url, 'updateUrl' => $site_kit_update_url, 'isAnalyticsConnected' => $this->is_ga_connected(), 'isFeatureEnabled' => ( new Google_Site_Kit_Feature_Conditional() )->is_met(), 'isConfigurationDismissed' => $this->permanently_dismissed_site_kit_configuration_repository->is_site_kit_configuration_dismissed(), 'capabilities' => [ 'installPlugins' => \current_user_can( 'install_plugins' ), 'viewSearchConsoleData' => $this->can_read_data( 'search-console' ), 'viewAnalyticsData' => $this->can_read_data( 'analytics-4' ), ], 'connectionStepsStatuses' => [ 'isInstalled' => \file_exists( \WP_PLUGIN_DIR . '/' . self::SITE_KIT_FILE ), 'isActive' => $this->is_enabled(), 'isSetupCompleted' => $this->is_setup_completed(), 'isConsentGranted' => $this->is_connected(), ], 'isVersionSupported' => \defined( 'GOOGLESITEKIT_VERSION' ) ? \version_compare( \GOOGLESITEKIT_VERSION, '1.148.0', '>=' ) : false, ]; } /** * Return this object represented by a key value array. This is not used yet. * * @codeCoverageIgnore * * @return array<string, bool> Returns the name and if the feature is enabled. */ public function to_legacy_array(): array { return $this->to_array(); } }