Skip to content

Commit

Permalink
Merge pull request #10209 from google/issue/10169-plugin-detection-logic
Browse files Browse the repository at this point in the history
Issue / 10169 Plugin Detection Logic
  • Loading branch information
tofumatt authored Feb 18, 2025
2 parents a5f136a + 6dd387f commit e8c41ae
Show file tree
Hide file tree
Showing 10 changed files with 416 additions and 40 deletions.
53 changes: 52 additions & 1 deletion includes/Core/Assets/Assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use Google\Site_Kit\Core\Permissions\Permissions;
use Google\Site_Kit\Core\Storage\Options;
use Google\Site_Kit\Core\Util\Feature_Flags;
use Google\Site_Kit\Core\Util\URL;
use Google\Site_Kit\Core\Util\Plugin_Status;
use WP_Dependencies;
use WP_Post_Type;

Expand Down Expand Up @@ -761,6 +761,22 @@ private function get_inline_base_data() {
'isMultisite' => is_multisite(),
);

if ( Feature_Flags::enabled( 'adsPax' ) ) {
$inline_data['plugins'] = array(
'wooCommerce' => array(
'installed' => false,
'active' => false,
),
'googleForWooCommerce' => array(
'installed' => false,
'active' => false,
'adsConnected' => false,
),
);

$inline_data = $this->update_plugins_inline_data( $inline_data );
}

/**
* Filters the most basic inline data to pass to JS.
*
Expand Down Expand Up @@ -1122,4 +1138,39 @@ protected function get_product_post_type() {

return null;
}

/**
* Updates the plugins inline data based on plugin status.
*
* @param array $inline_data The inline Site Kit base data.
* @since n.e.x.t
*
* @return array The inline data with plugins data modified.
*/
public function update_plugins_inline_data( $inline_data = array() ) {

// Get the status of the WooCommerce plugin.
$woocommerce_plugin_status = Plugin_Status::get_plugin_status( 'woocommerce/woocommerce.php', 'https://woocommerce.com/' );

// Get the status of the Google for WooCommerce plugin.
$google_for_woocommerce_plugin_status = Plugin_Status::get_plugin_status( 'google-listings-and-ads/google-listings-and-ads.php', 'https://wordpress.org/plugins/google-listings-and-ads/' );

$inline_data['plugins']['wooCommerce']['installed'] = Plugin_Status::PLUGIN_STATUS_INSTALLED === $woocommerce_plugin_status || Plugin_Status::PLUGIN_STATUS_ACTIVE === $woocommerce_plugin_status;
$inline_data['plugins']['wooCommerce']['active'] = Plugin_Status::PLUGIN_STATUS_ACTIVE === $woocommerce_plugin_status;

$inline_data['plugins']['googleForWooCommerce']['installed'] = Plugin_Status::PLUGIN_STATUS_INSTALLED === $google_for_woocommerce_plugin_status || Plugin_Status::PLUGIN_STATUS_ACTIVE === $google_for_woocommerce_plugin_status;
$inline_data['plugins']['googleForWooCommerce']['active'] = Plugin_Status::PLUGIN_STATUS_ACTIVE === $google_for_woocommerce_plugin_status;

// Only check for the presence of Ads connection if the "Google for
// Woo" plugin is active.
if ( $inline_data['plugins']['googleForWooCommerce']['active'] ) {
$gla_ads_id = get_option( 'gla_ads_id' );

if ( ! empty( $gla_ads_id ) ) {
$inline_data['plugins']['googleForWooCommerce']['adsConnected'] = true;
}
}

return $inline_data;
}
}
21 changes: 6 additions & 15 deletions includes/Core/Consent_Mode/REST_Consent_Mode_Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Google\Site_Kit\Core\REST_API\REST_Route;
use Google\Site_Kit\Core\REST_API\REST_Routes;
use Google\Site_Kit\Core\Storage\Options;
use Google\Site_Kit\Core\Util\Plugin_Status;
use Google\Site_Kit\Modules\Ads;
use Google\Site_Kit\Modules\Analytics_4;
use Google\Site_Kit\Modules\Analytics_4\Settings as Analytics_Settings;
Expand Down Expand Up @@ -197,30 +198,20 @@ protected function get_rest_routes() {
);

