1<?php
2
3namespace WPaaS;
4
5use GoDaddy\WordPress\Plugins\GoCommerce\WooCommerce_Extensions_Tab;
6
7if ( ! defined( 'ABSPATH' ) ) {
8
9 exit;
10
11}
12
13final class RAD {
14
15 /**
16 * Instance of the API.
17 *
18 * @var API_Interface
19 */
20 private $api;
21
22 /**
23 * Old theme mods before Customizer save.
24 *
25 * @var array
26 */
27 private $old_theme_mods = [];
28
29 /**
30 * Class constructor.
31 *
32 * @param API_Interface $api
33 */
34 public function __construct( API_Interface $api ) {
35
36 // RAD event tracking enabled by default, overridable via constant.
37 if ( defined( 'GD_RAD_ENABLED' ) && ! GD_RAD_ENABLED ) {
38
39 return;
40
41 }
42
43 $this->api = $api;
44
45 if ( is_admin() ) {
46
47 $this->register_admin_hooks();
48
49 } else {
50
51 $this->register_fos_hooks();
52
53 }
54
55 }
56
57 private function register_admin_hooks() {
58
59 // Only applies to sites created after RAD was implemented.
60 if ( $this->site_created_after( '2020-09-14 00:00:00 MST' ) ) {
61
62 add_action( 'post_updated', [ $this, 'first_page_on_front_update' ], PHP_INT_MAX, 2 );
63 add_action( 'save_post', [ $this, 'first_woocommerce_product_created' ], PHP_INT_MAX, 3 );
64
65 }
66
67 add_action( 'update_option_wpseo', [ $this, 'yoast_seo_wizard_completed' ], PHP_INT_MAX, 2 );
68 add_action( 'update_option', [ $this, 'woocommerce_payment_gateway_enabled' ], PHP_INT_MAX, 3 );
69 add_action( 'activate_plugin', [ $this, 'plugin_activated_from_gd_recommended_tab' ], PHP_INT_MAX, 1 );
70 add_action( 'update_option_theme_mods_go', [ $this, 'go_theme_site_design_updated' ], PHP_INT_MAX, 2 );
71
72 if ( defined( WooCommerce_Extensions_Tab::class . '::SLUG' ) ) {
73
74 add_action( 'activate_plugin', [ $this, 'woocommerce_plugin_activated_from_available_extensions_tab' ], PHP_INT_MAX, 1 );
75
76 }
77
78 add_action( 'customize_save', function () {
79
80 // Prevent double event log.
81 remove_action( 'update_option_theme_mods_go', [ $this, 'go_theme_site_design_updated' ], PHP_INT_MAX );
82
83 $this->old_theme_mods = (array) get_option( 'theme_mods_go', [] );
84
85 } );
86
87 add_action( 'customize_save_after', [ $this, 'go_theme_site_design_updated' ], PHP_INT_MAX );
88
89 add_action( 'update_option_sitelogo', [ $this, 'site_logo_updated' ], PHP_INT_MAX, 2 );
90 add_action( 'update_option_blogname', [ $this, 'site_title_updated' ], PHP_INT_MAX, 2 );
91
92 }
93
94 private function register_fos_hooks() {
95
96 // Only applies to sites created after RAD was implemented.
97 if ( $this->site_created_after( '2020-09-14 00:00:00 MST' ) ) {
98
99 add_action( 'save_post', [ $this, 'first_woocommerce_order_created' ], PHP_INT_MAX, 3 );
100
101 }
102
103 }
104
105 private function site_created_after( $datetime ) {
106
107 return defined( 'GD_SITE_CREATED' ) && (int) GD_SITE_CREATED >= strtotime( $datetime );
108
109 }
110
111 private function log_rad_event( $name, $metadata = [], $action_priority = PHP_INT_MAX ) {
112
113 $this->api->log_rad_event( $name, $metadata );
114
115 remove_action( current_action(), [ $this, $name ], $action_priority );
116
117 }
118
119 public function first_page_on_front_update( $post_id, $post_after ) {
120
121 // Only applies to sites created after RAD was implemented.
122 if ( ! $this->site_created_after( '2020-09-14 00:00:00 MST' ) ) {
123
124 return;
125
126 }
127
128 if ( $post_id !== (int) get_option( 'page_on_front' ) || get_option( 'gd_system_first_page_on_front_update' ) ) {
129
130 return;
131
132 }
133
134 update_option( 'gd_system_first_page_on_front_update', time(), false );
135
136 $this->log_rad_event( __FUNCTION__, [
137 'builder' => Plugin::get_page_builder( $post_after ),
138 'theme' => sanitize_title( get_template() ),
139 'wpnux' => ! empty( get_post_meta( $post_id, 'wpnux_id', true ) ),
140 ] );
141
142 }
143
144 public function yoast_seo_wizard_completed( $old_value, $new_value ) {
145
146 if ( ! empty( $old_value['show_onboarding_notice'] ) && empty( $new_value['show_onboarding_notice'] ) ) {
147
148 $this->log_rad_event( __FUNCTION__, [
149 'theme' => sanitize_title( get_template() ),
150 ] );
151
152 }
153
154 }
155
156 public function first_woocommerce_product_created( $post_id, $post, $update ) {
157
158 // Only applies to sites created after RAD was implemented.
159 if ( ! $this->site_created_after( '2020-09-14 00:00:00 MST' ) ) {
160
161 return;
162
163 }
164
165 if ( 'publish' !== $post->post_status || 'product' !== $post->post_type || ! Plugin::is_plugin_active( 'woocommerce/woocommerce.php' ) || get_option( 'gd_system_first_woo_product' ) ) {
166
167 return;
168
169 }
170
171 update_option( 'gd_system_first_woo_product', time(), false );
172
173 $this->log_rad_event( __FUNCTION__, [
174 'theme' => sanitize_title( get_template() ),
175 'wpnux' => $update && ! empty( get_post_meta( $post_id, 'wpnux_id', true ) ),
176 ] );
177
178 }
179
180 public function first_woocommerce_order_created( $post_id, $post, $update ) {
181
182 // Only applies to sites created after RAD was implemented.
183 if ( ! $this->site_created_after( '2020-09-14 00:00:00 MST' ) ) {
184
185 return;
186
187 }
188
189 if ( is_admin() || $update || 'wc-completed' !== $post->post_status || 'shop_order' !== $post->post_type || ! Plugin::is_plugin_active( 'woocommerce/woocommerce.php' ) || get_option( 'gd_system_first_woo_order' ) || ! get_option( 'gd_system_first_woo_product' ) ) {
190
191 return;
192
193 }
194
195 // If the Customer email matches the shop owner, it's probably a test.
196 // Loose comparison ok.
197 if ( $billing_email = get_post_meta( $post_id, '_billing_email', true ) && $billing_email == get_option( 'admin_email' ) ) {
198
199 return;
200
201 }
202
203 // Must be a Guest (user_id = 0) or a registered user with the Customer role.
204 if ( $customer_user_id = (int) get_post_meta( $post_id, '_customer_user', true ) ) {
205
206 $user = get_userdata( $customer_user_id );
207 $roles = isset( $user->roles ) ? (array) $user->roles : [];
208
209 if ( ! in_array( 'customer', $roles, true ) ) {
210
211 return;
212
213 }
214
215 }
216
217 // Autoload for best performance.
218 update_option( 'gd_system_first_woo_order', time() );
219
220 $this->log_rad_event( __FUNCTION__, [
221 'theme' => sanitize_title( get_template() ),
222 ] );
223
224 }
225
226 public function woocommerce_payment_gateway_enabled( $option, $old_value, $new_value ) {
227
228 static $logged = [];
229
230 if ( ! preg_match( '/^woocommerce_(.+)_settings$/', $option, $matches ) || ! empty( $logged[ $matches[1] ] ) ) {
231
232 return;
233
234 }
235
236 $new_enabled = ! empty( $new_value['enabled'] ) && 'yes' === $new_value['enabled'];
237 $old_enabled = ! empty( $old_value['enabled'] ) && 'yes' === $old_value['enabled'];
238
239 if ( ! $new_enabled || $old_enabled || ! Plugin::is_plugin_active( 'woocommerce/woocommerce.php' ) || ! in_array( $matches[1], array_keys( get_option( 'woocommerce_gateway_order', [] ) ), true ) ) {
240
241 return;
242
243 }
244
245 // Action removal not needed, use api method directly.
246 $this->log_rad_event( __FUNCTION__, [
247 'gateway' => $matches[1],
248 'theme' => sanitize_title( get_template() ),
249 ] );
250
251 $logged[ $matches[1] ] = true;
252
253 }
254
255 public function plugin_activated_from_gd_recommended_tab( $plugin ) {
256
257 $query_string = wp_parse_url( wp_get_referer(), PHP_URL_QUERY );
258 $query_args = array();
259 if ( is_string( $query_string ) ) {
260 parse_str( $query_string, $query_args );
261 }
262
263 if ( empty( $query_args['tab'] ) || Admin\Recommended_Plugins_Tab::SLUG !== $query_args['tab'] ) {
264
265 return;
266
267 }
268
269 $this->log_rad_event( __FUNCTION__, [
270 'plugin' => dirname( $plugin ),
271 ] );
272
273 }
274
275 public function woocommerce_plugin_activated_from_available_extensions_tab( $plugin ) {
276
277 $query_string = wp_parse_url( wp_get_referer(), PHP_URL_QUERY );
278 $query_args = array();
279 if ( is_string( $query_string ) ) {
280 parse_str( $query_string, $query_args );
281 }
282
283 if ( empty( $query_args['page'] ) || 'wc-addons' !== $query_args['page'] || empty( $query_args['tab'] ) || WooCommerce_Extensions_Tab::SLUG !== $query_args['tab'] || ! Plugin::is_plugin_active( 'woocommerce/woocommerce.php' ) ) {
284
285 return;
286
287 }
288
289 $this->log_rad_event( __FUNCTION__, [
290 'plugin' => dirname( $plugin ),
291 ] );
292
293 }
294
295 public function go_theme_site_design_updated( $old_value = [], $new_value = [] ) {
296
297 if ( 'customize_save_after' === current_action() ) {
298
299 $old_value = $this->old_theme_mods;
300 $new_value = (array) get_option( 'theme_mods_go', [] );
301
302 }
303
304 // Loose comparison ok.
305 if ( $old_value != $new_value ) {
306
307 $this->log_rad_event( __FUNCTION__, array_diff( $new_value, $old_value ) );
308
309 }
310
311 }
312
313 public function site_logo_updated( $old_value, $new_value ) {
314
315 if ( $old_value === $new_value ) {
316
317 return;
318
319 }
320
321 $site_logo_url = wp_get_attachment_image_src( $new_value, 'full' );
322
323 if ( ! empty( $site_logo_url[0] ) ) {
324
325 $this->log_rad_event( __FUNCTION__, [
326 'url' => defined( 'GD_TEMP_DOMAIN' ) ? str_replace( home_url(), 'https://' . GD_TEMP_DOMAIN, $site_logo_url[0] ) : $site_logo_url[0],
327 ] );
328
329 }
330
331 }
332
333 public function site_title_updated( $old_value, $new_value ) {
334
335 if ( $old_value !== $new_value ) {
336
337 $this->log_rad_event( __FUNCTION__, [
338 'old_value' => $old_value,
339 'new_value' => $new_value,
340 ] );
341
342 }
343
344 }
345
346}
347