Completed
Push — master ( ec01c3...75529e )
by Mike
18:54
created

WC_Tracker::get_wordpress_info()   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 18
Code Lines 12

Duplication

Lines 4
Ratio 22.22 %
Metric Value
dl 4
loc 18
rs 8.8571
cc 5
eloc 12
nc 16
nop 0
1
<?php
1 ignored issue
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 19 and the first side effect is on line 16.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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
		$response = wp_safe_remote_post( self::$api_url, array(
0 ignored issues
show
Unused Code introduced by
$response is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
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
		// Store count info
108
		$data['users']              = self::get_user_counts();
109
		$data['products']           = self::get_product_counts();
110
		$data['orders']             = self::get_order_counts();
111
112
		// Payment gateway info
113
		$data['gateways']           = self::get_active_payment_gateways();
114
115
		// Shipping method info
116
		$data['shipping_methods']   = self::get_active_shipping_methods();
117
118
		// Get all WooCommerce options info
119
		$data['settings']           = self::get_all_woocommerce_options_values();
120
121
		// Template overrides
122
		$data['template_overrides'] = self::get_all_template_overrides();
123
124
		return apply_filters( 'woocommerce_tracker_data', $data );
125
	}
126
127
	/**
128
	 * Get the current theme info, theme name and version.
129
	 * @return array
130
	 */
131
	public static function get_theme_info() {
132
		$wp_version = get_bloginfo( 'version' );
133
134
		if ( version_compare( $wp_version, '3.4', '<' ) ) {
135
			$theme_data = get_theme_data( get_stylesheet_directory() . '/style.css' );
136
			$theme_name = $theme_data['Name'];
137
			$theme_version = $theme_data['Version'];
138
		} else {
139
			$theme_data = wp_get_theme();
140
			$theme_name = $theme_data->Name;
141
			$theme_version = $theme_data->Version;
142
		}
143
		$theme_child_theme = is_child_theme() ? 'Yes' : 'No';
144
		$theme_wc_support = ( ! current_theme_supports( 'woocommerce' ) && ! in_array( $theme_data->template, wc_get_core_supported_themes() ) ) ? 'No' : 'Yes';
145
146
		return array( 'name' => $theme_name, 'version' => $theme_version, 'child_theme' => $theme_child_theme, 'wc_support' => $theme_wc_support );
147
	}
148
149
	/**
150
	 * Get WordPress related data.
151
	 * @return array
152
	 */
153
	private static function get_wordpress_info() {
154
		$wp_data = array();
155
156
		$memory = wc_let_to_num( WP_MEMORY_LIMIT );
157
158 View Code Duplication
		if ( function_exists( 'memory_get_usage' ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
159
			$system_memory = wc_let_to_num( @ini_get( 'memory_limit' ) );
160
			$memory        = max( $memory, $system_memory );
161
		}
162
163
		$wp_data['memory_limit'] = size_format( $memory );
164
		$wp_data['debug_mode']   = ( defined('WP_DEBUG') && WP_DEBUG ) ? 'Yes' : 'No';
165
		$wp_data['locale']       = get_locale();
166
		$wp_data['version']      = get_bloginfo( 'version' );
167
		$wp_data['multisite']    = is_multisite() ? 'Yes' : 'No';
168
169
		return $wp_data;
170
	}
171
172
	/**
173
	 * Get server related info.
174
	 * @return array
175
	 */
176
	private static function get_server_info() {
177
		$server_data = array();
178
179
		if ( isset( $_SERVER['SERVER_SOFTWARE'] ) && ! empty( $_SERVER['SERVER_SOFTWARE'] ) ) {
180
			$server_data['software'] = $_SERVER['SERVER_SOFTWARE'];
181
		}
182
183
		if ( function_exists( 'phpversion' ) ) {
184
			$server_data['php_version'] = phpversion();
185
		}
186
187
		if ( function_exists( 'ini_get' ) ) {
188
			$server_data['php_post_max_size'] = size_format( wc_let_to_num( ini_get( 'post_max_size' ) ) );
189
			$server_data['php_time_limt'] = ini_get( 'max_execution_time' );
190
			$server_data['php_max_input_vars'] = ini_get( 'max_input_vars' );
191
			$server_data['php_suhosin'] = extension_loaded( 'suhosin' ) ? 'Yes' : 'No';
192
		}
193
194
		global $wpdb;
195
		$server_data['mysql_version'] = $wpdb->db_version();
196
197
		$server_data['php_max_upload_size'] = size_format( wp_max_upload_size() );
198
		$server_data['php_default_timezone'] = date_default_timezone_get();
199
		$server_data['php_soap'] = class_exists( 'SoapClient' ) ? 'Yes' : 'No';
200
		$server_data['php_fsockopen'] = function_exists( 'fsockopen' ) ? 'Yes' : 'No';
201
		$server_data['php_curl'] = function_exists( 'curl_init' ) ? 'Yes' : 'No';
202
203
		return $server_data;
204
	}
205
206
	/**
207
	 * Get all plugins grouped into activated or not.
208
	 * @return array
209
	 */
210
	private static function get_all_plugins() {
211
		// Ensure get_plugins function is loaded
212
		if( ! function_exists( 'get_plugins' ) ) {
213
			include ABSPATH . '/wp-admin/includes/plugin.php';
214
		}
215
216
		$plugins        	 = get_plugins();
217
		$active_plugins_keys = get_option( 'active_plugins', array() );
218
		$active_plugins 	 = array();
219
220
		foreach ( $plugins as $k => $v ) {
221
			// Take care of formatting the data how we want it.
222
			$formatted = array();
223
			$formatted['name'] = strip_tags( $v['Name'] );
224
			if ( isset( $v['Version'] ) ) {
225
				$formatted['version'] = strip_tags( $v['Version'] );
226
			}
227
			if ( isset( $v['Author'] ) ) {
228
				$formatted['author'] = strip_tags( $v['Author'] );
229
			}
230
			if ( isset( $v['Network'] ) ) {
231
				$formatted['network'] = strip_tags( $v['Network'] );
232
			}
233
			if ( isset( $v['PluginURI'] ) ) {
234
				$formatted['plugin_uri'] = strip_tags( $v['PluginURI'] );
235
			}
236
			if ( in_array( $k, $active_plugins_keys ) ) {
237
				// Remove active plugins from list so we can show active and inactive separately
238
				unset( $plugins[$k] );
239
				$active_plugins[$k] = $formatted;
240
			} else {
241
				$plugins[$k] = $formatted;
242
			}
243
		}
244
245
		return array( 'active_plugins' => $active_plugins, 'inactive_plugins' => $plugins );
246
	}
247
248
	/**
249
	 * Get user totals based on user role.
250
	 * @return array
251
	 */
252
	private static function get_user_counts() {
253
		$user_count          = array();
254
		$user_count_data     = count_users();
255
		$user_count['total'] = $user_count_data['total_users'];
256
257
		// Get user count based on user role
258
		foreach ( $user_count_data['avail_roles'] as $role => $count ) {
259
			$user_count[ $role ] = $count;
260
		}
261
262
		return $user_count;
263
	}
264
265
	/**
266
	 * Get product totals based on product type.
267
	 * @return array
268
	 */
269
	private static function get_product_counts() {
270
		$product_count          = array();
271
		$product_count_data     = wp_count_posts( 'product' );
272
		$product_count['total'] = $product_count_data->publish;
273
274
		$product_statuses = get_terms( 'product_type', array( 'hide_empty' => 0 ) );
275
		foreach ( $product_statuses as $product_status ) {
276
			$product_count[ $product_status->name ] = $product_status->count;
277
		}
278
279
		return $product_count;
280
	}
281
282
	/**
283
	 * Get order counts based on order status.
284
	 * @return array
285
	 */
286
	private static function get_order_counts() {
287
		$order_count      = array();
288
		$order_count_data = wp_count_posts( 'shop_order' );
289
290
		foreach ( wc_get_order_statuses() as $status_slug => $status_name ) {
291
			$order_count[ $status_slug ] = $order_count_data->{ $status_slug };
292
		}
293
294
		return $order_count;
295
	}
296
297
	/**
298
	 * Get a list of all active payment gateways.
299
	 * @return array
300
	 */
301 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...
302
		$active_gateways = array();
303
		$gateways        = WC()->payment_gateways->payment_gateways();
304
		foreach ( $gateways as $id => $gateway ) {
305
			if ( isset( $gateway->enabled ) && $gateway->enabled == 'yes' ) {
306
				$active_gateways[ $id ] = array( 'title' => $gateway->title, 'supports' => $gateway->supports );
307
			}
308
		}
309
310
		return $active_gateways;
311
	}
312
313
	/**
314
	 * Get a list of all active shipping methods.
315
	 * @return array
316
	 */
317 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...
318
		$active_methods   = array();
319
		$shipping_methods = WC()->shipping->get_shipping_methods();
320
		foreach ( $shipping_methods as $id => $shipping_method ) {
321
			if ( isset( $shipping_method->enabled ) && $shipping_method->enabled == 'yes' ) {
322
				$active_methods[ $id ] = array( 'title' => $shipping_method->title, 'tax_status' => $shipping_method->tax_status );
323
			}
324
		}
325
326
		return $active_methods;
327
	}
