Completed
Push — master ( c14ea5...651a4c )
by Claudio
21:49
created

WC_Tracker::get_admin_user_agents()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * WooCommerce Tracker
4
 *
5
 * The WooCommerce tracker class adds functionality to track WooCommerce usage based on if the customer opted in.
6
 * No personal infomation is tracked, only general WooCommerce settings, general product, order and user counts and admin email for discount code.
7
 *
8
 * @class 		WC_Tracker
9
 * @version		2.3.0
10
 * @package		WooCommerce/Classes
11
 * @category	Class
12
 * @author 		WooThemes
13
 */
14
15
if ( ! defined( 'ABSPATH' ) ) {
16
	exit;
17
}
18
19
class WC_Tracker {
20
21
	/**
22
	 * URL to the WooThemes Tracker API endpoint.
23
	 * @var string
24
	 */
25
	private static $api_url = 'https://tracking.woocommerce.com/v1/';
26
27
	/**
28
	 * Hook into cron event.
29
	 */
30
	public static function init() {
31
		add_action( 'woocommerce_tracker_send_event', array( __CLASS__, 'send_tracking_data' ) );
32
	}
33
34
	/**
35
	 * Decide whether to send tracking data or not.
36
	 *
37
	 * @param boolean $override
38
	 */
39
	public static function send_tracking_data( $override = false ) {
40
		// Dont trigger this on AJAX Requests
41
		if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
42
			return;
43
		}
44
45
		if ( ! apply_filters( 'woocommerce_tracker_send_override', $override ) ) {
46
			// Send a maximum of once per week by default.
47
			$last_send = self::get_last_send_time();
48
			if ( $last_send && $last_send > apply_filters( 'woocommerce_tracker_last_send_interval', strtotime( '-1 week' ) ) ) {
49
				return;
50
			}
51
		} else {
52
			// Make sure there is at least a 1 hour delay between override sends, we dont want duplicate calls due to double clicking links.
53
			$last_send = self::get_last_send_time();
54
			if ( $last_send && $last_send > strtotime( '-1 hours' ) ) {
55
				return;
56
			}
57
		}
58
59
		// Update time first before sending to ensure it is set
60
		update_option( 'woocommerce_tracker_last_send', time() );
61
62
		$params   = self::get_tracking_data();
63
		wp_safe_remote_post( self::$api_url, array(
64
				'method'      => 'POST',
65
				'timeout'     => 45,
66
				'redirection' => 5,
67
				'httpversion' => '1.0',
68
				'blocking'    => false,
69
				'headers'     => array( 'user-agent' => 'WooCommerceTracker/' . md5( esc_url( home_url( '/' ) ) ) . ';' ),
70
				'body'        => json_encode( $params ),
71
				'cookies'     => array(),
72
			)
73
		);
74
	}
75
76
	/**
77
	 * Get the last time tracking data was sent.
78
	 * @return int|bool
79
	 */
80
	private static function get_last_send_time() {
81
		return apply_filters( 'woocommerce_tracker_last_send_time', get_option( 'woocommerce_tracker_last_send', false ) );
82
	}
83
84
	/**
85
	 * Get all the tracking data.
86
	 * @return array
87
	 */
88
	private static function get_tracking_data() {
89
		$data                       = array();
90
91
		// General site info
92
		$data['url']                = home_url();
93
		$data['email']              = apply_filters( 'woocommerce_tracker_admin_email', get_option( 'admin_email' ) );
94
		$data['theme']              = self::get_theme_info();
95
96
		// WordPress Info
97
		$data['wp']                 = self::get_wordpress_info();
98
99
		// Server Info
100
		$data['server']             = self::get_server_info();
101
102
		// Plugin info
103
		$all_plugins                = self::get_all_plugins();
104
		$data['active_plugins']     = $all_plugins['active_plugins'];
105
		$data['inactive_plugins']   = $all_plugins['inactive_plugins'];
106
107
		// Jetpack & WooCommerce Connect
108
		$data['jetpack_version']    = defined( 'JETPACK__VERSION' ) ? JETPACK__VERSION : 'none';
109
		$data['jetpack_connected']  = ( class_exists( 'Jetpack' ) && is_callable( 'Jetpack::is_active' ) && Jetpack::is_active() ) ? 'yes' : 'no';
110
		$data['jetpack_is_staging'] = ( class_exists( 'Jetpack' ) && is_callable( 'Jetpack::is_staging_site' ) && Jetpack::is_staging_site() ) ? 'yes' : 'no';
111
		$data['connect_installed']  = class_exists( 'WC_Connect_Loader' ) ? 'yes' : 'no';
112
		$data['connect_active']     = ( class_exists( 'WC_Connect_Loader' ) && wp_next_scheduled( 'wc_connect_fetch_service_schemas' ) ) ? 'yes' : 'no';
113
114
		// Store count info
115
		$data['users']              = self::get_user_counts();
116
		$data['products']           = self::get_product_counts();
117
		$data['orders']             = self::get_order_counts();
118
119
		// Payment gateway info
120
		$data['gateways']           = self::get_active_payment_gateways();
121
122
		// Shipping method info
123
		$data['shipping_methods']   = self::get_active_shipping_methods();
124
125
		// Get all WooCommerce options info
126
		$data['settings']           = self::get_all_woocommerce_options_values();
127
128
		// Template overrides
129
		$data['template_overrides'] = self::get_all_template_overrides();
130
131
		// Template overrides
132
		$data['admin_user_agents']  = self::get_admin_user_agents();
133
134
		return apply_filters( 'woocommerce_tracker_data', $data );
135
	}
