A guide to WooCommerce's main instance (and friends)
Like... a lot of code..
class WooCommerce
Singleton??
A pattern that means only ONE instance of the object can exist
<?php /* In includes/class-woocommerce.php */
Final class WooCommerce {
/**
* Main WooCommerce Instance.
* @see WC()
* @return WooCommerce - Main instance.
*/
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
WC() (in capitals)
A helper function is registered to make things simple
<?php /* In your plugin / theme / code / whatever */
class MyPlugin {
public function doSomethingWithWooCommerce(){
/* Doing it the long way */
$woo = WooCommerce::instance();
/* Much shorter! */
$also_woo = WC();
}
private function isWooCommerceRestRequest(){
/* we can chain */
return WC()->is_rest_api_request();
}
}
Boot Sequence
This is how WooCommerce is loaded, offers a great insight into where you can hook in or customise!
<?php /* in includes/class-woocommerce.php */
Final class WooCommerce {
/**
* WooCommerce Constructor.
*/
public function __construct() {
$this->define_constants();
$this->define_tables();
$this->includes();
$this->init_hooks();
}
define_constants()
Uses a 'safe define' so you can set them earlier..
<?php /* in includes/class-woocommerce.php */
Final class WooCommerce {
/**
* Define WC Constants.
*/
private function define_constants() {
$upload_dir = wp_upload_dir( null, false );
$this->define( 'WC_ABSPATH', dirname( WC_PLUGIN_FILE ) . '/' );
$this->define( 'WC_PLUGIN_BASENAME', plugin_basename( WC_PLUGIN_FILE ) );
$this->define( 'WC_VERSION', $this->version );
$this->define( 'WOOCOMMERCE_VERSION', $this->version );
$this->define( 'WC_ROUNDING_PRECISION', 6 );
$this->define( 'WC_DISCOUNT_ROUNDING_MODE', 2 );
$this->define( 'WC_TAX_ROUNDING_MODE', 'yes' === get_option( 'woocommerce_prices_include_tax', 'no' ) ? 2 : 1 );
$this->define( 'WC_DELIMITER', '|' );
$this->define( 'WC_LOG_DIR', $upload_dir['basedir'] . '/wc-logs/' );
$this->define( 'WC_SESSION_CACHE_GROUP', 'wc_session_id' );
$this->define( 'WC_TEMPLATE_DEBUG_MODE', false );
$this->define( 'WC_NOTICE_MIN_PHP_VERSION', '5.6.20' );
$this->define( 'WC_NOTICE_MIN_WP_VERSION', '4.9' );
}
includes()
define_tables()
read the source, not much to them!
init_hooks
Sets up the rest of the loading..
WooCommerce->init()
<?php /* in includes/class-woocommerce.php */
Final class WooCommerce {
/**
* Hook into actions and filters.
*
* @since 2.3
*/
private function init_hooks() {
register_activation_hook( WC_PLUGIN_FILE, array( 'WC_Install', 'install' ) );
register_shutdown_function( array( $this, 'log_errors' ) );
add_action( 'plugins_loaded', array( $this, 'on_plugins_loaded' ), -1 );
add_action( 'after_setup_theme', array( $this, 'setup_environment' ) );
add_action( 'after_setup_theme', array( $this, 'include_template_functions' ), 11 );
add_action( 'init', array( $this, 'init' ), 0 );
add_action( 'init', array( 'WC_Shortcodes', 'init' ) );
add_action( 'init', array( 'WC_Emails', 'init_transactional_emails' ) );
add_action( 'switch_blog', array( $this, 'wpdb_table_fix' ), 0 );
add_action( 'activated_plugin', array( $this, 'activated_plugin' ) );
add_action( 'deactivated_plugin', array( $this, 'deactivated_plugin' ) );
}
properties and methods
What else can we get access to?
Public Properties
WC()->{prop_name}
<?php /* in includes/class-woocommerce.php */
Final class WooCommerce {
public $version = '3.6.5';
public $session;
public $query;
public $product_factory;
public $countries;
public $integrations;
public $cart;
public $customer;
public $order_factory;
public $structured_data;
Public Methods
WC()->{method_name}()
<?php /* in includes/class-woocommerce.php */
Final class WooCommerce {
public function queue() {
return WC_Queue::instance();
}
public function checkout() {
return WC_Checkout::instance();
}
public function payment_gateways() {
return WC_Payment_Gateways::instance();
}
public function shipping() {
return WC_Shipping::instance();
}
public function mailer() {
return WC_Emails::instance();
}
Public Methods as props
WC()->{method_name}
<?php /* in includes/class-woocommerce.php */
Final class WooCommerce {
/**
* Auto-load in-accessible properties on demand.
*
* @param mixed $key Key name.
* @return mixed
*/
public function __get( $key ) {
if ( in_array( $key, array( 'payment_gateways', 'shipping', 'mailer', 'checkout' ), true ) ) {
return $this->$key();
}
}
<?php /* in your/theme/functions.php */
/* get the cart contents */
$cart = WC()->cart->get_cart_contents();
/* Change an email class */
WC()->emails()->emails['email-slug'] = new MyEmailClass();
/* Queue up a background action */
WC()->queue()->add( 'my_background_action_callback', [ 'hello world', WC()->session ],
function my_background_action_callback( $args ) {
// Do something that takes a long time here
}
/* Set your plugin on the main instance */
$woo = WC();
$woo->my_plugin = new MyPluginClass();
Any Questions?