Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue / 10169 Plugin Detection Logic #10209

Open
wants to merge 27 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6f931c1
Merge branch 'develop' of github.com:google/site-kit-wp into develop.
10upsimon Jan 28, 2025
5914f7c
Merge branch 'develop' of github.com:google/site-kit-wp into develop.
10upsimon Jan 29, 2025
6913e87
Merge branch 'develop' of github.com:google/site-kit-wp into develop.
10upsimon Feb 3, 2025
41bd763
Merge branch 'develop' of github.com:google/site-kit-wp into develop.
10upsimon Feb 10, 2025
1369812
Merge branch 'develop' of github.com:google/site-kit-wp into develop.
10upsimon Feb 11, 2025
abbce03
Add plugins output to base data.
10upsimon Feb 12, 2025
510e4ba
Update AssetsTest suite to cater for new base data.
10upsimon Feb 12, 2025
70ef21e
Update WooCommerce provider to user new Plugin_Status util.
10upsimon Feb 12, 2025
4d35d36
Update WooCommerceTest suite following integration of new Plugin_Stat…
10upsimon Feb 12, 2025
dc74e6f
Update REST_Consent_Mode_Controller to use new Plugin_Status util.
10upsimon Feb 12, 2025
5511753
Upate Sign_In_With_Google module entry point to use new Plugin_Status…
10upsimon Feb 12, 2025
ba4e30c
Create new Plugin_Status util class.
10upsimon Feb 12, 2025
235742a
Add basic test coverage for Plugin_Status class.
10upsimon Feb 12, 2025
b3f3ae2
Update activate_plugin helper method in Plugin_StatusTest.
10upsimon Feb 12, 2025
27ece88
Remove feature flag nesting for plugins inline data.
10upsimon Feb 13, 2025
9ccfeb9
Reorder use statements, remove unused imports.
10upsimon Feb 13, 2025
2c5ef80
Refactor WooCommerce active check into helper method and class property.
10upsimon Feb 13, 2025
8b68a2c
Clean up tests, remove unneeded methods after base data refactor.
10upsimon Feb 13, 2025
ff08035
Update plugins entries in base data to avoide kebab-case.
10upsimon Feb 13, 2025
2e3a626
Update AssetsTest class to expect newly renamed plugin keys.
10upsimon Feb 13, 2025
11c06a0
Move WooCommerce and Google for WooCommerce plugin base data logic in…
10upsimon Feb 13, 2025
d797ec3
Add static plugin_path property and store plugin path whether changed…
10upsimon Feb 13, 2025
688446c
Update URL value for GFW plugin.
10upsimon Feb 13, 2025
d4cd255
Get plugin path from Plugin_Status::.
10upsimon Feb 13, 2025
28b1a1b
Reinstante the feature flag check.
zutigrm Feb 13, 2025
f6a6a2b
Reinstate feature flag in tests.
zutigrm Feb 13, 2025
885bb24
Fix previously commited wrong key name.
zutigrm Feb 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions includes/Core/Assets/Assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Google\Site_Kit\Core\Util\URL;
use WP_Dependencies;
use WP_Post_Type;
use Google\Site_Kit\Core\Util\Plugin_Status;
zutigrm marked this conversation as resolved.
Show resolved Hide resolved