136
137
	/**
138
	 * Get the current theme info, theme name and version.
139
	 * @return array
140
	 */
141
	public static function get_theme_info() {
142
		$wp_version = get_bloginfo( 'version' );
143
144
		if ( version_compare( $wp_version, '3.4', '<' ) ) {
145
			$theme_data = get_theme_data( get_stylesheet_directory() . '/style.css' );
146
			$theme_name = $theme_data['Name'];
147
			$theme_version = $theme_data['Version'];
148
		} else {
149
			$theme_data = wp_get_theme();
150
			$theme_name = $theme_data->Name;
151
			$theme_version = $theme_data->Version;
152
		}
153
		$theme_child_theme = is_child_theme() ? 'Yes' : 'No';
154
		$theme_wc_support = ( ! current_theme_supports( 'woocommerce' ) && ! in_array( $theme_data->template, wc_get_core_supported_themes() ) ) ? 'No' : 'Yes';
155
156
		return array( 'name' => $theme_name, 'version' => $theme_version, 'child_theme' => $theme_child_theme, 'wc_support' => $theme_wc_support );
157
	}
158
159
	/**
160
	 * Get WordPress related data.
161
	 * @return array
162
	 */
163
	private static function get_wordpress_info() {
164
		$wp_data = array();
165
166
		$memory = wc_let_to_num( WP_MEMORY_LIMIT );
167
168
		if ( function_exists( 'memory_get_usage' ) ) {
169
			$system_memory = wc_let_to_num( @ini_get( 'memory_limit' ) );
170
			$memory        = max( $memory, $system_memory );
171
		}
172
173
		$wp_data['memory_limit'] = size_format( $memory );
174
		$wp_data['debug_mode']   = ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? 'Yes' : 'No';
175
		$wp_data['locale']       = get_locale();
176
		$wp_data['version']      = get_bloginfo( 'version' );
177
		$wp_data['multisite']    = is_multisite() ? 'Yes' : 'No';
178
179
		return $wp_data;
180
	}
181
182
	/**
183
	 * Get server related info.
184
	 * @return array
185
	 */
186
	private static function get_server_info() {
187
		$server_data = array();
188
189
		if ( isset( $_SERVER['SERVER_SOFTWARE'] ) && ! empty( $_SERVER['SERVER_SOFTWARE'] ) ) {
190
			$server_data['software'] = $_SERVER['SERVER_SOFTWARE'];
191
		}
192
193
		if ( function_exists( 'phpversion' ) ) {
194
			$server_data['php_version'] = phpversion();
195
		}
196
197
		if ( function_exists( 'ini_get' ) ) {
198
			$server_data['php_post_max_size'] = size_format( wc_let_to_num( ini_get( 'post_max_size' ) ) );
199
			$server_data['php_time_limt'] = ini_get( 'max_execution_time' );
200
			$server_data['php_max_input_vars'] = ini_get( 'max_input_vars' );
201
			$server_data['php_suhosin'] = extension_loaded( 'suhosin' ) ? 'Yes' : 'No';
202
		}
203
204
		global $wpdb;
205
		$server_data['mysql_version'] = $wpdb->db_version();
206
207
		$server_data['php_max_upload_size'] = size_format( wp_max_upload_size() );
208
		$server_data['php_default_timezone'] = date_default_timezone_get();
209
		$server_data['php_soap'] = class_exists( 'SoapClient' ) ? 'Yes' : 'No';
210
		$server_data['php_fsockopen'] = function_exists( 'fsockopen' ) ? 'Yes' : 'No';
211
		$server_data['php_curl'] = function_exists( 'curl_init' ) ? 'Yes' : 'No';
212
213
		return $server_data;
214
	}
