238 lines
6.6 KiB
PHP
238 lines
6.6 KiB
PHP
<?php
|
|
/**
|
|
* WC Data Store.
|
|
*
|
|
* @package WooCommerce\Classes
|
|
* @since 3.0.0
|
|
* @version 3.0.0
|
|
*/
|
|
|
|
defined( 'ABSPATH' ) || exit;
|
|
|
|
/**
|
|
* Data store class.
|
|
*/
|
|
class WC_Data_Store {
|
|
|
|
/**
|
|
* Contains an instance of the data store class that we are working with.
|
|
*
|
|
* @var WC_Data_Store
|
|
*/
|
|
private $instance = null;
|
|
|
|
/**
|
|
* Contains an array of default WC supported data stores.
|
|
* Format of object name => class name.
|
|
* Example: 'product' => 'WC_Product_Data_Store_CPT'
|
|
* You can also pass something like product_<type> for product stores and
|
|
* that type will be used first when available, if a store is requested like
|
|
* this and doesn't exist, then the store would fall back to 'product'.
|
|
* Ran through `woocommerce_data_stores`.
|
|
*
|
|
* @var array
|
|
*/
|
|
private $stores = array(
|
|
'coupon' => 'WC_Coupon_Data_Store_CPT',
|
|
'customer' => 'WC_Customer_Data_Store',
|
|
'customer-download' => 'WC_Customer_Download_Data_Store',
|
|
'customer-download-log' => 'WC_Customer_Download_Log_Data_Store',
|
|
'customer-session' => 'WC_Customer_Data_Store_Session',
|
|
'order' => 'WC_Order_Data_Store_CPT',
|
|
'order-refund' => 'WC_Order_Refund_Data_Store_CPT',
|
|
'order-item' => 'WC_Order_Item_Data_Store',
|
|
'order-item-coupon' => 'WC_Order_Item_Coupon_Data_Store',
|
|
'order-item-fee' => 'WC_Order_Item_Fee_Data_Store',
|
|
'order-item-product' => 'WC_Order_Item_Product_Data_Store',
|
|
'order-item-shipping' => 'WC_Order_Item_Shipping_Data_Store',
|
|
'order-item-tax' => 'WC_Order_Item_Tax_Data_Store',
|
|
'payment-token' => 'WC_Payment_Token_Data_Store',
|
|
'product' => 'WC_Product_Data_Store_CPT',
|
|
'product-grouped' => 'WC_Product_Grouped_Data_Store_CPT',
|
|
'product-variable' => 'WC_Product_Variable_Data_Store_CPT',
|
|
'product-variation' => 'WC_Product_Variation_Data_Store_CPT',
|
|
'shipping-zone' => 'WC_Shipping_Zone_Data_Store',
|
|
'webhook' => 'WC_Webhook_Data_Store',
|
|
);
|
|
|
|
/**
|
|
* Contains the name of the current data store's class name.
|
|
*
|
|
* @var string
|
|
*/
|
|
private $current_class_name = '';
|
|
|
|
/**
|
|
* The object type this store works with.
|
|
*
|
|
* @var string
|
|
*/
|
|
private $object_type = '';
|
|
|
|
|
|
/**
|
|
* Tells WC_Data_Store which object (coupon, product, order, etc)
|
|
* store we want to work with.
|
|
*
|
|
* @throws Exception When validation fails.
|
|
* @param string $object_type Name of object.
|
|
*/
|
|
public function __construct( $object_type ) {
|
|
$this->object_type = $object_type;
|
|
$this->stores = apply_filters( 'woocommerce_data_stores', $this->stores );
|
|
|
|
// If this object type can't be found, check to see if we can load one
|
|
// level up (so if product-type isn't found, we try product).
|
|
if ( ! array_key_exists( $object_type, $this->stores ) ) {
|
|
$pieces = explode( '-', $object_type );
|
|
$object_type = $pieces[0];
|
|
}
|
|
|
|
if ( array_key_exists( $object_type, $this->stores ) ) {
|
|
$store = apply_filters( 'woocommerce_' . $object_type . '_data_store', $this->stores[ $object_type ] );
|
|
if ( is_object( $store ) ) {
|
|
if ( ! $store instanceof WC_Object_Data_Store_Interface ) {
|
|
throw new Exception( __( 'Invalid data store.', 'woocommerce' ) );
|
|
}
|
|
$this->current_class_name = get_class( $store );
|
|
$this->instance = $store;
|
|
} else {
|
|
if ( ! class_exists( $store ) ) {
|
|
throw new Exception( __( 'Invalid data store.', 'woocommerce' ) );
|
|
}
|
|
$this->current_class_name = $store;
|
|
$this->instance = new $store();
|
|
}
|
|
} else {
|
|
throw new Exception( __( 'Invalid data store.', 'woocommerce' ) );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Only store the object type to avoid serializing the data store instance.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function __sleep() {
|
|
return array( 'object_type' );
|
|
}
|
|
|
|
/**
|
|
* Re-run the constructor with the object type.
|
|
*
|
|
* @throws Exception When validation fails.
|
|
*/
|
|
public function __wakeup() {
|
|
$this->__construct( $this->object_type );
|
|
}
|
|
|
|
/**
|
|
* Loads a data store.
|
|
*
|
|
* @param string $object_type Name of object.
|
|
*
|
|
* @since 3.0.0
|
|
* @throws Exception When validation fails.
|
|
* @return WC_Data_Store
|
|
*/
|
|
public static function load( $object_type ) {
|
|
return new WC_Data_Store( $object_type );
|
|
}
|
|
|
|
/**
|
|
* Returns the class name of the current data store.
|
|
*
|
|
* @since 3.0.0
|
|
* @return string
|
|
*/
|
|
public function get_current_class_name() {
|
|
return $this->current_class_name;
|
|
}
|
|
|
|
/**
|
|
* Reads an object from the data store.
|
|
*
|
|
* @since 3.0.0
|
|
* @param WC_Data $data WooCommerce data instance.
|
|
*/
|
|
public function read( &$data ) {
|
|
$this->instance->read( $data );
|
|
}
|
|
|
|
/**
|
|
* Reads multiple objects from the data store.
|
|
*
|
|
* @since 6.9.0
|
|
* @param array[WC_Data] $objects Array of object instances to read.
|
|
*/
|
|
public function read_multiple( &$objects = array() ) {
|
|
// If the datastore allows for bulk-reading, use it.
|
|
if ( is_callable( array( $this->instance, 'read_multiple' ) ) ) {
|
|
$this->instance->read_multiple( $objects );
|
|
} else {
|
|
foreach ( $objects as &$obj ) {
|
|
$this->read( $obj );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create an object in the data store.
|
|
*
|
|
* @since 3.0.0
|
|
* @param WC_Data $data WooCommerce data instance.
|
|
*/
|
|
public function create( &$data ) {
|
|
$this->instance->create( $data );
|
|
}
|
|
|
|
/**
|
|
* Update an object in the data store.
|
|
*
|
|
* @since 3.0.0
|
|
* @param WC_Data $data WooCommerce data instance.
|
|
*/
|
|
public function update( &$data ) {
|
|
$this->instance->update( $data );
|
|
}
|
|
|
|
/**
|
|
* Delete an object from the data store.
|
|
*
|
|
* @since 3.0.0
|
|
* @param WC_Data $data WooCommerce data instance.
|
|
* @param array $args Array of args to pass to the delete method.
|
|
*/
|
|
public function delete( &$data, $args = array() ) {
|
|
$this->instance->delete( $data, $args );
|
|
}
|
|
|
|
/**
|
|
* Data stores can define additional functions (for example, coupons have
|
|
* some helper methods for increasing or decreasing usage). This passes
|
|
* through to the instance if that function exists.
|
|
*
|
|
* @since 3.0.0
|
|
* @param string $method Method.
|
|
* @param mixed $parameters Parameters.
|
|
* @return mixed
|
|
*/
|
|
public function __call( $method, $parameters ) {
|
|
if ( is_callable( array( $this->instance, $method ) ) ) {
|
|
$object = array_shift( $parameters );
|
|
$parameters = array_merge( array( &$object ), $parameters );
|
|
return $this->instance->$method( ...$parameters );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if the data store we are working with has a callable method.
|
|
*
|
|
* @param string $method Method name.
|
|
*
|
|
* @return bool Whether the passed method is callable.
|
|
*/
|
|
public function has_callable( string $method ) : bool {
|
|
return is_callable( array( $this->instance, $method ) );
|
|
}
|
|
}
|