Skip to content

Commit

Permalink
Merge branch 'develop' into track_search_events
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan0sz committed Jun 7, 2024
2 parents be64fe6 + 94e324b commit d206845
Show file tree
Hide file tree
Showing 12 changed files with 228 additions and 21 deletions.
16 changes: 10 additions & 6 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,28 +47,32 @@ Plausible is lightweight analytics. Our script is 45 times smaller than Google A

Plausible is privacy-friendly analytics. All the site measurement is carried out absolutely anonymously. Cookies are not used and no personal data is collected. There are no persistent identifiers. No cross-site or cross-device tracking either. Your site data is not used for any other purposes. All visitor data is exclusively processed with servers owned and operated by European companies and it never leaves the EU.

### Track goal conversions, revenue and campaigns
### Track events and marketing campaigns

Plausible is useful. Segment your audience by any metric you click on. Answer the important questions about your visitors, content and referral sources. Analyze paid campaigns using UTM parameters. Track WooCommerce revenue, outbound link clicks, file downloads and 404 error pages. Create custom events with custom dimensions to track conversions and attribution. Increase conversions using funnel analysis.
Plausible is useful. Segment your audience by any metric you click on. Answer the important questions about your visitors, content and referral sources. Analyze paid campaigns using UTM parameters. Track site search terms, outbound link clicks, file downloads, 404 error pages, post authors, post categories and custom taxonomies without manually configuring anything or writing any code.

### Built-in WooCommerce analytics

Plausible provides an automatic WooCommerce analytics solution to track conversions, revenue and attribution. Activities tracked include adding to cart, removing from cart, entering checkout and completing a purchase. A purchase funnel looking at the user journey from viewing a product to making a purchase is enabled to help you see the drop-off rates between the different steps, understand your cart abandonment rate and increase your conversions.

### Invite team members and share your dashboard

Plausible is shareable. Your stats are private by default but you can choose to be transparent and make them public so anyone with your custom link can view them. You can also share your stats privately by generating a secure link. This link is impossible to guess but you can add password protection for extra security. You can invite team members and assign user roles too.

### Transparent and open source software

Plausible is open source analytics. Our source code is available and accessible on GitHub so anyone can read it, inspect it and review it to verify that our actions match with our words. We welcome feedback and have a public roadmap. If you're happy to manage your own infrastructure, you can self-host Plausible too.
Plausible is open source analytics. Our source code is available and accessible on GitHub so anyone can read it, inspect it and review it to verify that our actions match with our words. We welcome feedback and have a public roadmap. If you're happy to manage your own infrastructure, you can self-host Plausible too.

## Features

