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