328
329
	/**
330
	 * Get all options starting with woocommerce_ prefix.
331
	 * @return array
332
	 */
333
	private static function get_all_woocommerce_options_values() {
334
		return array(
335
			'version'                               => WC()->version,
336
			'currency'                              => get_woocommerce_currency(),
337
			'base_location'                         => WC()->countries->get_base_country(),
338
			'selling_locations'                     => WC()->countries->get_allowed_countries(),
339
			'api_enabled'                           => get_option( 'woocommerce_api_enabled' ),
340
			'weight_unit'                           => get_option( 'woocommerce_weight_unit' ),
341
			'dimension_unit'                        => get_option( 'woocommerce_dimension_unit' ),
342
			'download_method'                       => get_option( 'woocommerce_file_download_method' ),
343
			'download_require_login'                => get_option( 'woocommerce_downloads_require_login' ),
344
			'calc_taxes'                            => get_option( 'woocommerce_calc_taxes' ),
345
			'coupons_enabled'                       => get_option( 'woocommerce_enable_coupons' ),
346
			'guest_checkout'                        => get_option( 'woocommerce_enable_guest_checkout'),
347
			'secure_checkout'                       => get_option( 'woocommerce_force_ssl_checkout' ),
348
			'enable_signup_and_login_from_checkout' => get_option( 'woocommerce_enable_signup_and_login_from_checkout' ),
349
			'enable_myaccount_registration'         => get_option( 'woocommerce_enable_myaccount_registration' ),
350
			'registration_generate_username'        => get_option( 'woocommerce_registration_generate_username' ),
351
			'registration_generate_password'        => get_option( 'woocommerce_registration_generate_password' ),
352
		);
353
	}