* Our product is updated several times per week and with our WordPress plugin you always have access to all the latest features
* Automatically includes tracking code in the header of your site
* Simple plugin settings page with easy options and an onboarding guide
* Get more accurate stats by running the Plausible script as a first-party connection from your domain name
* Get more accurate stats and count those who use adblockers by running the Plausible script as a first-party connection from your domain name
* View your Plausible stats directly in your WordPress dashboard (you can grant access to other user roles too)
* Tracking of admin users is disabled by default (you can also disable tracking of other user roles)
* Enable ecommerce revenue, file downloads, external link clicks and 404 error pages tracking
* Enable automated tracking of post authors and post categories for better content analysis
* Enable WooCommerce revenue, file downloads, external link clicks, site search terms and 404 error pages tracking
* Enable automated tracking of post authors, post categories and custom taxonomies for better content analysis
* Custom events and custom dimensions can be setup using CSS class names directly in the WordPress editor
* Integrate with Google Search Console so you can see search queries people use to find your site in Google's search results
* Import your historical Google Analytics stats
Expand Down
2 changes: 1 addition & 1 deletion src/Admin/Provisioning.php
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ private function create_goals( $goals ) {
*/
public function maybe_create_woocommerce_goals( $old_settings, $settings ) {
if ( ! Helpers::is_enhanced_measurement_enabled( 'revenue', $settings[ 'enhanced_measurements' ] ) || ! Integrations::is_wc_active() ) {
return;
return; // @codeCoverageIgnore
}

$goals = [];
Expand Down
2 changes: 1 addition & 1 deletion src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public function validate_api_token() {
* Don't cache invalid API tokens.
*/
if ( $is_valid ) {
set_transient( 'plausible_analytics_valid_token', [ $token => true ], 86400 );
set_transient( 'plausible_analytics_valid_token', [ $token => true ], 86400 ); // @codeCoverageIgnore
}

return $is_valid;
Expand Down
3 changes: 3 additions & 0 deletions src/Compatibility.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@

use Exception;

/**
* @codeCoverageIgnore Because this is to be tested in a headless browser.
*/
class Compatibility {
/**
* A list of filters and actions to prevent our script from being manipulated by other plugins, known to cause issues.
Expand Down
2 changes: 1 addition & 1 deletion src/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ public static function is_enhanced_measurement_enabled( $name, $enhanced_measure
}

if ( ! is_array( $enhanced_measurements ) ) {
return false;
return false; // @codeCoverageIgnore
}

return in_array( $name, $enhanced_measurements );
Expand Down
7 changes: 5 additions & 2 deletions src/Integrations.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

namespace Plausible\Analytics\WP;

/**
* @codeCoverageIgnore Because the code is very straight-forward.
*/
class Integrations {
const SCRIPT_WRAPPER = '<script defer id="plausible-analytics-integration-tracking">document.addEventListener("DOMContentLoaded", () => { %s });</script>';

Expand Down Expand Up @@ -43,7 +46,7 @@ private function init() {
* @return bool
*/
public static function is_wc_active() {
return function_exists( 'WC' );
return apply_filters( 'plausible_analytics_integrations_woocommerce', function_exists( 'WC' ) );
}

/**
Expand All @@ -52,6 +55,6 @@ public static function is_wc_active() {
* @return bool
*/
public static function is_edd_active() {
return function_exists( 'EDD' );
return apply_filters( 'plausible_analytics_integrations_edd', function_exists( 'EDD' ) );
}
}
24 changes: 21 additions & 3 deletions src/Integrations/WooCommerce.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class WooCommerce {

/**
* Build class.
*
* @codeCoverageIgnore
*/
public function __construct( $init = true ) {
$this->event_goals = [
Expand All @@ -58,6 +60,8 @@ public function __construct( $init = true ) {
* Filter and action hooks.
*
* @return void
*
* @codeCoverageIgnore
*/
private function init( $init ) {
if ( ! $init ) {
Expand Down Expand Up @@ -85,11 +89,13 @@ private function init( $init ) {
* Enqueue required JS in frontend.
*
* @return void
*
* @codeCoverageIgnore Because there's nothing to test here.
*/
public function add_js() {
// Causes errors in checkout and isn't needed either way.
if ( is_checkout() ) {
return;
return; // @codeCoverageIgnore
}

wp_enqueue_script(
Expand All @@ -108,6 +114,8 @@ public function add_js() {
* @param $request
*
* @return mixed
*
* @codeCoverageIgnore Because there's nothing to test here.
*/
public function add_http_referer( $add_to_cart_data, $request ) {
$http_referer = $request->get_param( '_wp_http_referer' );
Expand All @@ -123,8 +131,9 @@ public function add_http_referer( $add_to_cart_data, $request ) {
* A hacky approach (with lack of a proper solution) to make sure Add To Cart events are tracked on simple product pages. Unfortunately, cart
* information isn't available this way.
*
*
* @return void
*
* @codeCoverageIgnore Because we're not testing JS here.
*/
public function track_add_to_cart_on_product_page() {
$product = wc_get_product();
Expand Down Expand Up @@ -153,6 +162,8 @@ public function track_add_to_cart_on_product_page() {
* @param string|int $product_id ID of the product added to the cart.
*
* @return void
*
* @codeCoverageIgnore Because we can't test XHR requests here.
*/
public function track_ajax_add_to_cart( $product_id ) {
$product = wc_get_product( $product_id );
Expand All @@ -171,6 +182,8 @@ public function track_ajax_add_to_cart( $product_id ) {
* @param array $add_to_cart_data Cart data for the product added to the cart, e.g. quantity, variation ID, etc.
*
* @return void
*
* @codeCoverageIgnore Because we can't test XHR requests here.
*/
public function track_add_to_cart( $product, $add_to_cart_data ) {
$product_data = $this->clean_data( $product->get_data() );
Expand Down Expand Up @@ -199,6 +212,8 @@ public function track_add_to_cart( $product, $add_to_cart_data ) {
* @param array $product Product Data.
*
* @return mixed
*
* @codeCoverageIgnore Because it can't be tested.
*/
private function clean_data( $product ) {
foreach ( $product as $key => $value ) {
Expand All @@ -217,6 +232,8 @@ private function clean_data( $product ) {
* @param WC_Cart $cart Instance of the current cart.
*
* @return void
*
* @codeCoverageIgnore because we can't test XHR requests here.
*/
public function track_remove_cart_item( $cart_item_key, $cart ) {
$cart_contents = $cart->get_cart_contents();
Expand Down Expand Up @@ -245,7 +262,8 @@ public function track_entered_checkout() {
return;
}

$cart = WC()->cart;
$cart = WC()->cart;

$props = apply_filters(
'plausible_analytics_woocommerce_entered_checkout_custom_properties',
[
Expand Down
2 changes: 1 addition & 1 deletion src/Plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function register_services() {
}

if ( Helpers::is_enhanced_measurement_enabled( 'revenue' ) ) {
new Integrations();
new Integrations(); // @codeCoverageIgnore
}

new Actions();
Expand Down
6 changes: 5 additions & 1 deletion src/Proxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public function do_request( $name = 'pageview', $domain = '', $url = '', $props
];

if ( ! empty( $props ) ) {
$body[ 'p' ] = $props;
$body[ 'p' ] = $props; // @codeCoverageIgnore
}

$request->set_body( wp_json_encode( $body ) );
Expand Down Expand Up @@ -189,6 +189,8 @@ private function header_exists( $global ) {
* Register the API route.
*
* @return void
*
* @codeCoverageIgnore Because we have no way of knowing if the API works in integration tests.
*/
public function register_route() {
register_rest_route(
Expand All @@ -214,6 +216,8 @@ public function register_route() {
* @param WP_REST_Request $request
*
* @return WP_HTTP_Response
*
* @codeCoverageIgnore
*/
public function force_http_response_code( $response, $server, $request ) {
if ( strpos( $request->get_route(), $this->namespace ) === false ) {
Expand Down
68 changes: 67 additions & 1 deletion tests/integration/Admin/ProvisioningTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Plausible\Analytics\WP\Client\Model\Goal;
use Plausible\Analytics\WP\Client\Model\GoalPageviewAllOfGoal;
use Plausible\Analytics\WP\Helpers;
use function Brain\Monkey\Functions\when;

class ProvisioningTest extends TestCase {
/**
Expand Down Expand Up @@ -49,7 +50,6 @@ public function testCreateSharedLink() {
* @throws ApiException
*/
public function testCreateGoals() {
$settings = [];
$settings[ 'enhanced_measurements' ] = [
'404',
'outbound-links',
Expand Down Expand Up @@ -92,5 +92,71 @@ public function testCreateGoals() {
$this->assertArrayHasKey( 111, $goal_ids );
$this->assertArrayHasKey( 222, $goal_ids );
$this->assertArrayHasKey( 333, $goal_ids );

delete_option( 'plausible_analytics_enhanced_measurements_goal_ids' );
}

/**
* @see Provisioning::maybe_create_woocommerce_goals()
* @return void
* @throws ApiException
*/
public function testCreateWooCommerceGoals() {
$settings = [
'enhanced_measurements' => [
'revenue',
],
];
$mock = $this->getMockBuilder( Client::class )->onlyMethods( [ 'create_goals' ] )->getMock();
$goals_array = [
new Goal(
[
'goal' => new GoalPageviewAllOfGoal( [ 'display_name' => 'Add Item To Cart', 'id' => 112, 'path' => null ] ),
'goal_type' => 'Goal.CustomEvent',
]
),
new Goal(
[
'goal' => new GoalPageviewAllOfGoal( [ 'display_name' => 'Remove Cart Item', 'id' => 223, 'path' => null ] ),
'goal_type' => 'Goal.CustomEvent',
]
),
new Goal(
[
'goal' => new GoalPageviewAllOfGoal( [ 'display_name' => 'Entered Checkout', 'id' => 334, 'path' => null ] ),
'goal_type' => 'Goal.CustomEvent',
]
),
new Goal(
[
'goal' => new GoalPageviewAllOfGoal( [ 'display_name' => 'Purchase', 'id' => 445, 'path' => null ] ),
'goal_type' => 'Goal.Revenue',
]
),
];
$goals = new Client\Model\GoalListResponse();

$goals->setGoals( $goals_array );
$goals->setMeta( new Client\Model\GoalListResponseMeta() );
$mock->method( 'create_goals' )->willReturn( $goals );

$class = new Provisioning( $mock );

add_filter( 'plausible_analytics_integrations_woocommerce', '__return_true' );
when( 'get_woocommerce_currency' )->justReturn( 'EUR' );

$class->maybe_create_woocommerce_goals( [], $settings );

remove_filter( 'plausible_analytics_integrations_woocommerce', '__return_true' );

$goal_ids = get_option( 'plausible_analytics_enhanced_measurements_goal_ids' );

$this->assertCount( 4, $goal_ids );
$this->assertArrayHasKey( 112, $goal_ids );
$this->assertArrayHasKey( 223, $goal_ids );
$this->assertArrayHasKey( 334, $goal_ids );
$this->assertArrayHasKey( 445, $goal_ids );

delete_option( 'plausible_analytics_enhanced_measurements_goal_ids' );
}
}
Loading

0 comments on commit d206845

Please sign in to comment.