Skip to content

Commit ff2f330

Browse files
committed
Merge branch 'develop' into defer_plausible_js
2 parents 9519317 + 199e89a commit ff2f330

File tree

9 files changed

+161
-55
lines changed

9 files changed

+161
-55
lines changed

README.md

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,45 @@
44

55
[![Github CI](https://github.com/plausible/wordpress/actions/workflows/push.yml/badge.svg)](https://github.com/plausible/wordpress/actions/workflows/push.yml) ![WordPress version](https://img.shields.io/wordpress/plugin/v/plausible-analytics.svg) ![WordPress Rating](https://img.shields.io/wordpress/plugin/r/plausible-analytics.svg) ![WordPress Downloads](https://img.shields.io/wordpress/plugin/dt/plausible-analytics.svg)
66

7-
Welcome to the Plausible Analytics WordPress Plugin GitHub repository. This is the code source and the center of active development. Here you can
7+
Welcome to the Plausible Analytics WordPress Plugin GitHub repository. This is the code source and the center of active
8+
development. Here you can
89
browse the source, look at open issues, and contribute to the project.
910

1011
## Getting Started
1112

1213
If you're looking to contribute or actively develop on Plausible Analytics then skip ahead to
13-
the [Local Development](https://github.com/plausible/wordpress/#local-development) section below. The following is if you're looking to actively use
14+
the [Local Development](https://github.com/plausible/wordpress/#local-development) section below. The following is if
15+
you're looking to actively use
1416
the plugin on your WordPress site.
1517

1618
### Minimum Requirements
1719

18-
* WordPress 5.3 or greater
20+
* WordPress 5.9 or greater
1921
* PHP version 7.4 or greater
2022
* MySQL version 5.5 or greater
2123

2224
### Automatic installation
2325

24-
Automatic installation is the easiest option as WordPress handles the file transfers itself, and you don't need to leave your web browser. To do an
25-
automatic installation of Plausible Analytics, log in to your WordPress dashboard, navigate to the Plugins menu and click "Add New".
26+
Automatic installation is the easiest option as WordPress handles the file transfers itself, and you don't need to leave
27+
your web browser. To do an
28+
automatic installation of Plausible Analytics, log in to your WordPress dashboard, navigate to the Plugins menu and
29+
click "Add New".
2630

27-
In the search field type "Plausible Analytics" and click Search Plugins. Once you have found the plugin you can view details about it such as the
31+
In the search field type "Plausible Analytics" and click Search Plugins. Once you have found the plugin you can view
32+
details about it such as the
2833
point release, rating and description. Most importantly of course, you can install it by simply clicking "Install Now".
2934

3035
### Manual installation
3136

32-
The manual installation method involves downloading our plugin and uploading it to your server via your favorite FTP application. The
33-
WordPress codex contains [instructions on how to do this](https://codex.wordpress.org/Managing_Plugins#Manual_Plugin_Installation).
37+
The manual installation method involves downloading our plugin and uploading it to your server via your favorite FTP
38+
application. The
39+
WordPress codex
40+
contains [instructions on how to do this](https://codex.wordpress.org/Managing_Plugins#Manual_Plugin_Installation).
3441

3542
### Support
3643

37-
This repository is not suitable for support. Please don't use GitHub issues for support requests. To get support please use the following channels:
44+
This repository is not suitable for support. Please don't use GitHub issues for support requests. To get support please
45+
use the following channels:
3846

3947
* [WP.org Support Forums](https://wordpress.org/support/plugin/plausible-analytics) - for all users
4048

@@ -45,25 +53,33 @@ This repository is not suitable for support. Please don't use GitHub issues for
4553
- `plausible_analytics_settings`: Allows you to modify and/or force values for each of the plugin's settings.
4654
- `plausible_load_js_in_footer`: Allows you to load the JS code snippet in the footer.
4755
- `plausible_analytics_script_params`: Allows you to modify the `script` element, loading the Plausible JS library.
48-
- Example: using this filter and the `file-types` attribute will allow you to track downloads of certain file types when File Downloads tracking is
56+
- Example: using this filter and the `file-types` attribute will allow you to track downloads of certain file types
57+
when File Downloads tracking is
4958
enabled.
50-
- `plausible_analytics_pageview_properties`: Allows you to add custom pageview properties when the Pageview Properties option is enabled under
51-
Enhanced Measurements. For examples, read the [documentation on Pageview Properties](https://plausible.io/docs/custom-props/for-pageviews).
59+
- `plausible_analytics_pageview_properties`: Allows you to add custom pageview properties when the Pageview Properties
60+
option is enabled under
61+
Enhanced Measurements. For examples, read
62+
the [documentation on Pageview Properties](https://plausible.io/docs/custom-props/for-pageviews).
5263

5364
### Actions
5465

5566
- `plausible_analytics_settings_saved`: Trigger additional tasks directly after settings are saved.
56-
- `plausible_analytics_after_register_assets`: This action allows you to trigger additional tasks or add custom JS (e.g. events) to the tracking code.
67+
- `plausible_analytics_after_register_assets`: This action allows you to trigger additional tasks or add custom JS (e.g.
68+
events) to the tracking code.
5769

5870
### Toggles
5971

60-
Using constants, you can modify the behavior of the plugin. `wp-config.php` is the best place to define constants. If you're using a custom plugin,
72+
Using constants, you can modify the behavior of the plugin. `wp-config.php` is the best place to define constants. If
73+
you're using a custom plugin,
6174
make sure its code is loaded before this plugin.
6275

63-
- `PLAUSIBLE_SELF_HOSTED_DOMAIN`: Especially useful for Multisite instances using the self-hosted version of Plausible, this constant allows you to
64-
specify the Self-Hosted Domain for all subsites at once. **IMPORTANT**: this constant takes precedence over the plugin's setting. So, if this
76+
- `PLAUSIBLE_SELF_HOSTED_DOMAIN`: Especially useful for Multisite instances using the self-hosted version of Plausible,
77+
this constant allows you to
78+
specify the Self-Hosted Domain for all subsites at once. **IMPORTANT**: this constant takes precedence over the
79+
plugin's setting. So, if this
6580
constant is defined, changing the setting won't have any effect.
66-
- `plausible_proxy`: Appending this `GET`-parameter will force enable the proxy on the page you\'re calling it. This will allow you to test your proxy
81+
- `plausible_proxy`: Appending this `GET`-parameter will force enable the proxy on the page you\'re calling it. This
82+
will allow you to test your proxy
6783
in the frontend, before enabling the option.
6884

6985
## Local Development
@@ -83,15 +99,17 @@ That's it. You're now ready to start development.
8399

84100
Plausible Analytics relies on several npm commands to get you started:
85101

86-
* `npm run watch` - Live reloads JS and SASS files. Typically, you'll run this command before you start development. It's necessary to build the
102+
* `npm run watch` - Live reloads JS and SASS files. Typically, you'll run this command before you start development.
103+
It's necessary to build the
87104
JS/CSS
88105
however if you're working strictly within PHP it may not be necessary to run.
89106
* `npm run dev` - Runs a one time build for development. No production files are created.
90107
* `npm run production` - Builds the minified production files for release.
91108

92109
### Development Notes
93110

94-
* Ensure that you have `SCRIPT_DEBUG` enabled within your wp-config.php file. Here's a good example of wp-config.php for debugging:
111+
* Ensure that you have `SCRIPT_DEBUG` enabled within your wp-config.php file. Here's a good example of wp-config.php for
112+
debugging:
95113
```
96114
// Enable WP_DEBUG mode
97115
define( 'WP_DEBUG', true );
@@ -103,21 +121,27 @@ Plausible Analytics relies on several npm commands to get you started:
103121
define( 'SCRIPT_DEBUG', true );
104122
```
105123
* Commit the `package.lock` file. Read more about why [here](https://docs.npmjs.com/files/package-lock.json).
106-
* Your editor should recognize the `.eslintrc` and `.editorconfig` files within the Repo's root directory. Please only submit PRs following those
124+
* Your editor should recognize the `.eslintrc` and `.editorconfig` files within the Repo's root directory. Please only
125+
submit PRs following those
107126
coding style rulesets.
108127
109128
### Regenerating the OpenAPI PHP Client
110129
111-
This plugin uses a OpenAPI PHP Client which is autogenerated by the OpenAPI generator to reduce contract violations, etc. to a minimum. But, since
112-
this is a WordPress plugin, some manual modifications need to be done to make sure it doesn't conflict with other plugins:
130+
This plugin uses a OpenAPI PHP Client which is autogenerated by the OpenAPI generator to reduce contract violations,
131+
etc. to a minimum. But, since
132+
this is a WordPress plugin, some manual modifications need to be done to make sure it doesn't conflict with other
133+
plugins:
113134
114-
- (Re)generate the PHP client using the following command (trigger it from the Plugin's root dir as output will be saved to `src/Client`):
135+
- (Re)generate the PHP client using the following command (trigger it from the Plugin's root dir as output will be saved
136+
to `src/Client`):
115137
`openapi-generator-cli generate -i https://plausible.io/api/plugins/spec/openapi -g php -o src/Client --additional-properties=identifierNamingConvention=snake_case,invokerPackage="Plausible\\Analytics\\WP\\Client" --global-property=apis,models,supportingFiles,modelDocs=false,modelTests=false,apiDocs=false,apiTests=false`
116138
- (When regenerating the PHP client this step can be skipped) Navigate to the `src/Client` director and install Composer
117139
dependencies: `composer install --no-dev`
118-
- (When regenerating the PHP client this step can be skipped) Run `mozart compose` from the `src/Client` directory (Make sure Mozart is installed
140+
- (When regenerating the PHP client this step can be skipped) Run `mozart compose` from the `src/Client` directory (Make
141+
sure Mozart is installed
119142
globally)
120-
- In the `src/Client/lib` directory, replace all occurrences of ` GuzzleHttp` (mind the space) with ` Plausible\Analytics\WP\Client\Lib\GuzzleHttp` (
143+
- In the `src/Client/lib` directory, replace all occurrences of ` GuzzleHttp` (mind the space) with
144+
` Plausible\Analytics\WP\Client\Lib\GuzzleHttp` (
121145
again, mind the space at the beginning)
122146
- In the same directory, replace all occurrences of ` \GuzzleHttp` (mind the space and backslash)
123147
with ` \Plausible\Analytics\WP\Client\Lib\GuzzleHttp`.

readme.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ Contributors: plausible, DaanvandenBergh
33
Donate link: https://plausible.io/
44
Tags: analytics, google analytics, web analytics, stats, privacy
55
Requires at least: 5.9
6-
Tested up to: 6.6
7-
Requires PHP: 7.0
6+
Tested up to: 6.7
7+
Requires PHP: 7.2
88
Stable tag: 2.3.0
99
License: Massachusetts Institute of Technology (MIT) license
1010
License URI: https://opensource.org/licenses/MIT

src/Cron.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@
1313
use Exception;
1414

1515
class Cron {
16+
/**
17+
* Cron job handle
18+
*
19+
* @var string
20+
*/
21+
const TASK_NAME = 'plausible_analytics_update_js';
22+
1623
/**
1724
* Build class
1825
*

src/Integrations/WooCommerce.php

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,10 @@ private function init( $init ) {
6969
*/
7070
add_action( 'woocommerce_before_add_to_cart_quantity', [ $this, 'add_cart_form_hidden_input' ] );
7171
add_action( 'woocommerce_after_add_to_cart_form', [ $this, 'track_add_to_cart_on_product_page' ] );
72-
add_filter( 'woocommerce_store_api_validate_add_to_cart', [ $this, 'track_add_to_cart' ], 10, 2 );
73-
add_filter( 'woocommerce_ajax_added_to_cart', [ $this, 'track_ajax_add_to_cart' ] );
72+
add_action( 'woocommerce_store_api_validate_add_to_cart', [ $this, 'track_add_to_cart' ], 10, 2 );
73+
add_action( 'woocommerce_ajax_added_to_cart', [ $this, 'track_ajax_add_to_cart' ] );
74+
/** @see \WC_Form_Handler::add_to_cart_action() runs on priority 20. */
75+
add_action( 'wp_loaded', [ $this, 'track_direct_add_to_cart' ], 21 );
7476
add_action( 'woocommerce_remove_cart_item', [ $this, 'track_remove_cart_item' ], 10, 2 );
7577
add_action( 'wp_head', [ $this, 'track_entered_checkout' ] );
7678
add_action( 'woocommerce_thankyou', [ $this, 'track_purchase' ] );
@@ -173,22 +175,22 @@ public function track_add_to_cart_on_product_page() {
173175
}
174176

175177
/**
176-
* Track (non-Interactivity API, i.e. AJAX) add to cart events.
177-
*
178-
* @param string|int $product_id ID of the product added to the cart.
178+
* Track add to cart actions by direct link, e.g. ?product_type=download&add-to-cart=1&quantity=1
179179
*
180180
* @return void
181181
*
182-
* @codeCoverageIgnore Because we can't test XHR requests here.
182+
* @codeCoverageIgnore Because we can't test XHR here.
183183
*/
184-
public function track_ajax_add_to_cart( $product_id ) {
185-
$product = wc_get_product( $product_id );
186-
$add_to_cart_data = [
187-
'id' => $product_id,
188-
'quantity' => $_POST[ 'quantity' ] ?? 1,
189-
];
184+
public function track_direct_add_to_cart() {
185+
if ( ! isset( $_REQUEST[ 'add-to-cart' ] ) || ! is_numeric( wp_unslash( $_REQUEST[ 'add-to-cart' ] ) ) ) {
186+
return;
187+
}
190188

191-
$this->track_add_to_cart( $product, $add_to_cart_data );
189+
$product_id = absint( wp_unslash( $_REQUEST[ 'add-to-cart' ] ) );
190+
$product = wc_get_product( $product_id );
191+
$quantity = isset( $_REQUEST[ 'quantity' ] ) ? absint( wp_unslash( $_REQUEST[ 'quantity' ] ) ) : 1;
192+
193+
$this->track_add_to_cart( $product, [ 'id' => $product_id, 'quantity' => $quantity ] );
192194
}
193195

194196
/**
@@ -241,6 +243,25 @@ private function clean_data( $product ) {
241243
return $product;
242244
}
243245

246+
/**
247+
* Track (non-Interactivity API, i.e. AJAX) add to cart events.
248+
*
249+
* @param string|int $product_id ID of the product added to the cart.
250+
*
251+
* @return void
252+
*
253+
* @codeCoverageIgnore Because we can't test XHR requests here.
254+
*/
255+
public function track_ajax_add_to_cart( $product_id ) {
256+
$product = wc_get_product( $product_id );
257+
$add_to_cart_data = [
258+
'id' => $product_id,
259+
'quantity' => $_POST[ 'quantity' ] ?? 1,
260+
];
261+
262+
$this->track_add_to_cart( $product, $add_to_cart_data );
263+
}
264+
244265
/**
245266
* Track Remove from cart events.
246267
*

src/Plugin.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,22 @@ final class Plugin {
1616
* @return void
1717
*/
1818
public function register() {
19+
$this->setup();
20+
1921
// Register services used throughout the plugin. (WP Rocket runs at priority 10)
2022
add_action( 'plugins_loaded', [ $this, 'register_services' ], 9 );
2123

2224
// Load text domain.
23-
add_action( 'init', [ $this, 'load_plugin_textdomain' ] );
25+
add_action( 'init', [ $this, 'load_plugin_textdomain' ], 1000 );
26+
}
27+
28+
/**
29+
* Register plugin (de)activation hooks and cron job.
30+
*
31+
* @return void
32+
*/
33+
public function setup() {
34+
new Setup();
2435
}
2536

2637
/**
@@ -47,7 +58,6 @@ public function register_services() {
4758
new Compatibility();
4859
new Filters();
4960
new Proxy();
50-
new Setup();
5161
}
5262

5363
/**

src/Proxy.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ public function do_request( $name = 'pageview', $domain = '', $url = '', $props
112112
'u' => $url ?: wp_get_referer(),
113113
];
114114

115+
// URL is required, so if no $url was set and no referer was found, attempt to create it from the REQUEST_URI server variable.
116+
if ( empty( $body[ 'u' ] ) ) {
117+
$body[ 'u' ] = $this->generate_event_url(); // @codeCoverageIgnore
118+
}
119+
115120
// Revenue events use a different approach.
116121
if ( isset( $props[ 'revenue' ] ) ) {
117122
$body[ 'revenue' ] = reset( $props ); // @codeCoverageIgnore
@@ -124,6 +129,23 @@ public function do_request( $name = 'pageview', $domain = '', $url = '', $props
124129
return $this->send_event( $request );
125130
}
126131

132+
/**
133+
* Attempts to generate the Event URL from available resources.
134+
*
135+
* @return string
136+
*/
137+
public function generate_event_url() {
138+
$url = '';
139+
$parts = parse_url( $_SERVER[ 'REQUEST_URI' ] );
140+
$home_url_parts = parse_url( get_home_url() );
141+
142+
if ( isset( $home_url_parts[ 'scheme' ] ) && isset( $home_url_parts[ 'host' ] ) && isset( $parts[ 'path' ] ) ) {
143+
$url = $home_url_parts[ 'scheme' ] . '://' . $home_url_parts [ 'host' ] . $parts[ 'path' ];
144+
}
145+
146+
return $url;
147+
}
148+
127149
/**
128150
* Formats and sends $request to the Plausible API.
129151
*

src/Setup.php

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@
1010
namespace Plausible\Analytics\WP;
1111

1212
class Setup {
13-
/**
14-
* Cron job handle
15-
*
16-
* @var string
17-
*/
18-
private $cron = 'plausible_analytics_update_js';
19-
2013
/**
2114
* Filters and Hooks.
2215
*
@@ -28,7 +21,7 @@ public function __construct() {
2821
register_deactivation_hook( PLAUSIBLE_ANALYTICS_PLUGIN_FILE, [ $this, 'deactivate_cron' ] );
2922

3023
// Attach the cron script to the cron action.
31-
add_action( $this->cron, [ $this, 'load_cron_script' ] );
24+
add_action( Cron::TASK_NAME, [ $this, 'load_cron_script' ] );
3225

3326
// This assures that the local file is downloaded/updated when settings are saved.
3427
add_action( 'plausible_analytics_settings_saved', [ $this, 'load_cron_script' ] );
@@ -51,8 +44,8 @@ public function create_cache_dir() {
5144
* @codeCoverageIgnore
5245
*/
5346
public function activate_cron() {
54-
if ( ! wp_next_scheduled( $this->cron ) ) {
55-
wp_schedule_event( time(), 'daily', $this->cron );
47+
if ( ! wp_next_scheduled( Cron::TASK_NAME ) ) {
48+
wp_schedule_event( time(), 'daily', Cron::TASK_NAME );
5649
}
5750
}
5851

@@ -62,8 +55,8 @@ public function activate_cron() {
6255
* @codeCoverageIgnore
6356
*/
6457
public function deactivate_cron() {
65-
if ( wp_next_scheduled( $this->cron ) ) {
66-
wp_clear_scheduled_hook( $this->cron );
58+
if ( wp_next_scheduled( Cron::TASK_NAME ) ) {
59+
wp_clear_scheduled_hook( Cron::TASK_NAME );
6760
}
6861
}
6962

tests/unit/ClientFactoryTest.php renamed to tests/integration/ClientFactoryTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* @package Plausible Analytics Unit Tests - ClientFactory
44
*/
55

6-
namespace Plausible\Analytics\Tests\Unit;
6+
namespace Plausible\Analytics\Tests\Integration;
77

88
use Plausible\Analytics\Tests\TestCase;
99
use Plausible\Analytics\WP\Client;

0 commit comments

Comments
 (0)