Set reading to prevent exceptions during DB load
This commit is contained in:
parent
7e30e8dda3
commit
d9798f7226
|
@ -27,6 +27,12 @@ abstract class WC_Data {
|
|||
*/
|
||||
protected $_data = array();
|
||||
|
||||
/**
|
||||
* True when reading from the database.
|
||||
* @var bool
|
||||
*/
|
||||
protected $_reading = false;
|
||||
|
||||
/**
|
||||
* Stores meta in cache for future reads.
|
||||
* A group must be set to to enable caching.
|
||||
|
@ -377,33 +383,17 @@ abstract class WC_Data {
|
|||
* @return mixed
|
||||
*/
|
||||
protected function get_prop() {
|
||||
$args = func_get_args();
|
||||
$target = &$this->_data;
|
||||
$args = func_get_args();
|
||||
$prop = &$this->_data;
|
||||
|
||||
foreach ( $args as $arg ) {
|
||||
if ( ! isset( $target[ $arg ] ) ) {
|
||||
if ( ! isset( $prop[ $arg ] ) ) {
|
||||
return false;
|
||||
}
|
||||
$target = &$target[ $arg ];
|
||||
$prop = &$prop[ $arg ];
|
||||
}
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all props to passed key value pairs using setters and ignoring invalid
|
||||
* values with the try/catch.
|
||||
* @param array $values
|
||||
*/
|
||||
protected function set_props( $values = array() ) {
|
||||
foreach ( $values as $prop => $value ) {
|
||||
try {
|
||||
$this->{"set_$prop"}( $value );
|
||||
} catch ( WC_Data_Exception $e ) {
|
||||
// Default value will be left as-is.
|
||||
unset( $e );
|
||||
}
|
||||
}
|
||||
return $prop;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -413,7 +403,7 @@ abstract class WC_Data {
|
|||
*/
|
||||
protected function set_prop() {
|
||||
if ( func_num_args() < 2 ) {
|
||||
$this->throw_exception( 'invalid_value', 'set_prop requires at least 2 parameters' );
|
||||
$this->invalid_data( 'invalid_value', 'set_prop requires at least 2 parameters' );
|
||||
}
|
||||
|
||||
$args = func_get_args();
|
||||
|
@ -428,12 +418,14 @@ abstract class WC_Data {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns an invalid data WP_Error object.
|
||||
* When invalid data is found, throw an exception unless reading from the DB.
|
||||
* @param string $message Error Message.
|
||||
* @param mixed $data Data the user tried to set.
|
||||
* @throws WC_Data_Exception
|
||||
*/
|
||||
protected function throw_exception( $error_code, $error_message, $http_status_code = 400 ) {
|
||||
throw new WC_Data_Exception( $error_code, $error_message, $http_status_code );
|
||||
protected function invalid_data( $error_code, $error_message, $http_status_code = 400 ) {
|
||||
if ( ! $this->_reading ) {
|
||||
throw new WC_Data_Exception( $error_code, $error_message, $http_status_code );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,6 +108,8 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
|
|||
* @param int|object|WC_Order $order Order to init.
|
||||
*/
|
||||
public function __construct( $order = 0 ) {
|
||||
$this->set_defaults();
|
||||
|
||||
if ( is_numeric( $order ) && $order > 0 ) {
|
||||
$this->read( $order );
|
||||
} elseif ( $order instanceof self ) {
|
||||
|
@ -199,6 +201,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
|
|||
return;
|
||||
}
|
||||
|
||||
$this->_reading = true;
|
||||
// Map standard post data
|
||||
$this->set_id( $post_object->ID );
|
||||
$this->set_parent_id( $post_object->post_parent );
|
||||
|
@ -219,6 +222,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
|
|||
|
||||
// Load meta data
|
||||
$this->read_meta_data();
|
||||
$this->_reading = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -605,7 +609,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
|
|||
*/
|
||||
public function set_parent_id( $value ) {
|
||||
if ( $value && ! get_post( $value ) ) {
|
||||
$this->throw_exception( 'order_invalid_parent_id', __( 'Invalid parent ID', 'woocommerce' ) );
|
||||
$this->invalid_data( 'order_invalid_parent_id', __( 'Invalid parent ID', 'woocommerce' ) );
|
||||
}
|
||||
$this->set_prop( 'parent_id', absint( $value ) );
|
||||
}
|
||||
|
@ -654,7 +658,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
|
|||
*/
|
||||
public function set_currency( $value ) {
|
||||
if ( $value && ! in_array( $value, array_keys( get_woocommerce_currencies() ) ) ) {
|
||||
$this->throw_exception( 'order_invalid_currency', __( 'Invalid currency code', 'woocommerce' ) );
|
||||
$this->invalid_data( 'order_invalid_currency', __( 'Invalid currency code', 'woocommerce' ) );
|
||||
}
|
||||
$this->set_prop( 'currency', $value );
|
||||
}
|
||||
|
|
|
@ -434,6 +434,8 @@ class WC_REST_Orders_Controller extends WC_REST_Posts_Controller {
|
|||
}
|
||||
|
||||
return $order->get_id();
|
||||
} catch ( WC_Data_Exception $e ) {
|
||||
return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
|
||||
} catch ( WC_REST_Exception $e ) {
|
||||
return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
|
||||
}
|
||||
|
|
|
@ -74,8 +74,10 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
|
|||
public function read( $id ) {
|
||||
parent::read( $id );
|
||||
if ( $this->get_id() ) {
|
||||
$this->_reading = true;
|
||||
$this->set_discount( get_metadata( 'order_item', $this->get_id(), 'discount_amount', true ) );
|
||||
$this->set_discount_tax( get_metadata( 'order_item', $this->get_id(), 'discount_amount_tax', true ) );
|
||||
$this->_reading = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -83,11 +83,13 @@ class WC_Order_Item_Fee extends WC_Order_Item {
|
|||
public function read( $id ) {
|
||||
parent::read( $id );
|
||||
if ( $this->get_id() ) {
|
||||
$this->_reading = true;
|
||||
$this->set_tax_class( get_metadata( 'order_item', $this->get_id(), '_tax_class', true ) );
|
||||
$this->set_tax_status( get_metadata( 'order_item', $this->get_id(), '_tax_status', true ) );
|
||||
$this->set_total( get_metadata( 'order_item', $this->get_id(), '_line_total', true ) );
|
||||
$this->set_total_tax( get_metadata( 'order_item', $this->get_id(), '_line_tax', true ) );
|
||||
$this->set_taxes( get_metadata( 'order_item', $this->get_id(), '_line_tax_data', true ) );
|
||||
$this->_reading = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +131,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
|
|||
*/
|
||||
public function set_tax_class( $value ) {
|
||||
if ( $value && ! in_array( $value, WC_Tax::get_tax_classes() ) ) {
|
||||
$this->throw_exception( 'order_item_fee_invalid_tax_class', __( 'Invalid tax class', 'woocommerce' ) );
|
||||
$this->invalid_data( 'order_item_fee_invalid_tax_class', __( 'Invalid tax class', 'woocommerce' ) );
|
||||
}
|
||||
$this->set_prop( 'tax_class', $value );
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
|
|||
public function read( $id ) {
|
||||
parent::read( $id );
|
||||
if ( $this->get_id() ) {
|
||||
$this->_reading = true;
|
||||
$this->set_product_id( get_metadata( 'order_item', $this->get_id(), '_product_id', true ) );
|
||||
$this->set_variation_id( get_metadata( 'order_item', $this->get_id(), '_variation_id', true ) );
|
||||
$this->set_quantity( get_metadata( 'order_item', $this->get_id(), '_qty', true ) );
|
||||
|
@ -105,6 +106,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
|
|||
$this->set_total( get_metadata( 'order_item', $this->get_id(), '_line_total', true ) );
|
||||
$this->set_total_tax( get_metadata( 'order_item', $this->get_id(), '_line_tax', true ) );
|
||||
$this->set_taxes( get_metadata( 'order_item', $this->get_id(), '_line_tax_data', true ) );
|
||||
$this->_reading = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,7 +237,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
|
|||
*/
|
||||
public function set_quantity( $value ) {
|
||||
if ( 0 >= $value ) {
|
||||
$this->throw_exception( 'order_item_product_invalid_quantity', __( 'Quantity must be positive', 'woocommerce' ) );
|
||||
$this->invalid_data( 'order_item_product_invalid_quantity', __( 'Quantity must be positive', 'woocommerce' ) );
|
||||
}
|
||||
$this->set_prop( 'quantity', wc_stock_amount( $value ) );
|
||||
}
|
||||
|
@ -247,7 +249,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
|
|||
*/
|
||||
public function set_tax_class( $value ) {
|
||||
if ( $value && ! in_array( $value, WC_Tax::get_tax_classes() ) ) {
|
||||
$this->throw_exception( 'order_item_product_invalid_tax_class', __( 'Invalid tax class', 'woocommerce' ) );
|
||||
$this->invalid_data( 'order_item_product_invalid_tax_class', __( 'Invalid tax class', 'woocommerce' ) );
|
||||
}
|
||||
$this->set_prop( 'tax_class', $value );
|
||||
}
|
||||
|
@ -258,8 +260,8 @@ class WC_Order_Item_Product extends WC_Order_Item {
|
|||
* @throws WC_Data_Exception
|
||||
*/
|
||||
public function set_product_id( $value ) {
|
||||
if ( 0 >= $value || 'product' !== get_post_type( absint( $value ) ) ) {
|
||||
$this->throw_exception( 'order_item_product_invalid_product_id', __( 'Invalid product ID', 'woocommerce' ) );
|
||||
if ( $value > 0 && 'product' !== get_post_type( absint( $value ) ) ) {
|
||||
$this->invalid_data( 'order_item_product_invalid_product_id', __( 'Invalid product ID', 'woocommerce' ) );
|
||||
}
|
||||
$this->set_prop( 'product_id', absint( $value ) );
|
||||
}
|
||||
|
@ -270,8 +272,8 @@ class WC_Order_Item_Product extends WC_Order_Item {
|
|||
* @throws WC_Data_Exception
|
||||
*/
|
||||
public function set_variation_id( $value ) {
|
||||
if ( 0 >= $value || 'product_variation' !== get_post_type( $value ) ) {
|
||||
$this->throw_exception( 'order_item_product_invalid_variation_id', __( 'Invalid variation ID', 'woocommerce' ) );
|
||||
if ( $value > 0 && 'product_variation' !== get_post_type( $value ) ) {
|
||||
$this->invalid_data( 'order_item_product_invalid_variation_id', __( 'Invalid variation ID', 'woocommerce' ) );
|
||||
}
|
||||
$this->set_prop( 'variation_id', absint( $value ) );
|
||||
}
|
||||
|
@ -349,7 +351,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
|
|||
*/
|
||||
public function set_product( $product ) {
|
||||
if ( ! is_a( $product, 'WC_Product' ) ) {
|
||||
$this->throw_exception( 'order_item_product_invalid_product', __( 'Invalid product', 'woocommerce' ) );
|
||||
$this->invalid_data( 'order_item_product_invalid_product', __( 'Invalid product', 'woocommerce' ) );
|
||||
}
|
||||
$this->set_product_id( $product->get_id() );
|
||||
$this->set_name( $product->get_title() );
|
||||
|
|
|
@ -74,10 +74,12 @@ class WC_Order_Item_Shipping extends WC_Order_Item {
|
|||
public function read( $id ) {
|
||||
parent::read( $id );
|
||||
if ( $this->get_id() ) {
|
||||
$this->_reading = true;
|
||||
$this->set_method_id( get_metadata( 'order_item', $this->get_id(), 'method_id', true ) );
|
||||
$this->set_total( get_metadata( 'order_item', $this->get_id(), 'cost', true ) );
|
||||
$this->set_total_tax( get_metadata( 'order_item', $this->get_id(), 'total_tax', true ) );
|
||||
$this->set_taxes( get_metadata( 'order_item', $this->get_id(), 'taxes', true ) );
|
||||
$this->_reading = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,11 +35,13 @@ class WC_Order_Item_Tax extends WC_Order_Item {
|
|||
public function read( $id ) {
|
||||
parent::read( $id );
|
||||
if ( $this->get_id() ) {
|
||||
$this->_reading = true;
|
||||
$this->set_rate_id( get_metadata( 'order_item', $this->get_id(), 'rate_id', true ) );
|
||||
$this->set_label( get_metadata( 'order_item', $this->get_id(), 'label', true ) );
|
||||
$this->set_compound( get_metadata( 'order_item', $this->get_id(), 'compound', true ) );
|
||||
$this->set_tax_total( get_metadata( 'order_item', $this->get_id(), 'tax_amount', true ) );
|
||||
$this->set_shipping_tax_total( get_metadata( 'order_item', $this->get_id(), 'shipping_tax_amount', true ) );
|
||||
$this->_reading = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,11 +70,13 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
|
|||
* @access private
|
||||
*/
|
||||
public function set_all( $data ) {
|
||||
$this->_reading = true;
|
||||
foreach ( $data as $key => $value ) {
|
||||
if ( is_callable( array( $this, "set_$key" ) ) ) {
|
||||
$this->{"set_$key"}( $value );
|
||||
}
|
||||
}
|
||||
$this->_reading = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -244,11 +246,13 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
|
|||
}
|
||||
|
||||
if ( $data ) {
|
||||
$this->_reading = true;
|
||||
$this->set_order_id( $data->order_id );
|
||||
$this->set_id( $data->order_item_id );
|
||||
$this->set_name( $data->order_item_name );
|
||||
$this->set_type( $data->order_item_type );
|
||||
$this->read_meta_data();
|
||||
$this->_reading = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ class WC_Order_Refund extends WC_Abstract_Order {
|
|||
|
||||
// Read additonal order data
|
||||
if ( $this->get_id() ) {
|
||||
$this->_reading = true;
|
||||
$post_object = get_post( $id );
|
||||
$this->set_amount( get_post_meta( $this->get_id(), '_refund_amount', true ) );
|
||||
|
||||
|
@ -73,6 +74,7 @@ class WC_Order_Refund extends WC_Abstract_Order {
|
|||
|
||||
// post_excerpt was used before refund_reason meta.
|
||||
$this->set_reason( metadata_exists( 'post', $this->get_id(), '_refund_reason' ) ? get_post_meta( $this->get_id(), '_refund_reason', true ) : absint( $post_object->post_excerpt ) );
|
||||
$this->_reading = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,45 +36,6 @@ class WC_Order extends WC_Abstract_Order {
|
|||
'_customer_note', '_date_completed', '_date_paid', '_payment_tokens',
|
||||
);
|
||||
|
||||
/**
|
||||
* Map of meta data keys to internal prop keys.
|
||||
* @var array
|
||||
*/
|
||||
protected $prop_to_meta_key = array(
|
||||
'order_key' => '_order_key',
|
||||
'customer_id' => '_customer_user',
|
||||
'billing_first_name' => '_billing_first_name',
|
||||
'billing_last_name' => '_billing_last_name',
|
||||
'billing_company' => '_billing_company',
|
||||
'billing_address_1' => '_billing_address_1',
|
||||
'billing_address_2' => '_billing_address_2',
|
||||
'billing_city' => '_billing_city',
|
||||
'billing_state' => '_billing_state',
|
||||
'billing_postcode' => '_billing_postcode',
|
||||
'billing_country' => '_billing_country',
|
||||
'billing_email' => '_billing_email',
|
||||
'billing_phone' => '_billing_phone',
|
||||
'shipping_first_name' => '_shipping_first_name',
|
||||
'shipping_last_name' => '_shipping_last_name',
|
||||
'shipping_company' => '_shipping_company',
|
||||
'shipping_address_1' => '_shipping_address_1',
|
||||
'shipping_address_2' => '_shipping_address_2',
|
||||
'shipping_city' => '_shipping_city',
|
||||
'shipping_state' => '_shipping_state',
|
||||
'shipping_postcode' => '_shipping_postcode',
|
||||
'shipping_country' => '_shipping_country',
|
||||
'payment_method' => '_payment_method',
|
||||
'payment_method_title' => '_payment_method_title',
|
||||
'transaction_id' => '_transaction_id',
|
||||
'customer_ip_address' => '_customer_ip_address',
|
||||
'customer_user_agent' => '_customer_user_agent',
|
||||
'created_via' => '_created_via',
|
||||
'customer_note' => '_customer_note',
|
||||
'date_completed' => '_completed_date',
|
||||
'date_paid' => '_paid_date',
|
||||
'cart_hash' => '_cart_hash',
|
||||
);
|
||||
|
||||
/**
|
||||
* Stores data about status changes so relevant hooks can be fired.
|
||||
* @var bool|array
|
||||
|
@ -308,17 +269,45 @@ class WC_Order extends WC_Abstract_Order {
|
|||
return;
|
||||
}
|
||||
|
||||
$post_object = get_post( $this->get_id() );
|
||||
$values = array(
|
||||
'customer_note' => $post_object->post_excerpt,
|
||||
);
|
||||
$this->_reading = true;
|
||||
$post_object = get_post( $this->get_id() );
|
||||
|
||||
foreach ( $this->prop_to_meta_key as $prop => $meta_key ) {
|
||||
$values[ $prop ] = get_post_meta( $this->get_id(), $meta_key, true );
|
||||
}
|
||||
|
||||
$this->set_props( $values );
|
||||
// Read additonal order data
|
||||
$this->set_order_key( get_post_meta( $this->get_id(), '_order_key', true ) );
|
||||
$this->set_customer_id( get_post_meta( $this->get_id(), '_customer_user', true ) );
|
||||
$this->set_billing_first_name( get_post_meta( $this->get_id(), '_billing_first_name', true ) );
|
||||
$this->set_billing_last_name( get_post_meta( $this->get_id(), '_billing_last_name', true ) );
|
||||
$this->set_billing_company( get_post_meta( $this->get_id(), '_billing_company', true ) );
|
||||
$this->set_billing_address_1( get_post_meta( $this->get_id(), '_billing_address_1', true ) );
|
||||
$this->set_billing_address_2( get_post_meta( $this->get_id(), '_billing_address_2', true ) );
|
||||
$this->set_billing_city( get_post_meta( $this->get_id(), '_billing_city', true ) );
|
||||
$this->set_billing_state( get_post_meta( $this->get_id(), '_billing_state', true ) );
|
||||
$this->set_billing_postcode( get_post_meta( $this->get_id(), '_billing_postcode', true ) );
|
||||
$this->set_billing_country( get_post_meta( $this->get_id(), '_billing_country', true ) );
|
||||
$this->set_billing_email( get_post_meta( $this->get_id(), '_billing_email', true ) );
|
||||
$this->set_billing_phone( get_post_meta( $this->get_id(), '_billing_phone', true ) );
|
||||
$this->set_shipping_first_name( get_post_meta( $this->get_id(), '_shipping_first_name', true ) );
|
||||
$this->set_shipping_last_name( get_post_meta( $this->get_id(), '_shipping_last_name', true ) );
|
||||
$this->set_shipping_company( get_post_meta( $this->get_id(), '_shipping_company', true ) );
|
||||
$this->set_shipping_address_1( get_post_meta( $this->get_id(), '_shipping_address_1', true ) );
|
||||
$this->set_shipping_address_2( get_post_meta( $this->get_id(), '_shipping_address_2', true ) );
|
||||
$this->set_shipping_city( get_post_meta( $this->get_id(), '_shipping_city', true ) );
|
||||
$this->set_shipping_state( get_post_meta( $this->get_id(), '_shipping_state', true ) );
|
||||
$this->set_shipping_postcode( get_post_meta( $this->get_id(), '_shipping_postcode', true ) );
|
||||
$this->set_shipping_country( get_post_meta( $this->get_id(), '_shipping_country', true ) );
|
||||
$this->set_payment_method( get_post_meta( $this->get_id(), '_payment_method', true ) );
|
||||
$this->set_payment_method_title( get_post_meta( $this->get_id(), '_payment_method_title', true ) );
|
||||
$this->set_transaction_id( get_post_meta( $this->get_id(), '_transaction_id', true ) );
|
||||
$this->set_customer_ip_address( get_post_meta( $this->get_id(), '_customer_ip_address', true ) );
|
||||
$this->set_customer_user_agent( get_post_meta( $this->get_id(), '_customer_user_agent', true ) );
|
||||
$this->set_created_via( get_post_meta( $this->get_id(), '_created_via', true ) );
|
||||
$this->set_customer_note( get_post_meta( $this->get_id(), '_customer_note', true ) );
|
||||
$this->set_date_completed( get_post_meta( $this->get_id(), '_completed_date', true ) );
|
||||
$this->set_date_paid( get_post_meta( $this->get_id(), '_paid_date', true ) );
|
||||
$this->set_cart_hash( get_post_meta( $this->get_id(), '_cart_hash', true ) );
|
||||
$this->set_customer_note( $post_object->post_excerpt );
|
||||
$this->maybe_set_user_billing_email();
|
||||
$this->_reading = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -957,7 +946,7 @@ class WC_Order extends WC_Abstract_Order {
|
|||
*/
|
||||
public function set_billing_email( $value ) {
|
||||
if ( $value && ! is_email( $value ) ) {
|
||||
$this->throw_exception( 'order_invalid_billing_email', __( 'Invalid order billing email address', 'woocommerce' ) );
|
||||
$this->invalid_data( 'order_invalid_billing_email', __( 'Invalid order billing email address', 'woocommerce' ) );
|
||||
}
|
||||
$this->set_prop( 'billing', 'email', sanitize_email( $value ) );
|
||||
}
|
||||
|
|
|
@ -799,6 +799,7 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case {
|
|||
$this->assertEquals( $set_to, $object->get_billing_email() );
|
||||
|
||||
$set_to = 'not an email';
|
||||
$this->setExpectedException( 'WC_Data_Exception' );
|
||||
$object->set_billing_email( $set_to );
|
||||
$this->assertEquals( 'test@test.com', $object->get_billing_email() );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue