Completed
Push — master ( 309357...67521b )
by Mike
13:25
created

woocommerce.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 31 and the first side effect is on line 20.

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
 * Plugin Name: WooCommerce
4
 * Plugin URI: http://www.woothemes.com/woocommerce/
5
 * Description: An e-commerce toolkit that helps you sell anything. Beautifully.
6
 * Version: 2.6.0-dev
7
 * Author: WooThemes
8
 * Author URI: http://woothemes.com
9
 * Requires at least: 4.1
10
 * Tested up to: 4.3
11
 *
12
 * Text Domain: woocommerce
13
 * Domain Path: /i18n/languages/
14
 *
15
 * @package WooCommerce
16
 * @category Core
17
 * @author WooThemes
18
 */
19
if ( ! defined( 'ABSPATH' ) ) {
20
	exit; // Exit if accessed directly.
21
}
22
23
if ( ! class_exists( 'WooCommerce' ) ) :
24
25
/**
26
 * Main WooCommerce Class.
27
 *
28
 * @class WooCommerce
29
 * @version	2.5.0
30
 */
31
final class WooCommerce {
32
33
	/**
34
	 * WooCommerce version.
35
	 *
36
	 * @var string
37
	 */
38
	public $version = '2.6.0';
39
40
	/**
41
	 * The single instance of the class.
42
	 *
43
	 * @var WooCommerce
44
	 * @since 2.1
45
	 */
46
	protected static $_instance = null;
47
48
	/**
49
	 * Session instance.
50
	 *
51
	 * @var WC_Session
52
	 */
53
	public $session = null;
54
55
	/**
56
	 * Query instance.
57
	 *
58
	 * @var WC_Query
59
	 */
60
	public $query = null;
61
62
	/**
63
	 * Product factory instance.
64
	 *
65
	 * @var WC_Product_Factory
66
	 */
67
	public $product_factory = null;
68
69
	/**
70
	 * Countries instance.
71
	 *
72
	 * @var WC_Countries
73
	 */
74
	public $countries = null;
75
76
	/**
77
	 * Integrations instance.
78
	 *
79
	 * @var WC_Integrations
80
	 */
81
	public $integrations = null;
82
83
	/**
84
	 * Cart instance.
85
	 *
86
	 * @var WC_Cart
87
	 */
88
	public $cart = null;
89
90
	/**
91
	 * Customer instance.
92
	 *
93
	 * @var WC_Customer
94
	 */
95
	public $customer = null;
96
97
	/**
98
	 * Order factory instance.
99
	 *
100
	 * @var WC_Order_Factory
101
	 */
102
	public $order_factory = null;
103
104
	/**
105
	 * Main WooCommerce Instance.
106
	 *
107
	 * Ensures only one instance of WooCommerce is loaded or can be loaded.
108
	 *
109
	 * @since 2.1
110
	 * @static
111
	 * @see WC()
112
	 * @return WooCommerce - Main instance.
113
	 */
114
	public static function instance() {
115
		if ( is_null( self::$_instance ) ) {
116
			self::$_instance = new self();
117
		}
118
		return self::$_instance;
119
	}
120
121
	/**
122
	 * Cloning is forbidden.
123
	 * @since 2.1
124
	 */
125
	public function __clone() {
126
		_doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'woocommerce' ), '2.1' );
127
	}
128
129
	/**
130
	 * Unserializing instances of this class is forbidden.
131
	 * @since 2.1
132
	 */
133
	public function __wakeup() {
134
		_doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'woocommerce' ), '2.1' );
135
	}
136
137
	/**
138
	 * Auto-load in-accessible properties on demand.
139
	 * @param mixed $key
140
	 * @return mixed
141
	 */
142
	public function __get( $key ) {
143
		if ( in_array( $key, array( 'payment_gateways', 'shipping', 'mailer', 'checkout' ) ) ) {
144
			return $this->$key();
145
		}
146
	}
147
148
	/**
149
	 * WooCommerce Constructor.
150
	 */
151
	public function __construct() {
152
		$this->define_constants();
153
		$this->includes();
154
		$this->init_hooks();
155
156
		do_action( 'woocommerce_loaded' );
157
	}
158
159
	/**
160
	 * Hook into actions and filters.
161
	 * @since  2.3
162
	 */
163
	private function init_hooks() {
164
		register_activation_hook( __FILE__, array( 'WC_Install', 'install' ) );
165
		add_action( 'after_setup_theme', array( $this, 'setup_environment' ) );
166
		add_action( 'after_setup_theme', array( $this, 'include_template_functions' ), 11 );
167
		add_action( 'init', array( $this, 'init' ), 0 );
168
		add_action( 'init', array( 'WC_Shortcodes', 'init' ) );
169
		add_action( 'init', array( 'WC_Emails', 'init_transactional_emails' ) );
170
	}