/**
* Class managing assets.
Expand Down Expand Up @@ -760,6 +761,54 @@ private function get_inline_base_data() {
'isMultisite' => is_multisite(),
);

if ( Feature_Flags::enabled( 'adsPax' ) ) {
$inline_data['plugins'] = array(
zutigrm marked this conversation as resolved.
Show resolved Hide resolved
'woocommerce' => array(
'installed' => false,
'active' => false,
),
'google-listings-and-ads' => array(
zutigrm marked this conversation as resolved.
Show resolved Hide resolved
'installed' => false,
'active' => false,
'adsConnected' => false,
),
);

// 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' );

switch ( $woocommerce_plugin_status ) {
case Plugin_Status::PLUGIN_STATUS_ACTIVE:
$inline_data['plugins']['woocommerce']['installed'] = true;
$inline_data['plugins']['woocommerce']['active'] = true;
break;
case Plugin_Status::PLUGIN_STATUS_INSTALLED:
$inline_data['plugins']['woocommerce']['installed'] = true;
$inline_data['plugins']['woocommerce']['active'] = false;
break;
}

switch ( $google_for_woocommerce_plugin_status ) {
case Plugin_Status::PLUGIN_STATUS_ACTIVE:
$inline_data['plugins']['google-listings-and-ads']['installed'] = true;
$inline_data['plugins']['google-listings-and-ads']['active'] = true;

zutigrm marked this conversation as resolved.
Show resolved Hide resolved
// Only check for the presence of Ads connection if plugin is active.
$gla_ads_id = get_option( 'gla_ads_id' );
if ( ! empty( $gla_ads_id ) ) {
$inline_data['plugins']['google-listings-and-ads']['adsConnected'] = true;
}
break;
case Plugin_Status::PLUGIN_STATUS_INSTALLED:
$inline_data['plugins']['google-listings-and-ads']['installed'] = true;
$inline_data['plugins']['google-listings-and-ads']['active'] = false;
break;
}
}

/**
* Filters the most basic inline data to pass to JS.
*
Expand Down
17 changes: 3 additions & 14 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,22 +198,10 @@ 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;
zutigrm marked this conversation as resolved.
Show resolved Hide resolved
$installed = true;
break;
}
}
}

// Alternate wp_nonce_url without esc_html breaking query parameters.
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
70 changes: 70 additions & 0 deletions includes/Core/Util/Plugin_Status.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?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.
*/
class Plugin_Status {

/**
* Plugin installed identifier.
*/
const PLUGIN_STATUS_INSTALLED = 'installed';

/**
* Plugin not active identifier.
*/
const PLUGIN_STATUS_ACTIVE = 'active';

/**
* Plugin not installed identifier.
*/
const PLUGIN_STATUS_NOT_INSTALLED = 'not-installed';

/**
* 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 = '' ) {
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 ) {
return static::PLUGIN_STATUS_INSTALLED;
}
}
}

return static::PLUGIN_STATUS_NOT_INSTALLED;
}
}
14 changes: 3 additions & 11 deletions includes/Modules/Sign_In_With_Google.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use Google\Site_Kit\Core\Assets\Assets;
use Google\Site_Kit\Core\Assets\Script;
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 @@ -32,6 +31,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 @@ -80,13 +80,6 @@ final class Sign_In_With_Google extends Module implements Module_With_Assets, Mo
*/
protected $existing_client_id;

/**
* WooCommerce instance.
*
* @since 1.146.0
* @var WooCommerce
*/
protected $woocommerce;

/**
* Constructor.
Expand All @@ -108,7 +101,6 @@ public function __construct(
) {
parent::__construct( $context, $options, $user_options, $authentication, $assets );
$this->existing_client_id = new Existing_Client_ID( $this->options );
$this->woocommerce = new WooCommerce( $this->context );
}

/**
Expand Down Expand Up @@ -558,7 +550,7 @@ public function get_tag_matchers() {
public function get_content_url() {
$wp_login_url = wp_login_url();

if ( $this->woocommerce->is_active() ) {
if ( Plugin_Status::PLUGIN_STATUS_ACTIVE === Plugin_Status::get_plugin_status( 'woocommerce/woocommerce.php', 'https://woocommerce.com/' ) ) {
$wc_login_page_id = wc_get_page_id( 'myaccount' );
$wc_login_url = get_permalink( $wc_login_page_id );
return array(
Expand Down Expand Up @@ -713,7 +705,7 @@ protected function inline_module_data( $modules_data ) {
$inline_data['existingClientID'] = $existing_client_id;
}

$is_woocommerce_active = $this->woocommerce->is_active();
$is_woocommerce_active = Plugin_Status::PLUGIN_STATUS_ACTIVE === Plugin_Status::get_plugin_status( 'woocommerce/woocommerce.php', 'https://woocommerce.com/' );
zutigrm marked this conversation as resolved.
Show resolved Hide resolved
$woocommerce_registration_enabled = $is_woocommerce_active ? get_option( 'woocommerce_enable_myaccount_registration' ) : null;

$inline_data['isWooCommerceActive'] = $is_woocommerce_active;
Expand Down
106 changes: 105 additions & 1 deletion tests/phpunit/integration/Core/Assets/AssetsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ class AssetsTest extends TestCase {
*/
private $assets;

/**
* Initial active plugin state array.
*/
private $initial_active_plugins_state;

// The actions and filters below only get registered for users that can
// authorize with Site Kit.
private $authorized_actions = array(
Expand All @@ -54,7 +59,8 @@ class AssetsTest extends TestCase {
public function set_up() {
parent::set_up();

$this->assets = new Assets( new Context( GOOGLESITEKIT_PLUGIN_MAIN_FILE ) );
$this->assets = new Assets( new Context( GOOGLESITEKIT_PLUGIN_MAIN_FILE ) );
$this->initial_active_plugins_state = $GLOBALS['wp_tests_options']['active_plugins'];

wp_scripts()->registered = array();
wp_scripts()->queue = array();
Expand All @@ -68,6 +74,39 @@ public function tear_down() {
if ( post_type_exists( 'product' ) ) {
unregister_post_type( 'product' );
}

$GLOBALS['wp_tests_options']['active_plugins'] = $this->initial_active_plugins_state;
}

protected function enable_feature( $feature ) {
$enable_callback = function ( $enabled, $feature_name ) use ( $feature ) {
if ( $feature_name === $feature ) {
return true;
}
return $enabled;
};

add_filter( 'googlesitekit_is_feature_enabled', $enable_callback, 10, 2 );

return function () use ( $enable_callback ) {
remove_filter( 'googlesitekit_is_feature_enabled', $enable_callback, 10 );
};
}
zutigrm marked this conversation as resolved.
Show resolved Hide resolved

public function activate_woocommerce() {
$GLOBALS['wp_tests_options']['active_plugins'][] = 'woocommerce/woocommerce.php';
}

public function deactivate_woocommerce() {
$GLOBALS['wp_tests_options']['active_plugins'] = $this->initial_active_plugins_state;
}

public function activate_google_for_woocommerce() {
$GLOBALS['wp_tests_options']['active_plugins'][] = 'google-listings-and-ads/google-listings-and-ads.php';
}

public function deactivate_google_for_woocommerce() {
$GLOBALS['wp_tests_options']['active_plugins'] = $this->initial_active_plugins_state;
}

public function test_register() {
Expand Down Expand Up @@ -276,4 +315,69 @@ public function test_base_data__product_post_type() {

$this->assertEquals( 'product', $data['productPostType'] );
}

public function test_base_data__plugins_default_data_with_ads_pax_feature_flag() {
self::enable_feature( 'adsPax' );
$data = $this->get_inline_base_data();
$default_plugins_data = array(
'woocommerce' => array(
'installed' => false,
'active' => false,
),
'google-listings-and-ads' => array(
'installed' => false,
'active' => false,
'adsConnected' => false,
),
);

$this->assertEquals( $default_plugins_data, $data['plugins'] );
}

public function test_base_data__plugins_default_data_without_ads_pax_feature_flag() {
$data = $this->get_inline_base_data();
$this->assertArrayNotHasKey( 'plugins', $data );
}

public function test_base_data__plugins_default_data_with_woocommerce_active() {
self::enable_feature( 'adsPax' );
$this->activate_woocommerce();
$data = $this->get_inline_base_data();
$default_plugins_data = array(
'woocommerce' => array(
'installed' => true,
'active' => true,
),
'google-listings-and-ads' => array(
'installed' => false,
'active' => false,
'adsConnected' => false,
),
);

$this->assertEquals( $default_plugins_data, $data['plugins'] );

$this->deactivate_woocommerce();
}

public function test_base_data__plugins_default_data_with_google_for_woocommerce_active() {
self::enable_feature( 'adsPax' );
$this->activate_google_for_woocommerce();
$data = $this->get_inline_base_data();
$default_plugins_data = array(
'woocommerce' => array(
'installed' => false,
'active' => false,
),
'google-listings-and-ads' => array(
'installed' => true,
'active' => true,
'adsConnected' => false,
),
);

$this->assertEquals( $default_plugins_data, $data['plugins'] );

$this->deactivate_google_for_woocommerce();
}
}
Loading
Loading