PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
jetpack / jetpack_vendor / automattic / jetpack-premium-analytics / src / Sync / class-configuration.php

class-configuration.php in Jetpack – WP Security, Backup, Speed, & Growth 16.3-beta, at jetpack_vendor/automattic/jetpack-premium-analytics/src/Sync/class-configuration.php

200 lines 6.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Premium Analytics glue for the shared WooCommerce Analytics sync module.
4 *
5 * @package automattic/jetpack-premium-analytics
6 */
7
8 namespace Automattic\Jetpack\PremiumAnalytics\Sync;
9
10 use Automattic\Jetpack\Config;
11 use Automattic\Jetpack\Sync\Data_Settings;
12 use Automattic\Jetpack\Sync\Modules\Meta as Meta_Module;
13 use Automattic\Jetpack\Sync\Modules\Posts as Posts_Module;
14 use Automattic\Jetpack\Sync\Modules\Term_Relationships as Term_Relationships_Module;
15 use Automattic\Jetpack\Sync\Modules\Terms as Terms_Module;
16 use Automattic\Jetpack\Sync\Modules\WooCommerce_Analytics as WooCommerce_Analytics_Module;
17
18 defined( 'ABSPATH' ) || exit;
19
20 /**
21 * Opts in to the shared WooCommerce Analytics sync module and registers the
22 * Premium Analytics-specific sync configuration.
23 */
24 class Configuration {
25
26 /**
27 * FQCN of the Analytics module shipped by the standalone WooCommerce Analytics plugin.
28 *
29 * Must track that plugin's class: if it drifts, both modules load under the same
30 * name and every analytics event syncs twice. Moot once that plugin consumes the
31 * shared module, since the class strings then match.
32 *
33 * @since 0.9.0
34 * @var string
35 */
36 const ANALYTICS_PLUGIN_MODULE_FQCN = 'Automattic\\WooCommerce\\Analytics\\Internal\\Jetpack\\Sync\\Modules\\Analytics';
37
38 /**
39 * Bookings post meta to add to Sync's post meta whitelist. Bookings are synced
40 * via the Posts + Meta modules; there is no dedicated bookings sync module.
41 *
42 * Product meta needed by analytics reports is whitelisted by the shared module.
43 *
44 * @static
45 * @var array
46 */
47 private static $postmeta_to_sync = array(
48 '_booking_parent_id',
49 '_booking_duplicate_of',
50 '_booking_product_id',
51 '_booking_resource_id',
52 '_booking_order_id',
53 '_booking_order_item_id',
54 '_booking_customer_id',
55 '_booking_start',
56 '_booking_end',
57 '_booking_all_day',
58 '_booking_persons',
59 '_booking_cost',
60 '_booking_date_cancelled',
61 '_booking_attendance_status',
62 );
63
64 /**
65 * Entry point called from Analytics::init(). Schedules the Sync hookups on
66 * plugins_loaded; the actual registration is a no-op unless WooCommerce is active
67 * (see {@see configure_sync()}).
68 *
69 * Call it before plugins_loaded completes: the Config built in configure_sync() wires
70 * Sync\Main::configure() from a plugins_loaded priority 2 handler that never fires later.
71 *
72 * @return void
73 */
74 public static function register(): void {
75 $instance = new self();
76
77 // plugins_loaded priority 1: every plugin has loaded for the WooCommerce guard, and the
78 // Config constructed in configure_sync() still gets its priority 2 handler in this cycle.
79 if ( did_action( 'plugins_loaded' ) ) {
80 $instance->configure_sync();
81 } else {
82 add_action( 'plugins_loaded', array( $instance, 'configure_sync' ), 1 );
83 }
84 }
85
86 /**
87 * Whether WooCommerce is active in the current request.
88 *
89 * @return bool
90 */
91 private static function is_woocommerce_active(): bool {
92 return class_exists( 'WooCommerce' ) || function_exists( 'WC' );
93 }
94
95 /**
96 * Register the Jetpack Sync filters and ensure the Sync feature when WooCommerce
97 * is active.
98 *
99 * @return void
100 */
101 public function configure_sync(): void {
102 if ( ! self::is_woocommerce_active() ) {
103 return;
104 }
105
106 // The shared module is registered through the Sync config below; this only drops a duplicate.
107 add_filter( 'jetpack_sync_modules', array( $this, 'remove_duplicate_woocommerce_analytics_module' ), PHP_INT_MAX );
108 add_filter( 'jetpack_full_sync_config', array( $this, 'expand_full_sync_config' ) );
109 add_filter( 'jetpack_sync_post_meta_whitelist', array( $this, 'add_meta_to_sync_post_meta_whitelist' ) );
110
111 ( new Config() )->ensure( 'sync', $this->get_jetpack_sync_config() );
112 }
113
114 /**
115 * Jetpack Sync module configuration.
116 *
117 * MUST_SYNC_DATA_SETTINGS is merged in because Data_Settings falls back to the full default
118 * whitelist for any filter a consumer leaves out, which would widen standalone sites.
119 *
120 * @return array Jetpack Sync config array.
121 */
122 private function get_jetpack_sync_config(): array {
123 return array_merge_recursive(
124 Data_Settings::MUST_SYNC_DATA_SETTINGS,
125 array(
126 'jetpack_sync_modules' => array(
127 WooCommerce_Analytics_Module::class,
128 Meta_Module::class,
129 Posts_Module::class,
130 Terms_Module::class,
131 Term_Relationships_Module::class,
132 ),
133 // Listed explicitly so the contract does not depend on which other Sync modules load.
134 'jetpack_sync_options_whitelist' => array(
135 'woocommerce_custom_orders_table_enabled', // Required for HPOS checksums.
136 'woocommerce_excluded_report_order_statuses', // Required for generating analytics reports.
137 'woocommerce_date_type', // Date used to determine the date range for analytics reports.
138 ),
139 'jetpack_sync_constants_whitelist' => array(
140 // Syncing it makes WPCOM provision the WC Analytics tables (WOOA7S-1643). WC_ANALYTICS_VERSION
141 // belongs to the standalone plugin and would only sync null on a PA-only store.
142 'JETPACK_PREMIUM_ANALYTICS__VERSION',
143 ),
144 )
145 );
146 }
147
148 /**
149 * Drop the standalone plugin's Analytics module in favor of the shared one.
150 *
151 * Sync dedups by class name only, so both would load and sync every event twice. The shared
152 * module wins because the released standalone one syncs no lookup data, while the sync package
153 * advertises the lookup checksum tables for any module of this name.
154 *
155 * Runs at PHP_INT_MAX because Data_Settings re-asserts its whole module list at priority 10.
156 *
157 * @param array|mixed $modules Current Sync module class names.
158 * @return array|mixed Updated Sync module class names.
159 */
160 public function remove_duplicate_woocommerce_analytics_module( $modules ) {
161 // An emptied list is a kill switch (Jetpack's uninstaller uses one); leave it alone.
162 if ( ! is_array( $modules ) || empty( $modules ) ) {
163 return $modules;
164 }
165
166 return array_values( array_diff( $modules, array( self::ANALYTICS_PLUGIN_MODULE_FQCN ) ) );
167 }
168
169 /**
170 * Add the Analytics module to full sync, first in line.
171 *
172 * @param array $config Current full-sync configuration.
173 * @return array Updated full-sync configuration.
174 */
175 public function expand_full_sync_config( array $config ): array {
176 // Terms and term relationships must be synced before posts.
177 if ( isset( $config['posts'] ) ) {
178 unset( $config['posts'] );
179 $config += array( 'posts' => 1 );
180 }
181
182 if ( ! isset( $config['woocommerce_analytics'] ) ) {
183 $config = array( 'woocommerce_analytics' => 1 ) + $config;
184 }
185
186 return $config;
187 }
188
189 /**
190 * Add Bookings post meta to Sync's post meta whitelist.
191 * Any changes to these meta will be synced to WordPress.com.
192 *
193 * @param array $whitelist Existing post meta whitelist.
194 * @return array Updated post meta whitelist.
195 */
196 public function add_meta_to_sync_post_meta_whitelist( array $whitelist ): array {
197 return array_merge( self::$postmeta_to_sync, $whitelist );
198 }
199 }
200