if ( ! $is_active ) {
if ( ! function_exists( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}

$plugins = get_plugins();
$consent_mode_plugin_status = Plugin_Status::get_plugin_status( $plugin, $plugin_uri );

if ( array_key_exists( $plugin, $plugins ) ) {
if ( Plugin_Status::PLUGIN_STATUS_INSTALLED === $consent_mode_plugin_status ) {
$installed = true;
} else {
foreach ( $plugins as $plugin_file => $installed_plugin ) {
if ( $installed_plugin['PluginURI'] === $plugin_uri ) {
$plugin = $plugin_file;
$installed = true;
break;
}
}
}

// Alternate wp_nonce_url without esc_html breaking query parameters.
$nonce_url = function ( $action_url, $action ) {
return add_query_arg( '_wpnonce', wp_create_nonce( $action ), $action_url );
};

$plugin = Plugin_Status::$plugin_path;
$activate_url = $nonce_url( self_admin_url( 'plugins.php?action=activate&plugin=' . $plugin ), 'activate-plugin_' . $plugin );
$install_url = $nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=wp-consent-api' ), 'install-plugin_wp-consent-api' );
$install_url = $nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=wp-consent-api' ), 'install-plugin_wp-consent-api' );

$response['wpConsentPlugin'] = array(
'installed' => $installed,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Google\Site_Kit\Core\Assets\Script;
use Google\Site_Kit\Core\Conversion_Tracking\Conversion_Events_Provider;
use Google\Site_Kit\Core\Util\BC_Functions;
use Google\Site_Kit\Core\Util\Plugin_Status;

/**
* Class for handling WooCommerce conversion events.
Expand All @@ -33,7 +34,7 @@ class WooCommerce extends Conversion_Events_Provider {
* @return bool True if WooCommerce is active, false otherwise.
*/
public function is_active() {
return did_action( 'woocommerce_loaded' ) > 0;
return Plugin_Status::PLUGIN_STATUS_ACTIVE === Plugin_Status::get_plugin_status( 'woocommerce/woocommerce.php', 'https://woocommerce.com/' );
}

/**
Expand Down
90 changes: 90 additions & 0 deletions includes/Core/Util/Plugin_Status.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?php
/**
* Class Google\Site_Kit\Core\Util\Plugin_Status
*
* @package Google\Site_Kit
* @copyright 2025 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://sitekit.withgoogle.com
*/

namespace Google\Site_Kit\Core\Util;

/**
* Plugin_Status class.
*
* @since n.e.x.t
*/
class Plugin_Status {

/**
* Plugin installed identifier.
*
* @since n.e.x.t
*/
const PLUGIN_STATUS_INSTALLED = 'installed';

/**
* Plugin not active identifier.
*
* @since n.e.x.t
*/
const PLUGIN_STATUS_ACTIVE = 'active';

/**
* Plugin not installed identifier.
*
* @since n.e.x.t
*/
const PLUGIN_STATUS_NOT_INSTALLED = 'not-installed';

/**
* The plugin path of the plugin being checked.
*
* @var string The plugin path of the plugin being checked.
*
* @since n.e.x.t
*/
public static $plugin_path;

/**
* Helper method to retrieve plugin installation/activation status.
*
* @param string $plugin_path The plugin path.
* @param string $plugin_url The plugin URL.
*
* @since n.e.x.t
*
* @return string The status of the plugin.
*/
public static function get_plugin_status( $plugin_path = '', $plugin_url = '' ) {
static::$plugin_path = $plugin_path;

if ( empty( $plugin_path ) && empty( $plugin_url ) ) {
return static::PLUGIN_STATUS_NOT_INSTALLED;
}

if ( ! function_exists( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}

if ( true === is_plugin_active( $plugin_path ) ) {
return static::PLUGIN_STATUS_ACTIVE;
}

$plugins = get_plugins();

if ( array_key_exists( $plugin_path, $plugins ) ) {
return static::PLUGIN_STATUS_INSTALLED;
} else {
foreach ( $plugins as $plugin_file => $installed_plugin ) {
if ( $installed_plugin['PluginURI'] === $plugin_url ) {
static::$plugin_path = $plugin_file;
return static::PLUGIN_STATUS_INSTALLED;
}
}
}

return static::PLUGIN_STATUS_NOT_INSTALLED;
}
}
35 changes: 23 additions & 12 deletions includes/Modules/Sign_In_With_Google.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use Google\Site_Kit\Core\Assets\Script;
use Google\Site_Kit\Core\Assets\Stylesheet;
use Google\Site_Kit\Core\Authentication\Authentication;
use Google\Site_Kit\Core\Conversion_Tracking\Conversion_Event_Providers\WooCommerce;
use Google\Site_Kit\Core\Modules\Module;
use Google\Site_Kit\Core\Modules\Module_With_Assets;
use Google\Site_Kit\Core\Modules\Module_With_Assets_Trait;
Expand All @@ -33,6 +32,7 @@
use Google\Site_Kit\Core\Storage\User_Options;
use Google\Site_Kit\Core\Util\BC_Functions;
use Google\Site_Kit\Core\Util\Method_Proxy_Trait;
use Google\Site_Kit\Core\Util\Plugin_Status;
use Google\Site_Kit\Modules\Sign_In_With_Google\Authenticator;
use Google\Site_Kit\Modules\Sign_In_With_Google\Authenticator_Interface;
use Google\Site_Kit\Modules\Sign_In_With_Google\Existing_Client_ID;
Expand Down Expand Up @@ -91,12 +91,13 @@ final class Sign_In_With_Google extends Module implements Module_With_Assets, Mo
protected $sign_in_with_google_block;

/**
* WooCommerce instance.
* Stores the active state of the WooCommerce plugin.
*
* @since 1.146.0
* @var WooCommerce
* @since n.e.x.t
* @var bool Whether WooCommerce is active or not.
*/
protected $woocommerce;
protected $is_woocommerce_active;


/**
* Constructor.
Expand All @@ -117,9 +118,10 @@ public function __construct(
Assets $assets = null
) {
parent::__construct( $context, $options, $user_options, $authentication, $assets );

$this->existing_client_id = new Existing_Client_ID( $this->options );
$this->is_woocommerce_active = $this->check_is_woocommerce_active();
$this->sign_in_with_google_block = new Sign_In_With_Google_Block( $this->context );
$this->woocommerce = new WooCommerce( $this->context );
}

/**
Expand Down Expand Up @@ -367,7 +369,7 @@ private function render_signinwithgoogle_woocommerce() {
* - WooCommerce is active
* - the user is not logged in
*/
if ( ! $this->is_connected() || ! $this->woocommerce->is_active() || is_user_logged_in() ) {
if ( ! $this->is_connected() || ! $this->is_woocommerce_active || is_user_logged_in() ) {
return;
}

Expand Down Expand Up @@ -622,7 +624,7 @@ public function get_tag_matchers() {
public function get_content_url() {
$wp_login_url = wp_login_url();

if ( $this->woocommerce->is_active() ) {
if ( $this->is_woocommerce_active ) {
$wc_login_page_id = wc_get_page_id( 'myaccount' );
$wc_login_url = get_permalink( $wc_login_page_id );
return array(
Expand Down Expand Up @@ -777,15 +779,24 @@ protected function inline_module_data( $modules_data ) {
$inline_data['existingClientID'] = $existing_client_id;
}

$is_woocommerce_active = $this->woocommerce->is_active();
$woocommerce_registration_enabled = $is_woocommerce_active ? get_option( 'woocommerce_enable_myaccount_registration' ) : null;
$woocommerce_registration_enabled = $this->is_woocommerce_active ? get_option( 'woocommerce_enable_myaccount_registration' ) : null;

$inline_data['isWooCommerceActive'] = $is_woocommerce_active;
$inline_data['isWooCommerceRegistrationEnabled'] = $is_woocommerce_active && 'yes' === $woocommerce_registration_enabled;
$inline_data['isWooCommerceActive'] = $this->is_woocommerce_active;
$inline_data['isWooCommerceRegistrationEnabled'] = $this->is_woocommerce_active && 'yes' === $woocommerce_registration_enabled;

// Add the data under the `sign-in-with-google` key to make it clear it's scoped to this module.
$modules_data['sign-in-with-google'] = $inline_data;

return $modules_data;
}

/**
* Helper method to determine if the WooCommerce plugin is active.
*
* @since n.e.x.t
* @return bool True if active, false if not.
*/
public function check_is_woocommerce_active() {
return Plugin_Status::PLUGIN_STATUS_ACTIVE === Plugin_Status::get_plugin_status( 'woocommerce/woocommerce.php', 'https://woocommerce.com/' );
}
}
42 changes: 42 additions & 0 deletions tests/phpunit/includes/PluginStatusTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php
/**
* PluginStatusTrait
*
* @package Google\Site_Kit\Tests
* @copyright 2025 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://sitekit.withgoogle.com
*/

namespace Google\Site_Kit\Tests;

trait PluginStatusTrait {

protected $active_plugins = array();

protected $active_plugins_callback;

public function activate_plugin( $plugin_path ) {
if ( ! in_array( $plugin_path, $this->active_plugins, true ) ) {
$this->active_plugins[] = $plugin_path;
}

if ( null === $this->active_plugins_callback ) {
$this->active_plugins_callback = array( $this, 'filter_active_plugins' );
add_filter( 'pre_option_active_plugins', $this->active_plugins_callback );
}
}

public function filter_active_plugins( $plugins ) {
return array_merge( $plugins, $this->active_plugins );
}

public function deactivate_all_test_plugins() {
if ( null !== $this->active_plugins_callback ) {
remove_filter( 'pre_option_active_plugins', $this->active_plugins_callback );
$this->active_plugins_callback = null;
}

$this->active_plugins = array();
}
}
Loading

0 comments on commit e8c41ae

Please sign in to comment.