215
216
	/**
217
	 * Get all plugins grouped into activated or not.
218
	 * @return array
219
	 */
220
	private static function get_all_plugins() {
221
		// Ensure get_plugins function is loaded
222
		if ( ! function_exists( 'get_plugins' ) ) {
223
			include ABSPATH . '/wp-admin/includes/plugin.php';
224
		}
225
226
		$plugins        	 = get_plugins();
227
		$active_plugins_keys = get_option( 'active_plugins', array() );
228
		$active_plugins 	 = array();
229
230
		foreach ( $plugins as $k => $v ) {
231
			// Take care of formatting the data how we want it.
232
			$formatted = array();
233
			$formatted['name'] = strip_tags( $v['Name'] );
234
			if ( isset( $v['Version'] ) ) {
235
				$formatted['version'] = strip_tags( $v['Version'] );
236
			}
237
			if ( isset( $v['Author'] ) ) {
238
				$formatted['author'] = strip_tags( $v['Author'] );
239
			}
240
			if ( isset( $v['Network'] ) ) {
241
				$formatted['network'] = strip_tags( $v['Network'] );
242
			}
243
			if ( isset( $v['PluginURI'] ) ) {
244
				$formatted['plugin_uri'] = strip_tags( $v['PluginURI'] );
245
			}
246
			if ( in_array( $k, $active_plugins_keys ) ) {
247
				// Remove active plugins from list so we can show active and inactive separately
248
				unset( $plugins[ $k ] );
249
				$active_plugins[ $k ] = $formatted;
250
			} else {
251
				$plugins[ $k ] = $formatted;
252
			}
253
		}
254
255
		return array( 'active_plugins' => $active_plugins, 'inactive_plugins' => $plugins );
256
	}
257
258
	/**
259
	 * Get user totals based on user role.
260
	 * @return array
261
	 */
262
	private static function get_user_counts() {
263
		$user_count          = array();
264
		$user_count_data     = count_users();
265
		$user_count['total'] = $user_count_data['total_users'];
266
267
		// Get user count based on user role
268
		foreach ( $user_count_data['avail_roles'] as $role => $count ) {
269
			$user_count[ $role ] = $count;
270
		}
271
272
		return $user_count;
273
	}
274
275
	/**
276
	 * Get product totals based on product type.
277
	 * @return array
278
	 */
279
	private static function get_product_counts() {
280
		$product_count          = array();
281
		$product_count_data     = wp_count_posts( 'product' );
282
		$product_count['total'] = $product_count_data->publish;
283
284
		$product_statuses = get_terms( 'product_type', array( 'hide_empty' => 0 ) );
285
		foreach ( $product_statuses as $product_status ) {
286
			$product_count[ $product_status->name ] = $product_status->count;
287
		}
288
289
		return $product_count;
290
	}
291
292
	/**
293
	 * Get order counts based on order status.
294
	 * @return array
295
	 */
296
	private static function get_order_counts() {
297
		$order_count      = array();
298
		$order_count_data = wp_count_posts( 'shop_order' );
299
300
		foreach ( wc_get_order_statuses() as $status_slug => $status_name ) {
301
			$order_count[ $status_slug ] = $order_count_data->{ $status_slug };
302
		}
303
304
		return $order_count;
305
	}
306
307
	/**
308
	 * Get a list of all active payment gateways.
309
	 * @return array
310
	 */
311 View Code Duplication
	private static function get_active_payment_gateways() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
312
		$active_gateways = array();
313
		$gateways        = WC()->payment_gateways->payment_gateways();
314
		foreach ( $gateways as $id => $gateway ) {
315
			if ( isset( $gateway->enabled ) && 'yes' === $gateway->enabled ) {
316
				$active_gateways[ $id ] = array( 'title' => $gateway->title, 'supports' => $gateway->supports );
317
			}
318
		}
319
320
		return $active_gateways;
321
	}
