diff --git a/src/Admin/Provisioning.php b/src/Admin/Provisioning.php index 37f3a29c..01ad9ccc 100644 --- a/src/Admin/Provisioning.php +++ b/src/Admin/Provisioning.php @@ -14,11 +14,17 @@ use Plausible\Analytics\WP\Client\Model\GoalCreateRequestCustomEvent; use Plausible\Analytics\WP\Client\Model\GoalCreateRequestPageview; use Plausible\Analytics\WP\Client\Model\GoalCreateRequestRevenue; +use Plausible\Analytics\WP\ClientFactory; use Plausible\Analytics\WP\Helpers; use Plausible\Analytics\WP\Integrations; use Plausible\Analytics\WP\Integrations\WooCommerce; class Provisioning { + /** + * @var ClientFactory + */ + private $client_factory; + /** * @var Client $client */ @@ -54,19 +60,11 @@ class Provisioning { * @codeCoverageIgnore */ public function __construct( $client = null ) { - /** - * cURL or allow_url_fopen ini setting is required for GuzzleHttp to function properly. - */ - if ( ! extension_loaded( 'curl' ) && ! ini_get( 'allow_url_fopen' ) ) { - add_action( 'init', [ $this, 'add_curl_error' ] ); - - return; - } - $this->client = $client; if ( ! $this->client ) { - $this->client = new Client(); + $this->client_factory = new ClientFactory(); + $this->client = $this->client_factory->build(); } $this->custom_event_goals = [ @@ -88,7 +86,7 @@ public function __construct( $client = null ) { * @codeCoverageIgnore */ private function init() { - if ( ! $this->client->validate_api_token() ) { + if ( ! $this->client instanceof Client || ! $this->client->validate_api_token() ) { return; // @codeCoverageIgnore } @@ -100,22 +98,6 @@ private function init() { add_action( 'update_option_plausible_analytics_settings', [ $this, 'maybe_create_custom_properties' ], 11, 2 ); } - /** - * Show an error on the settings screen if cURL isn't enabled on this machine. - * - * @return void - * - * @codeCoverageIgnore - */ - public function add_curl_error() { - Messages::set_error( - __( - 'cURL is not enabled on this server, which means API provisioning will not work. Please contact your hosting provider to enable the cURL module or allow_url_fopen.', - 'plausible-analytics' - ) - ); - } - /** * Create shared link when Enable Analytics Dashboard option is enabled. * @@ -347,6 +329,8 @@ public function maybe_delete_goals( $old_settings, $settings ) { * @param $settings * * @return void + * + * @codeCoverageIgnore Because we don't want to test if the API is working. */ public function maybe_delete_woocommerce_goals( $old_settings, $settings ) { $enhanced_measurements = array_filter( $settings[ 'enhanced_measurements' ] ); @@ -381,6 +365,8 @@ public function maybe_delete_woocommerce_goals( $old_settings, $settings ) { * @param array $haystack * * @return false|mixed + * + * @codeCoverageIgnore Because it can't be unit tested. */ private function array_search_contains( $string, $haystack ) { if ( preg_match( '/\([A-Z]*?\)/', $string ) ) { diff --git a/src/Admin/Settings/Page.php b/src/Admin/Settings/Page.php index bcfb35b0..56aba5c2 100644 --- a/src/Admin/Settings/Page.php +++ b/src/Admin/Settings/Page.php @@ -12,6 +12,7 @@ use Exception; use Plausible\Analytics\WP\Client; +use Plausible\Analytics\WP\ClientFactory; use Plausible\Analytics\WP\Helpers; class Page extends API { @@ -59,6 +60,11 @@ class Page extends API { */ public $fields = []; + /** + * @var ClientFactory $client_factory + */ + private $client_factory; + /** * @var Client $client */ @@ -77,8 +83,9 @@ public function __construct() { $settings = Helpers::get_settings(); - $this->client = new Client(); - $this->fields = [ + $this->client_factory = new ClientFactory(); + $this->client = $this->client_factory->build(); + $this->fields = [ 'general' => [ [ 'label' => esc_html__( 'Connect your website with Plausible Analytics', 'plausible-analytics' ), @@ -118,6 +125,7 @@ public function __construct() { 'type' => 'button', 'disabled' => empty( $settings[ 'domain_name' ] ) || empty( $settings[ 'api_token' ] ) || + ! $this->client instanceof Client || $this->client->is_api_token_valid(), ], ], diff --git a/src/Ajax.php b/src/Ajax.php index 273c70a7..dc41a717 100644 --- a/src/Ajax.php +++ b/src/Ajax.php @@ -313,9 +313,10 @@ public function save_options() { * @throws ApiException */ private function validate_api_token( $token = '' ) { - $client = new Client( $token ); + $client_factory = new ClientFactory( $token ); + $client = $client_factory->build(); - if ( ! $client->validate_api_token() ) { + if ( $client instanceof Client && ! $client->validate_api_token() ) { $hosted_domain = Helpers::get_hosted_domain_url(); $domain = Helpers::get_domain(); diff --git a/src/ClientFactory.php b/src/ClientFactory.php new file mode 100644 index 00000000..ab33cb33 --- /dev/null +++ b/src/ClientFactory.php @@ -0,0 +1,55 @@ +token = $token; + } + + /** + * Loads the Client class if all conditions are met. + * + * @return false|Client + */ + public function build() { + /** + * cURL or allow_url_fopen ini setting is required for GuzzleHttp to function properly. + */ + if ( ! extension_loaded( 'curl' ) && ! ini_get( 'allow_url_fopen' ) ) { + add_action( 'init', [ $this, 'add_curl_error' ] ); // @codeCoverageIgnore + + return false; // @codeCoverageIgnore + } + + return new Client( $this->token ); + } + + /** + * Show an error on the settings screen if cURL isn't enabled on this machine. + * + * @return void + * + * @codeCoverageIgnore + */ + public function add_curl_error() { + Messages::set_error( + __( + 'cURL is not enabled on this server, which means API provisioning will not work. Please contact your hosting provider to enable the cURL module or allow_url_fopen.', + 'plausible-analytics' + ) + ); + } +} diff --git a/src/Filters.php b/src/Filters.php index 0b9a9774..213cc0d9 100644 --- a/src/Filters.php +++ b/src/Filters.php @@ -27,7 +27,6 @@ class Filters { */ public function __construct() { add_filter( 'script_loader_tag', [ $this, 'add_plausible_attributes' ], 10, 2 ); - add_filter( 'rest_url', [ $this, 'wpml_compatibility' ], 10, 1 ); add_filter( 'plausible_analytics_script_params', [ $this, 'maybe_add_custom_params' ] ); } @@ -43,7 +42,7 @@ public function __construct() { * @return string */ public function add_plausible_attributes( $tag, $handle ) { - // Bailout, if not `Plausible Analytics` script. + // Bail if it's not our script. if ( 'plausible-analytics' !== $handle ) { return $tag; // @codeCoverageIgnore } @@ -61,8 +60,8 @@ public function add_plausible_attributes( $tag, $handle ) { // Triggered when exclude pages is enabled. if ( ! empty( $settings[ 'excluded_pages' ] ) && $settings[ 'excluded_pages' ] ) { - $excluded_pages = $settings[ 'excluded_pages' ]; - $params .= " data-exclude='{$excluded_pages}'"; + $excluded_pages = $settings[ 'excluded_pages' ]; // @codeCoverageIgnore + $params .= " data-exclude='{$excluded_pages}'"; // @codeCoverageIgnore } $params = apply_filters( 'plausible_analytics_script_params', $params ); @@ -70,25 +69,6 @@ public function add_plausible_attributes( $tag, $handle ) { return str_replace( ' src', " {$params} src", $tag ); } - /** - * WPML overrides the REST API URL to include the language 'subdirectory', which leads to 404s. - * This forces it back to default behavior. - * - * @param mixed $url - * - * @return string|void - * @throws Exception - */ - public function wpml_compatibility( $url ) { - $rest_endpoint = Helpers::get_rest_endpoint( false ); - - if ( strpos( $url, $rest_endpoint ) !== false ) { - return get_option( 'home' ) . $rest_endpoint; // @codeCoverageIgnore - } - - return $url; - } - /** * Adds custom parameters Author and Category if Custom Pageview Properties is enabled. * diff --git a/src/Integrations/WooCommerce.php b/src/Integrations/WooCommerce.php index afd53f7a..67dfa840 100644 --- a/src/Integrations/WooCommerce.php +++ b/src/Integrations/WooCommerce.php @@ -264,7 +264,7 @@ public function track_remove_cart_item( $cart_item_key, $cart ) { */ public function track_entered_checkout() { if ( ! is_checkout() ) { - return; + return; // @codeCoverageIgnore } $cart = WC()->cart; @@ -298,7 +298,7 @@ public function track_purchase( $order_id ) { $is_tracked = $order->get_meta( self::PURCHASE_TRACKED_META_KEY ); if ( $is_tracked ) { - return; + return; // @codeCoverageIgnore } $props = wp_json_encode( diff --git a/tests/unit/ClientFactoryTest.php b/tests/unit/ClientFactoryTest.php new file mode 100644 index 00000000..06d1211a --- /dev/null +++ b/tests/unit/ClientFactoryTest.php @@ -0,0 +1,22 @@ +build(); + + $this->assertInstanceOf( Client::class, $client ); + } +}