171
172
	/**
173
	 * Define WC Constants.
174
	 */
175
	private function define_constants() {
176
		$upload_dir = wp_upload_dir();
177
178
		$this->define( 'WC_PLUGIN_FILE', __FILE__ );
179
		$this->define( 'WC_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
180
		$this->define( 'WC_VERSION', $this->version );
181
		$this->define( 'WOOCOMMERCE_VERSION', $this->version );
182
		$this->define( 'WC_ROUNDING_PRECISION', 4 );
183
		$this->define( 'WC_DISCOUNT_ROUNDING_MODE', 2 );
184
		$this->define( 'WC_TAX_ROUNDING_MODE', 'yes' === get_option( 'woocommerce_prices_include_tax', 'no' ) ? 2 : 1 );
185
		$this->define( 'WC_DELIMITER', '|' );
186
		$this->define( 'WC_LOG_DIR', $upload_dir['basedir'] . '/wc-logs/' );
187
		$this->define( 'WC_SESSION_CACHE_GROUP', 'wc_session_id' );
188
	}
189
190
	/**
191
	 * Define constant if not already set.
192
	 *
193
	 * @param  string $name
194
	 * @param  string|bool $value
195
	 */
196
	private function define( $name, $value ) {
197
		if ( ! defined( $name ) ) {
198
			define( $name, $value );
199
		}
200
	}
201
202
	/**
203
	 * What type of request is this?
204
	 * string $type ajax, frontend or admin.
205
	 *
206
	 * @return bool
207
	 */
208
	private function is_request( $type ) {
209
		switch ( $type ) {
210
			case 'admin' :
211
				return is_admin();
212
			case 'ajax' :
213
				return defined( 'DOING_AJAX' );
214
			case 'cron' :
215
				return defined( 'DOING_CRON' );
216
			case 'frontend' :
217
				return ( ! is_admin() || defined( 'DOING_AJAX' ) ) && ! defined( 'DOING_CRON' );
218
		}
219
	}
220
221
	/**
222
	 * Include required core files used in admin and on the frontend.
223
	 */
224
	public function includes() {
225
		include_once( 'includes/class-wc-autoloader.php' );
226
		include_once( 'includes/wc-core-functions.php' );
227
		include_once( 'includes/wc-widget-functions.php' );
228
		include_once( 'includes/wc-webhook-functions.php' );
229
		include_once( 'includes/class-wc-install.php' );
230
		include_once( 'includes/class-wc-geolocation.php' );
231
		include_once( 'includes/class-wc-download-handler.php' );
232
		include_once( 'includes/class-wc-comments.php' );
233
		include_once( 'includes/class-wc-post-data.php' );
234
		include_once( 'includes/class-wc-ajax.php' );
235
236
		if ( $this->is_request( 'admin' ) ) {
237
			include_once( 'includes/admin/class-wc-admin.php' );
238
		}
239
240
		if ( $this->is_request( 'frontend' ) ) {
241
			$this->frontend_includes();
242
		}
243
244
		if ( $this->is_request( 'frontend' ) || $this->is_request( 'cron' ) ) {
245
			include_once( 'includes/abstracts/abstract-wc-session.php' );
246
			include_once( 'includes/class-wc-session-handler.php' );
247
		}
248
249
		if ( $this->is_request( 'cron' ) && 'yes' === get_option( 'woocommerce_allow_tracking', 'no' ) ) {
250
			include_once( 'includes/class-wc-tracker.php' );
251
		}
252
253
		$this->query = include( 'includes/class-wc-query.php' );                // The main query class
254
		$this->api   = include( 'includes/class-wc-api.php' );                  // API Class
255
256
		include_once( 'includes/class-wc-auth.php' );                           // Auth Class
257
		include_once( 'includes/class-wc-post-types.php' );                     // Registers post types
258
		include_once( 'includes/abstracts/abstract-wc-product.php' );           // Products
259
		include_once( 'includes/abstracts/abstract-wc-order.php' );             // Orders
260
		include_once( 'includes/abstracts/abstract-wc-settings-api.php' );      // Settings API (for gateways, shipping, and integrations)
261
		include_once( 'includes/abstracts/abstract-wc-shipping-method.php' );   // A Shipping method
262
		include_once( 'includes/abstracts/abstract-wc-payment-gateway.php' );   // A Payment gateway
263
		include_once( 'includes/abstracts/abstract-wc-integration.php' );       // An integration with a service
264
		include_once( 'includes/class-wc-product-factory.php' );                // Product factory
265
		include_once( 'includes/class-wc-countries.php' );                      // Defines countries and states
266
		include_once( 'includes/class-wc-integrations.php' );                   // Loads integrations
267
		include_once( 'includes/class-wc-cache-helper.php' );                   // Cache Helper
268
269
		if ( defined( 'WP_CLI' ) && WP_CLI ) {
270
			include_once( 'includes/class-wc-cli.php' );
271
		}
272
	}
273
274
	/**
275
	 * Include required frontend files.
276
	 */
277
	public function frontend_includes() {
278
		include_once( 'includes/wc-cart-functions.php' );
279
		include_once( 'includes/wc-notice-functions.php' );
280
		include_once( 'includes/wc-template-hooks.php' );
281
		include_once( 'includes/class-wc-template-loader.php' );                // Template Loader
282
		include_once( 'includes/class-wc-frontend-scripts.php' );               // Frontend Scripts
283
		include_once( 'includes/class-wc-form-handler.php' );                   // Form Handlers
284
		include_once( 'includes/class-wc-cart.php' );                           // The main cart class
285
		include_once( 'includes/class-wc-tax.php' );                            // Tax class
286
		include_once( 'includes/class-wc-customer.php' );                       // Customer class
287
		include_once( 'includes/class-wc-shortcodes.php' );                     // Shortcodes class
288
		include_once( 'includes/class-wc-https.php' );                          // https Helper
289
		include_once( 'includes/class-wc-embed.php' );                          // Embeds
290
	}
291
292
	/**
293
	 * Function used to Init WooCommerce Template Functions - This makes them pluggable by plugins and themes.
294
	 */
295
	public function include_template_functions() {
296
		include_once( 'includes/wc-template-functions.php' );
297
	}
298
299
	/**
300
	 * Init WooCommerce when WordPress Initialises.
301
	 */
302
	public function init() {
303
		// Before init action.
304
		do_action( 'before_woocommerce_init' );
305
306
		// Set up localisation.
307
		$this->load_plugin_textdomain();
308
309
		// Load class instances.
310
		$this->product_factory = new WC_Product_Factory();                      // Product Factory to create new product instances
311
		$this->order_factory   = new WC_Order_Factory();                        // Order Factory to create new order instances
312
		$this->countries       = new WC_Countries();                            // Countries class
313
		$this->integrations    = new WC_Integrations();                         // Integrations class
314
315
		// Session class, handles session data for users - can be overwritten if custom handler is needed.
316
		if ( $this->is_request( 'frontend' ) || $this->is_request( 'cron' ) ) {
317
			$session_class  = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' );
318
			$this->session  = new $session_class();
319
		}
320
321
		// Classes/actions loaded for the frontend and for ajax requests.
322
		if ( $this->is_request( 'frontend' ) ) {
323
			$this->cart     = new WC_Cart();                                    // Cart class, stores the cart contents
324
			$this->customer = new WC_Customer();                                // Customer class, handles data such as customer location
325
		}
326
327
		$this->load_webhooks();
328
329
		// Init action.
330
		do_action( 'woocommerce_init' );
331
	}
332
333
	/**
334
	 * Load Localisation files.
335
	 *
336
	 * Note: the first-loaded translation file overrides any following ones if the same translation is present.
337
	 *
338
	 * Locales found in:
339
	 *      - WP_LANG_DIR/woocommerce/woocommerce-LOCALE.mo
340
	 *      - WP_LANG_DIR/plugins/woocommerce-LOCALE.mo
341
	 */
342
	public function load_plugin_textdomain() {
343
		$locale = apply_filters( 'plugin_locale', get_locale(), 'woocommerce' );
344
345
		load_textdomain( 'woocommerce', WP_LANG_DIR . '/woocommerce/woocommerce-' . $locale . '.mo' );
346
		load_plugin_textdomain( 'woocommerce', false, plugin_basename( dirname( __FILE__ ) ) . '/i18n/languages' );
347
	}
348
349
	/**
350
	 * Ensure theme and server variable compatibility and setup image sizes.
351
	 */
352
	public function setup_environment() {
353
		/**
354
		 * @deprecated 2.2 Use WC()->template_path()
355
		 */
356
		$this->define( 'WC_TEMPLATE_PATH', $this->template_path() );
357
358
		$this->add_thumbnail_support();
359
		$this->add_image_sizes();
360
	}
361
362
	/**
363
	 * Ensure post thumbnail support is turned on.
364
	 */
365
	private function add_thumbnail_support() {
366
		if ( ! current_theme_supports( 'post-thumbnails' ) ) {
367
			add_theme_support( 'post-thumbnails' );
368
		}
369
		add_post_type_support( 'product', 'thumbnail' );
370
	}
371
372
	/**
373
	 * Add WC Image sizes to WP.
374
	 *
375
	 * @since 2.3
376
	 */
377
	private function add_image_sizes() {
378
		$shop_thumbnail = wc_get_image_size( 'shop_thumbnail' );
379
		$shop_catalog	= wc_get_image_size( 'shop_catalog' );
380
		$shop_single	= wc_get_image_size( 'shop_single' );
381
382
		add_image_size( 'shop_thumbnail', $shop_thumbnail['width'], $shop_thumbnail['height'], $shop_thumbnail['crop'] );
383
		add_image_size( 'shop_catalog', $shop_catalog['width'], $shop_catalog['height'], $shop_catalog['crop'] );
384
		add_image_size( 'shop_single', $shop_single['width'], $shop_single['height'], $shop_single['crop'] );
385
	}
386
387
	/**
388
	 * Get the plugin url.
389
	 * @return string
390
	 */
391
	public function plugin_url() {
392
		return untrailingslashit( plugins_url( '/', __FILE__ ) );
393
	}
394
395
	/**
396
	 * Get the plugin path.
397
	 * @return string
398
	 */
399
	public function plugin_path() {
400
		return untrailingslashit( plugin_dir_path( __FILE__ ) );
401
	}
402
403
	/**
404
	 * Get the template path.
405
	 * @return string
406
	 */
407
	public function template_path() {
408
		return apply_filters( 'woocommerce_template_path', 'woocommerce/' );
409
	}
410
411
	/**
412
	 * Get Ajax URL.
413
	 * @return string
414
	 */
415
	public function ajax_url() {
416
		return admin_url( 'admin-ajax.php', 'relative' );
417
	}
418
419
	/**
420
	 * Return the WC API URL for a given request.
421
	 *
422
	 * @param string $request
423
	 * @param mixed $ssl (default: null)
424
	 * @return string
425
	 */
426
	public function api_request_url( $request, $ssl = null ) {
427
		if ( is_null( $ssl ) ) {
428
			$scheme = parse_url( home_url(), PHP_URL_SCHEME );
429
		} elseif ( $ssl ) {
430
			$scheme = 'https';
431
		} else {
432
			$scheme = 'http';
433
		}
434
435
		if ( strstr( get_option( 'permalink_structure' ), '/index.php/' ) ) {
436
			$api_request_url = trailingslashit( home_url( '/index.php/wc-api/' . $request, $scheme ) );
437
		} elseif ( get_option( 'permalink_structure' ) ) {
438
			$api_request_url = trailingslashit( home_url( '/wc-api/' . $request, $scheme ) );
439
		} else {
440
			$api_request_url = add_query_arg( 'wc-api', $request, trailingslashit( home_url( '', $scheme ) ) );
441
		}
442
443
		return esc_url_raw( apply_filters( 'woocommerce_api_request_url', $api_request_url, $request, $ssl ) );
444
	}
445
446
	/**
447
	 * Load & enqueue active webhooks.
448
	 *
449
	 * @since 2.2
450
	 */
451
	private function load_webhooks() {
452
		if ( false === ( $webhooks = get_transient( 'woocommerce_webhook_ids' ) ) ) {
453
			$webhooks = get_posts( array(
454
				'fields'         => 'ids',
455
				'post_type'      => 'shop_webhook',
456
				'post_status'    => 'publish',
457
				'posts_per_page' => -1
458
			) );
459
			set_transient( 'woocommerce_webhook_ids', $webhooks );
460
		}
461
		foreach ( $webhooks as $webhook_id ) {
462
			$webhook = new WC_Webhook( $webhook_id );
463
			$webhook->enqueue();
464
		}
465
	}
466
467
	/**
468
	 * Get Checkout Class.
469
	 * @return WC_Checkout
470
	 */
471
	public function checkout() {
472
		return WC_Checkout::instance();
473
	}
474
475
	/**
476
	 * Get gateways class.
477
	 * @return WC_Payment_Gateways
478
	 */
479
	public function payment_gateways() {
480
		return WC_Payment_Gateways::instance();
481
	}
482
483
	/**
484
	 * Get shipping class.
485
	 * @return WC_Shipping
486
	 */
487
	public function shipping() {
488
		return WC_Shipping::instance();
489
	}
490
491
	/**
492
	 * Email Class.
493
	 * @return WC_Emails
494
	 */
495
	public function mailer() {
496
		return WC_Emails::instance();
497
	}
498
}
499
500
endif;
501
502
/**
503
 * Main instance of WooCommerce.
504
 *
505
 * Returns the main instance of WC to prevent the need to use globals.
506
 *
507
 * @since  2.1
508
 * @return WooCommerce
509
 */
510
function WC() {
511
	return WooCommerce::instance();
512
}
513
514
// Global for backwards compatibility.
515
$GLOBALS['woocommerce'] = WC();
516