322
323
	/**
324
	 * Get a list of all active shipping methods.
325
	 * @return array
326
	 */
327 View Code Duplication
	private static function get_active_shipping_methods() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
328
		$active_methods   = array();
329
		$shipping_methods = WC()->shipping->get_shipping_methods();
330
		foreach ( $shipping_methods as $id => $shipping_method ) {
331
			if ( isset( $shipping_method->enabled ) && 'yes' === $shipping_method->enabled ) {
332
				$active_methods[ $id ] = array( 'title' => $shipping_method->title, 'tax_status' => $shipping_method->tax_status );
333
			}
334
		}
335
336
		return $active_methods;
337
	}
338
339
	/**
340
	 * Get all options starting with woocommerce_ prefix.
341
	 * @return array
342
	 */
343
	private static function get_all_woocommerce_options_values() {
344
		return array(
345
			'version'                               => WC()->version,
346
			'currency'                              => get_woocommerce_currency(),
347
			'base_location'                         => WC()->countries->get_base_country(),
348
			'selling_locations'                     => WC()->countries->get_allowed_countries(),
349
			'api_enabled'                           => get_option( 'woocommerce_api_enabled' ),
350
			'weight_unit'                           => get_option( 'woocommerce_weight_unit' ),
351
			'dimension_unit'                        => get_option( 'woocommerce_dimension_unit' ),
352
			'download_method'                       => get_option( 'woocommerce_file_download_method' ),
353
			'download_require_login'                => get_option( 'woocommerce_downloads_require_login' ),
354
			'calc_taxes'                            => get_option( 'woocommerce_calc_taxes' ),
355
			'coupons_enabled'                       => get_option( 'woocommerce_enable_coupons' ),
356
			'guest_checkout'                        => get_option( 'woocommerce_enable_guest_checkout' ),
357
			'secure_checkout'                       => get_option( 'woocommerce_force_ssl_checkout' ),
358
			'enable_signup_and_login_from_checkout' => get_option( 'woocommerce_enable_signup_and_login_from_checkout' ),
359
			'enable_myaccount_registration'         => get_option( 'woocommerce_enable_myaccount_registration' ),
360
			'registration_generate_username'        => get_option( 'woocommerce_registration_generate_username' ),
361
			'registration_generate_password'        => get_option( 'woocommerce_registration_generate_password' ),
362
		);
363
	}
364
365
	/**
366
	 * Look for any template override and return filenames.
367
	 * @return array
368
	 */
369
	private static function get_all_template_overrides() {
370
		$override_data  = array();
371
		$template_paths = apply_filters( 'woocommerce_template_overrides_scan_paths', array( 'WooCommerce' => WC()->plugin_path() . '/templates/' ) );
372
		$scanned_files  = array();
373
374
		require_once( WC()->plugin_path() . '/includes/admin/class-wc-admin-status.php' );
375
376
		foreach ( $template_paths as $plugin_name => $template_path ) {
377
			$scanned_files[ $plugin_name ] = WC_Admin_Status::scan_template_files( $template_path );
378
		}
379
380
		foreach ( $scanned_files as $plugin_name => $files ) {
381
			foreach ( $files as $file ) {
382
				if ( file_exists( get_stylesheet_directory() . '/' . $file ) ) {
383
					$theme_file = get_stylesheet_directory() . '/' . $file;
384
				} elseif ( file_exists( get_stylesheet_directory() . '/woocommerce/' . $file ) ) {
385
					$theme_file = get_stylesheet_directory() . '/woocommerce/' . $file;
386
				} elseif ( file_exists( get_template_directory() . '/' . $file ) ) {
387
					$theme_file = get_template_directory() . '/' . $file;
388
				} elseif ( file_exists( get_template_directory() . '/woocommerce/' . $file ) ) {
389
					$theme_file = get_template_directory() . '/woocommerce/' . $file;
390
				} else {
391
					$theme_file = false;
392
				}
393
394
				if ( false !== $theme_file ) {
395
					$override_data[] = basename( $theme_file );
396
				}
397
			}
398
		}
399
		return $override_data;
400
	}
401
402
	/**
403
	 * When an admin user logs in, there user agent is tracked in user meta and collected here.
404
	 * @return array
405
	 */
406
	private static function get_admin_user_agents() {
407
		return array_filter( (array) get_option( 'woocommerce_tracker_ua', array() ) );
408
	}
409
}
410
411
WC_Tracker::init();
412