354
355
	/**
356
	 * Look for any template override and return filenames.
357
	 * @return array
358
	 */
359
	private static function get_all_template_overrides() {
360
		$override_data  = array();
361
		$template_paths = apply_filters( 'woocommerce_template_overrides_scan_paths', array( 'WooCommerce' => WC()->plugin_path() . '/templates/' ) );
362
		$scanned_files  = array();
363
364
		require_once( WC()->plugin_path() . '/includes/admin/class-wc-admin-status.php' );
365
366
		foreach ( $template_paths as $plugin_name => $template_path ) {
367
			$scanned_files[ $plugin_name ] = WC_Admin_Status::scan_template_files( $template_path );
368
		}
369
370
		foreach ( $scanned_files as $plugin_name => $files ) {
371
			foreach ( $files as $file ) {
372 View Code Duplication
				if ( file_exists( get_stylesheet_directory() . '/' . $file ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
373
					$theme_file = get_stylesheet_directory() . '/' . $file;
374
				} elseif ( file_exists( get_stylesheet_directory() . '/woocommerce/' . $file ) ) {
375
					$theme_file = get_stylesheet_directory() . '/woocommerce/' . $file;
376
				} elseif ( file_exists( get_template_directory() . '/' . $file ) ) {
377
					$theme_file = get_template_directory() . '/' . $file;
378
				} elseif( file_exists( get_template_directory() . '/woocommerce/' . $file ) ) {
379
					$theme_file = get_template_directory() . '/woocommerce/' . $file;
380
				} else {
381
					$theme_file = false;
382
				}
383
384
				if ( $theme_file !== false ) {
385
					$override_data[] = basename( $theme_file );
386
				}
387
			}
388
		}
389
		return $override_data;
390
	}
391
}
392
393
WC_Tracker::init();
394