Merge pull request #11208 from woothemes/orders-crud-classes

Orders crud classes
This commit is contained in:
Mike Jolley 2016-08-05 15:44:15 +01:00 committed by GitHub
commit 1c592b3872
20 changed files with 6630 additions and 2451 deletions

View File

@ -0,0 +1,595 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Legacy Abstract Order
*
* Legacy and deprecated functions are here to keep the WC_Abstract_Order clean.
* This class will be removed in future versions.
*
* @version 2.7.0
* @package WooCommerce/Abstracts
* @category Abstract Class
* @author WooThemes
*/
abstract class WC_Abstract_Legacy_Order extends WC_Data {
/**
* Update a line item for the order.
*
* Note this does not update order totals.
*
* @param object|int $item order item ID or item object.
* @param WC_Product $product
* @param array $args data to update.
* @return int updated order item ID
*/
public function update_product( $item, $product, $args ) {
_deprecated_function( 'WC_Order::update_product', '2.7', 'Interact with WC_Order_Item_Product class' );
if ( is_numeric( $item ) ) {
$item = $this->get_item( $item );
}
if ( ! is_object( $item ) || ! $item->is_type( 'line_item' ) ) {
return false;
}
if ( ! $this->get_id() ) {
$this->save(); // Order must exist
}
// BW compatibility with old args
if ( isset( $args['totals'] ) ) {
foreach ( $args['totals'] as $key => $value ) {
if ( 'tax' === $key ) {
$args['total_tax'] = $value;
} elseif ( 'tax_data' === $key ) {
$args['taxes'] = $value;
} else {
$args[ $key ] = $value;
}
}
}
// Handly qty if set
if ( isset( $args['qty'] ) ) {
if ( $product->backorders_require_notification() && $product->is_on_backorder( $args['qty'] ) ) {
$item->add_meta_data( apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ) ), $args['qty'] - max( 0, $product->get_total_stock() ), true );
}
$args['subtotal'] = $args['subtotal'] ? $args['subtotal'] : $product->get_price_excluding_tax( $args['qty'] );
$args['total'] = $args['total'] ? $args['total'] : $product->get_price_excluding_tax( $args['qty'] );
}
$item->set_order_id( $this->get_id() );
$item->set_all( $args );
$item->save();
do_action( 'woocommerce_order_edit_product', $this->get_id(), $item->get_id(), $args, $product );
return $item->get_id();
}
/**
* Update coupon for order. Note this does not update order totals.
* @param object|int $item
* @param array $args
* @return int updated order item ID
*/
public function update_coupon( $item, $args ) {
_deprecated_function( 'WC_Order::update_coupon', '2.7', 'Interact with WC_Order_Item_Coupon class' );
if ( is_numeric( $item ) ) {
$item = $this->get_item( $item );
}
if ( ! is_object( $item ) || ! $item->is_type( 'coupon' ) ) {
return false;
}
if ( ! $this->get_id() ) {
$this->save(); // Order must exist
}
// BW compatibility for old args
if ( isset( $args['discount_amount'] ) ) {
$args['discount'] = $args['discount_amount'];
}
if ( isset( $args['discount_amount_tax'] ) ) {
$args['discount_tax'] = $args['discount_amount_tax'];
}
$item->set_order_id( $this->get_id() );
$item->set_all( $args );
$item->save();
do_action( 'woocommerce_order_update_coupon', $this->get_id(), $item->get_id(), $args );
return $item->get_id();
}
/**
* Update shipping method for order.
*
* Note this does not update the order total.
*
* @param object|int $item
* @param array $args
* @return int updated order item ID
*/
public function update_shipping( $item, $args ) {
_deprecated_function( 'WC_Order::update_shipping', '2.7', 'Interact with WC_Order_Item_Shipping class' );
if ( is_numeric( $item ) ) {
$item = $this->get_item( $item );
}
if ( ! is_object( $item ) || ! $item->is_type( 'shipping' ) ) {
return false;
}
if ( ! $this->get_id() ) {
$this->save(); // Order must exist
}
// BW compatibility for old args
if ( isset( $args['cost'] ) ) {
$args['total'] = $args['cost'];
}
$item->set_order_id( $this->get_id() );
$item->set_all( $args );
$item->save();
$this->calculate_shipping();
do_action( 'woocommerce_order_update_shipping', $this->get_id(), $item->get_id(), $args );
return $item->get_id();
}
/**
* Update fee for order.
*
* Note this does not update order totals.
*
* @param object|int $item
* @param array $args
* @return int updated order item ID
*/
public function update_fee( $item, $args ) {
_deprecated_function( 'WC_Order::update_fee', '2.7', 'Interact with WC_Order_Item_Fee class' );
if ( is_numeric( $item ) ) {
$item = $this->get_item( $item );
}
if ( ! is_object( $item ) || ! $item->is_type( 'fee' ) ) {
return false;
}
if ( ! $this->get_id() ) {
$this->save(); // Order must exist
}
$item->set_order_id( $this->get_id() );
$item->set_all( $args );
$item->save();
do_action( 'woocommerce_order_update_fee', $this->get_id(), $item->get_id(), $args );
return $item->get_id();
}
/**
* Update tax line on order.
* Note this does not update order totals.
*
* @since 2.7
* @param object|int $item
* @param array $args
* @return int updated order item ID
*/
public function update_tax( $item, $args ) {
_deprecated_function( 'WC_Order::update_tax', '2.7', 'Interact with WC_Order_Item_Tax class' );
if ( is_numeric( $item ) ) {
$item = $this->get_item( $item );
}
if ( ! is_object( $item ) || ! $item->is_type( 'tax' ) ) {
return false;
}
if ( ! $this->get_id() ) {
$this->save(); // Order must exist
}
$item->set_order_id( $this->get_id() );
$item->set_all( $args );
$item->save();
do_action( 'woocommerce_order_update_tax', $this->get_id(), $item->get_id(), $args );
return $item->get_id();
}
/**
* Get a product (either product or variation).
* @deprecated Add deprecation notices in future release. Replaced with $item->get_product()
* @param object $item
* @return WC_Product|bool
*/
public function get_product_from_item( $item ) {
if ( is_callable( array( $item, 'get_product' ) ) ) {
$product = $item->get_product();
} else {
$product = false;
}
return apply_filters( 'woocommerce_get_product_from_item', $product, $item, $this );
}
/**
* Set the customer address.
* @param array $address Address data.
* @param string $type billing or shipping.
*/
public function set_address( $address, $type = 'billing' ) {
foreach ( $address as $key => $value ) {
update_post_meta( $this->get_id(), "_{$type}_" . $key, $value );
if ( is_callable( array( $this, "set_{$type}_{$key}" ) ) ) {
$this->{"set_{$type}_{$key}"}( $value );
}
}
}
/**
* Set an order total.
* @param float $amount
* @param string $total_type
* @return bool
*/
public function legacy_set_total( $amount, $total_type = 'total' ) {
if ( ! in_array( $total_type, array( 'shipping', 'tax', 'shipping_tax', 'total', 'cart_discount', 'cart_discount_tax' ) ) ) {
return false;
}
switch ( $total_type ) {
case 'total' :
$amount = wc_format_decimal( $amount, wc_get_price_decimals() );
$this->set_total( $amount );
update_post_meta( $this->get_id(), '_order_total', $amount );
break;
case 'cart_discount' :
$amount = wc_format_decimal( $amount );
$this->set_discount_total( $amount );
update_post_meta( $this->get_id(), '_cart_discount', $amount );
break;
case 'cart_discount_tax' :
$amount = wc_format_decimal( $amount );
$this->set_discount_tax( $amount );
update_post_meta( $this->get_id(), '_cart_discount_tax', $amount );
break;
case 'shipping' :
$amount = wc_format_decimal( $amount );
$this->set_shipping_total( $amount );
update_post_meta( $this->get_id(), '_order_shipping', $amount );
break;
case 'shipping_tax' :
$amount = wc_format_decimal( $amount );
$this->set_shipping_tax( $amount );
update_post_meta( $this->get_id(), '_order_shipping_tax', $amount );
break;
case 'tax' :
$amount = wc_format_decimal( $amount );
$this->set_cart_tax( $amount );
update_post_meta( $this->get_id(), '_order_tax', $amount );
break;
}
return true;
}
/**
* Magic __isset method for backwards compatibility.
* @param string $key
* @return bool
*/
public function __isset( $key ) {
// Legacy properties which could be accessed directly in the past.
$legacy_props = array( 'completed_date', 'id', 'order_type', 'post', 'status', 'post_status', 'customer_note', 'customer_message', 'user_id', 'customer_user', 'prices_include_tax', 'tax_display_cart', 'display_totals_ex_tax', 'display_cart_ex_tax', 'order_date', 'modified_date', 'cart_discount', 'cart_discount_tax', 'order_shipping', 'order_shipping_tax', 'order_total', 'order_tax', 'billing_first_name', 'billing_last_name', 'billing_company', 'billing_address_1', 'billing_address_2', 'billing_city', 'billing_state', 'billing_postcode', 'billing_country', 'billing_phone', 'billing_email', 'shipping_first_name', 'shipping_last_name', 'shipping_company', 'shipping_address_1', 'shipping_address_2', 'shipping_city', 'shipping_state', 'shipping_postcode', 'shipping_country', 'customer_ip_address', 'customer_user_agent', 'payment_method_title', 'payment_method', 'order_currency' );
return $this->get_id() ? ( in_array( $key, $legacy_props ) || metadata_exists( 'post', $this->get_id(), '_' . $key ) ) : false;
}
/**
* Magic __get method for backwards compatibility.
* @param string $key
* @return mixed
*/
public function __get( $key ) {
_doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.7' );
if ( 'completed_date' === $key ) {
return $this->get_date_completed();
} elseif ( 'paid_date' === $key ) {
return $this->get_date_paid();
} elseif ( 'modified_date' === $key ) {
return $this->get_date_modified();
} elseif ( 'order_date' === $key ) {
return $this->get_date_created();
} elseif ( 'id' === $key ) {
return $this->get_id();
} elseif ( 'post' === $key ) {
return get_post( $this->get_id() );
} elseif ( 'status' === $key || 'post_status' === $key ) {
return $this->get_status();
} elseif ( 'customer_message' === $key || 'customer_note' === $key ) {
return $this->get_customer_note();
} elseif ( in_array( $key, array( 'user_id', 'customer_user' ) ) ) {
return $this->get_customer_id();
} elseif ( 'tax_display_cart' === $key ) {
return get_option( 'woocommerce_tax_display_cart' );
} elseif ( 'display_totals_ex_tax' === $key ) {
return 'excl' === get_option( 'woocommerce_tax_display_cart' );
} elseif ( 'display_cart_ex_tax' === $key ) {
return 'excl' === get_option( 'woocommerce_tax_display_cart' );
} elseif ( 'cart_discount' === $key ) {
return $this->get_discount();
} elseif ( 'cart_discount_tax' === $key ) {
return $this->get_discount_tax();
} elseif ( 'order_tax' === $key ) {
return $this->get_cart_tax();
} elseif ( 'order_shipping_tax' === $key ) {
return $this->get_shipping_tax();
} elseif ( 'order_shipping' === $key ) {
return $this->get_shipping_total();
} elseif ( 'order_total' === $key ) {
return $this->get_total();
} elseif ( 'order_type' === $key ) {
return $this->get_type();
} elseif ( 'order_currency' === $key ) {
return $this->get_currency();
} elseif ( 'order_version' === $key ) {
return $this->get_version();
} elseif ( is_callable( array( $this, "get_{$key}" ) ) ) {
return $this->{"get_{$key}"}();
} else {
return get_post_meta( $this->get_id(), '_' . $key, true );
}
}
/**
* has_meta function for order items.
*
* @param string $order_item_id
* @return array of meta data.
*/
public function has_meta( $order_item_id ) {
global $wpdb;
_deprecated_function( 'has_meta', '2.7', 'WC_Order_item::get_meta_data' );
return $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value, meta_id, order_item_id
FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id = %d
ORDER BY meta_id", absint( $order_item_id ) ), ARRAY_A );
}
/**
* Display meta data belonging to an item.
* @param array $item
*/
public function display_item_meta( $item ) {
_deprecated_function( 'get_item_meta', '2.7', 'wc_display_item_meta' );
$product = $item->get_product();
$item_meta = new WC_Order_Item_Meta( $item, $product );
$item_meta->display();
}
/**
* Display download links for an order item.
* @param array $item
*/
public function display_item_downloads( $item ) {
_deprecated_function( 'display_item_downloads', '2.7', 'wc_display_item_downloads' );
$product = $item->get_product();
if ( $product && $product->exists() && $product->is_downloadable() && $this->is_download_permitted() ) {
$download_files = $this->get_item_downloads( $item );
$i = 0;
$links = array();
foreach ( $download_files as $download_id => $file ) {
$i++;
$prefix = count( $download_files ) > 1 ? sprintf( __( 'Download %d', 'woocommerce' ), $i ) : __( 'Download', 'woocommerce' );
$links[] = '<small class="download-url">' . $prefix . ': <a href="' . esc_url( $file['download_url'] ) . '" target="_blank">' . esc_html( $file['name'] ) . '</a></small>' . "\n";
}
echo '<br/>' . implode( '<br/>', $links );
}
}
/**
* Get the Download URL.
*
* @param int $product_id
* @param int $download_id
* @return string
*/
public function get_download_url( $product_id, $download_id ) {
_deprecated_function( 'get_download_url', '2.7', 'WC_Order_Item_Product::get_item_download_url' );
return add_query_arg( array(
'download_file' => $product_id,
'order' => $this->get_order_key(),
'email' => urlencode( $this->get_billing_email() ),
'key' => $download_id,
), trailingslashit( home_url() ) );
}
/**
* Get the downloadable files for an item in this order.
*
* @param array $item
* @return array
*/
public function get_item_downloads( $item ) {
_deprecated_function( 'get_item_downloads', '2.7', 'WC_Order_Item_Product::get_item_downloads' );
return $item->get_item_downloads();
}
/**
* Gets shipping total. Alias of WC_Order::get_shipping_total().
* @deprecated 2.7.0 since this is an alias only.
* @return float
*/
public function get_total_shipping() {
return $this->get_shipping_total();
}
/**
* Get order item meta.
* @deprecated 2.7.0
* @param mixed $order_item_id
* @param string $key (default: '')
* @param bool $single (default: false)
* @return array|string
*/
public function get_item_meta( $order_item_id, $key = '', $single = false ) {
_deprecated_function( 'get_item_meta', '2.7', 'wc_get_order_item_meta' );
return get_metadata( 'order_item', $order_item_id, $key, $single );
}
/**
* Get all item meta data in array format in the order it was saved. Does not group meta by key like get_item_meta().
*
* @param mixed $order_item_id
* @return array of objects
*/
public function get_item_meta_array( $order_item_id ) {
_deprecated_function( 'get_item_meta_array', '2.7', 'WC_Order_Item::get_meta_data() (note the format has changed)' );
$item = $this->get_item( $order_item_id );
$meta_data = $item->get_meta_data();
$item_meta_array = array();
foreach ( $meta_data as $meta ) {
$item_meta_array[ $meta->meta_id ] = $meta;
}
return $item_meta_array;
}
/**
* Expand item meta into the $item array.
* @deprecated 2.7.0 Item meta no longer expanded due to new order item
* classes. This function now does nothing to avoid data breakage.
* @param array $item before expansion.
* @return array
*/
public function expand_item_meta( $item ) {
_deprecated_function( 'expand_item_meta', '2.7', '' );
return $item;
}
/**
* Load the order object. Called from the constructor.
* @deprecated 2.7.0 Logic moved to constructor
* @param int|object|WC_Order $order Order to init.
*/
protected function init( $order ) {
_deprecated_function( 'init', '2.7', 'Logic moved to constructor' );
if ( is_numeric( $order ) ) {
$this->read( $order );
} elseif ( $order instanceof WC_Order ) {
$this->read( absint( $order->get_id() ) );
} elseif ( isset( $order->ID ) ) {
$this->read( absint( $order->ID ) );
}
}
/**
* Gets an order from the database.
* @deprecated 2.7
* @param int $id (default: 0).
* @return bool
*/
public function get_order( $id = 0 ) {
_deprecated_function( 'get_order', '2.7', 'read' );
if ( ! $id ) {
return false;
}
if ( $result = get_post( $id ) ) {
$this->populate( $result );
return true;
}
return false;
}
/**
* Populates an order from the loaded post data.
* @deprecated 2.7
* @param mixed $result
*/
public function populate( $result ) {
_deprecated_function( 'populate', '2.7', 'read' );
$this->read( $result->ID );
}
/**
* Cancel the order and restore the cart (before payment).
* @deprecated 2.7.0 Moved to event handler.
* @param string $note (default: '') Optional note to add.
*/
public function cancel_order( $note = '' ) {
_deprecated_function( 'cancel_order', '2.7', 'update_status' );
WC()->session->set( 'order_awaiting_payment', false );
$this->update_status( 'cancelled', $note );
}
/**
* Record sales.
* @deprecated 2.7.0
*/
public function record_product_sales() {
_deprecated_function( 'record_product_sales', '2.7', 'wc_update_total_sales_counts' );
wc_update_total_sales_counts( $this->get_id() );
}
/**
* Increase applied coupon counts.
* @deprecated 2.7.0
*/
public function increase_coupon_usage_counts() {
_deprecated_function( 'increase_coupon_usage_counts', '2.7', 'wc_update_coupon_usage_counts' );
wc_update_coupon_usage_counts( $this->get_id() );
}
/**
* Decrease applied coupon counts.
* @deprecated 2.7.0
*/
public function decrease_coupon_usage_counts() {
_deprecated_function( 'decrease_coupon_usage_counts', '2.7', 'wc_update_coupon_usage_counts' );
wc_update_coupon_usage_counts( $this->get_id() );
}
/**
* Reduce stock levels for all line items in the order.
* @deprecated 2.7.0
*/
public function reduce_order_stock() {
_deprecated_function( 'reduce_order_stock', '2.7', 'wc_reduce_stock_levels' );
wc_reduce_stock_levels( $this->get_id() );
}
/**
* Send the stock notifications.
* @deprecated 2.7.0 No longer needs to be called directly.
*/
public function send_stock_notifications( $product, $new_stock, $qty_ordered ) {
_deprecated_function( 'send_stock_notifications', '2.7' );
}
/**
* Output items for display in html emails.
* @deprecated 2.7.0 Moved to template functions.
* @param array $args Items args.
* @return string
*/
public function email_order_items_table( $args = array() ) {
_deprecated_function( 'email_order_items_table', '2.7', 'wc_get_email_order_items' );
return wc_get_email_order_items( $this, $args );
}
/**
* Get currency.
* @deprecated 2.7.0
*/
public function get_order_currency() {
_deprecated_function( 'get_order_currency', '2.7', 'get_currency' );
return apply_filters( 'woocommerce_get_order_currency', $this->get_currency(), $this );
}
}

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@ if ( ! defined( 'ABSPATH' ) ) {
* The WooCommerce order factory creating the right order objects.
*
* @class WC_Order_Factory
* @version 2.2.0
* @version 2.7.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
@ -23,7 +23,7 @@ class WC_Order_Factory {
* @param bool $the_order (default: false)
* @return WC_Order|bool
*/
public function get_order( $the_order = false ) {
public static function get_order( $the_order = false ) {
global $post;
if ( false === $the_order ) {
@ -31,7 +31,7 @@ class WC_Order_Factory {
} elseif ( is_numeric( $the_order ) ) {
$the_order = get_post( $the_order );
} elseif ( $the_order instanceof WC_Order ) {
$the_order = get_post( $the_order->id );
$the_order = get_post( $the_order->get_id() );
}
if ( ! $the_order || ! is_object( $the_order ) ) {
@ -56,4 +56,49 @@ class WC_Order_Factory {
return new $classname( $the_order );
}
/**
* Get order item.
* @param int
* @return WC_Order_Item
*/
public static function get_order_item( $item_id = 0 ) {
global $wpdb;
if ( is_numeric( $item_id ) ) {
$item_data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d LIMIT 1;", $item_id ) );
$item_type = $item_data->order_item_type;
} elseif ( $item_id instanceof WC_Order_Item ) {
$item_data = $item_id->get_data();
$item_type = $item_data->get_type();
} elseif( is_object( $item_id ) && ! empty( $item_id->order_item_type ) ) {
$item_data = $item_id;
$item_type = $item_id->order_item_type;
} else {
$item_data = false;
$item_type = false;
}
if ( $item_data && $item_type ) {
switch ( $item_type ) {
case 'line_item' :
case 'product' :
return new WC_Order_Item_Product( $item_data );
break;
case 'coupon' :
return new WC_Order_Item_Coupon( $item_data );
break;
case 'fee' :
return new WC_Order_Item_Fee( $item_data );
break;
case 'shipping' :
return new WC_Order_Item_Shipping( $item_data );
break;
case 'tax' :
return new WC_Order_Item_Tax( $item_data );
break;
}
}
return new WC_Order_Item();
}
}

View File

@ -0,0 +1,187 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order Line Item (coupon).
*
* @version 2.7.0
* @since 2.7.0
* @package WooCommerce/Classes
* @author WooThemes
*/
class WC_Order_Item_Coupon extends WC_Order_Item {
/**
* Data properties of this order item object.
* @since 2.7.0
* @var array
*/
protected $_data = array(
'order_id' => 0,
'order_item_id' => 0,
'code' => '',
'discount' => 0,
'discount_tax' => 0,
);
/**
* offsetGet for ArrayAccess/Backwards compatibility.
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @return mixed
*/
public function offsetGet( $offset ) {
if ( 'discount_amount' === $offset ) {
$offset = 'discount';
} elseif ( 'discount_amount_tax' === $offset ) {
$offset = 'discount_tax';
}
return parent::offsetGet( $offset );
}
/**
* offsetSet for ArrayAccess/Backwards compatibility.
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @param mixed $value
*/
public function offsetSet( $offset, $value ) {
if ( 'discount_amount' === $offset ) {
$offset = 'discount';
} elseif ( 'discount_amount_tax' === $offset ) {
$offset = 'discount_tax';
}
parent::offsetSet( $offset, $value );
}
/**
* offsetExists for ArrayAccess
* @param string $offset
* @return bool
*/
public function offsetExists( $offset ) {
if ( in_array( $offset, array( 'discount_amount', 'discount_amount_tax' ) ) ) {
return true;
}
return parent::offsetExists( $offset );
}
/**
* Read/populate data properties specific to this order item.
*/
public function read( $id ) {
parent::read( $id );
if ( $this->get_id() ) {
$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 ) );
}
}
/**
* Save properties specific to this order item.
* @return int Item ID
*/
public function save() {
parent::save();
if ( $this->get_id() ) {
wc_update_order_item_meta( $this->get_id(), 'discount_amount', $this->get_discount() );
wc_update_order_item_meta( $this->get_id(), 'discount_amount_tax', $this->get_discount_tax() );
}
return $this->get_id();
}
/**
* Internal meta keys we don't want exposed as part of meta_data.
* @return array()
*/
protected function get_internal_meta_keys() {
return array( 'discount_amount', 'discount_amount_tax' );
}
/*
|--------------------------------------------------------------------------
| Setters
|--------------------------------------------------------------------------
*/
/**
* Set order item name.
* @param string $value
*/
public function set_name( $value ) {
$this->set_code( $value );
}
/**
* Set code.
* @param string $value
*/
public function set_code( $value ) {
$this->_data['code'] = wc_clean( $value );
}
/**
* Set discount amount.
* @param string $value
*/
public function set_discount( $value ) {
$this->_data['discount'] = wc_format_decimal( $value );
}
/**
* Set discounted tax amount.
* @param string $value
*/
public function set_discount_tax( $value ) {
$this->_data['discount_tax'] = wc_format_decimal( $value );
}
/*
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
*/
/**
* Get order item type.
* @return string
*/
public function get_type() {
return 'coupon';
}
/**
* Get order item name.
* @return string
*/
public function get_name() {
return $this->get_code();
}
/**
* Get coupon code.
* @return string
*/
public function get_code() {
return $this->_data['code'];
}
/**
* Get discount amount.
* @return string
*/
public function get_discount() {
return wc_format_decimal( $this->_data['discount'] );
}
/**
* Get discounted tax amount.
* @return string
*/
public function get_discount_tax() {
return wc_format_decimal( $this->_data['discount_tax'] );
}
}

View File

@ -0,0 +1,231 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order Line Item (fee).
*
* @version 2.7.0
* @since 2.7.0
* @package WooCommerce/Classes
* @author WooThemes
*/
class WC_Order_Item_Fee extends WC_Order_Item {
/**
* Data properties of this order item object.
* @since 2.7.0
* @var array
*/
protected $_data = array(
'order_id' => 0,
'order_item_id' => 0,
'name' => '',
'tax_class' => '',
'tax_status' => 'taxable',
'total' => '',
'total_tax' => '',
'taxes' => array(
'total' => array()
)
);
/**
* offsetGet for ArrayAccess/Backwards compatibility.
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @return mixed
*/
public function offsetGet( $offset ) {
if ( 'line_total' === $offset ) {
$offset = 'total';
} elseif ( 'line_tax' === $offset ) {
$offset = 'total_tax';
} elseif ( 'line_tax_data' === $offset ) {
$offset = 'taxes';
}
return parent::offsetGet( $offset );
}
/**
* offsetSet for ArrayAccess/Backwards compatibility.
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @param mixed $value
*/
public function offsetSet( $offset, $value ) {
if ( 'line_total' === $offset ) {
$offset = 'total';
} elseif ( 'line_tax' === $offset ) {
$offset = 'total_tax';
} elseif ( 'line_tax_data' === $offset ) {
$offset = 'taxes';
}
parent::offsetSet( $offset, $value );
}
/**
* offsetExists for ArrayAccess
* @param string $offset
* @return bool
*/
public function offsetExists( $offset ) {
if ( in_array( $offset, array( 'line_total', 'line_tax', 'line_tax_data' ) ) ) {
return true;
}
return parent::offsetExists( $offset );
}
/**
* Read/populate data properties specific to this order item.
*/
public function read( $id ) {
parent::read( $id );
if ( $this->get_id() ) {
$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 ) );
}
}
/**
* Save properties specific to this order item.
* @return int Item ID
*/
public function save() {
parent::save();
if ( $this->get_id() ) {
wc_update_order_item_meta( $this->get_id(), '_tax_class', $this->get_tax_class() );
wc_update_order_item_meta( $this->get_id(), '_tax_status', $this->get_tax_status() );
wc_update_order_item_meta( $this->get_id(), '_line_total', $this->get_total() );
wc_update_order_item_meta( $this->get_id(), '_line_tax', $this->get_total_tax() );
wc_update_order_item_meta( $this->get_id(), '_line_tax_data', $this->get_taxes() );
}
return $this->get_id();
}
/*
|--------------------------------------------------------------------------
| Setters
|--------------------------------------------------------------------------
*/
/**
* Set tax class.
* @param string $value
*/
public function set_tax_class( $value ) {
$this->_data['tax_class'] = $value;
}
/**
* Set tax_status.
* @param string $value
*/
public function set_tax_status( $value ) {
if ( in_array( $value, array( 'taxable', 'none' ) ) ) {
$this->_data['tax_status'] = $value;
} else {
$this->_data['tax_status'] = 'taxable';
}
}
/**
* Set total.
* @param string $value
*/
public function set_total( $value ) {
$this->_data['total'] = wc_format_decimal( $value );
}
/**
* Set total tax.
* @param string $value
*/
public function set_total_tax( $value ) {
$this->_data['total_tax'] = wc_format_decimal( $value );
}
/**
* Set taxes.
*
* This is an array of tax ID keys with total amount values.
* @param array $raw_tax_data
*/
public function set_taxes( $raw_tax_data ) {
$raw_tax_data = maybe_unserialize( $raw_tax_data );
$tax_data = array(
'total' => array(),
);
if ( ! empty( $raw_tax_data['total'] ) ) {
$tax_data['total'] = array_map( 'wc_format_decimal', $raw_tax_data['total'] );
}
$this->_data['taxes'] = $tax_data;
}
/*
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
*/
/**
* Get order item name.
* @return string
*/
public function get_name() {
return $this->_data['name'] ? $this->_data['name'] : __( 'Fee', 'woocommerce' );
}
/**
* Get order item type.
* @return string
*/
public function get_type() {
return 'fee';
}
/**
* Get tax class.
* @return string
*/
public function get_tax_class() {
return $this->_data['tax_class'];
}
/**
* Get tax status.
* @return string
*/
public function get_tax_status() {
return $this->_data['tax_status'];
}
/**
* Get total fee.
* @return string
*/
public function get_total() {
return wc_format_decimal( $this->_data['total'] );
}
/**
* Get total tax.
* @return string
*/
public function get_total_tax() {
return wc_format_decimal( $this->_data['total_tax'] );
}
/**
* Get fee taxes.
* @return array
*/
public function get_taxes() {
return $this->_data['taxes'];
}
}

View File

@ -1,7 +1,6 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
exit;
}
/**
@ -9,6 +8,7 @@ if ( ! defined( 'ABSPATH' ) ) {
*
* A Simple class for managing order item meta so plugins add it in the correct format.
*
* @deprecated 2.7.0 wc_display_item_meta function is used instead.
* @class order_item_meta
* @version 2.4
* @package WooCommerce/Classes
@ -41,7 +41,6 @@ class WC_Order_Item_Meta {
$this->meta = array_filter( (array) $item );
return;
}
$this->item = $item;
$this->meta = array_filter( (array) $item['item_meta'] );
$this->product = $product;

View File

@ -0,0 +1,412 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order Line Item (product).
*
* @version 2.7.0
* @since 2.7.0
* @package WooCommerce/Classes
* @author WooThemes
*/
class WC_Order_Item_Product extends WC_Order_Item {
/**
* Data properties of this order item object.
* @since 2.7.0
* @var array
*/
protected $_data = array(
'order_id' => 0,
'order_item_id' => 0,
'name' => '',
'product_id' => 0,
'variation_id' => 0,
'qty' => 0,
'tax_class' => '',
'subtotal' => 0,
'subtotal_tax' => 0,
'total' => 0,
'total_tax' => 0,
'taxes' => array(
'subtotal' => array(),
'total' => array()
),
);
/**
* offsetGet for ArrayAccess/Backwards compatibility.
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @return mixed
*/
public function offsetGet( $offset ) {
if ( 'line_subtotal' === $offset ) {
$offset = 'subtotal';
} elseif ( 'line_subtotal_tax' === $offset ) {
$offset = 'subtotal_tax';
} elseif ( 'line_total' === $offset ) {
$offset = 'total';
} elseif ( 'line_tax' === $offset ) {
$offset = 'total_tax';
} elseif ( 'line_tax_data' === $offset ) {
$offset = 'taxes';
}
return parent::offsetGet( $offset );
}
/**
* offsetSet for ArrayAccess/Backwards compatibility.
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @param mixed $value
*/
public function offsetSet( $offset, $value ) {
if ( 'line_subtotal' === $offset ) {
$offset = 'subtotal';
} elseif ( 'line_subtotal_tax' === $offset ) {
$offset = 'subtotal_tax';
} elseif ( 'line_total' === $offset ) {
$offset = 'total';
} elseif ( 'line_tax' === $offset ) {
$offset = 'total_tax';
} elseif ( 'line_tax_data' === $offset ) {
$offset = 'taxes';
}
parent::offsetSet( $offset, $value );
}
/**
* offsetExists for ArrayAccess
* @param string $offset
* @return bool
*/
public function offsetExists( $offset ) {
if ( in_array( $offset, array( 'line_subtotal', 'line_subtotal_tax', 'line_total', 'line_tax', 'line_tax_data', 'item_meta_array', 'item_meta' ) ) ) {
return true;
}
return parent::offsetExists( $offset );
}
/**
* Read/populate data properties specific to this order item.
*/
public function read( $id ) {
parent::read( $id );
if ( $this->get_id() ) {
$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_qty( get_metadata( 'order_item', $this->get_id(), '_qty', true ) );
$this->set_tax_class( get_metadata( 'order_item', $this->get_id(), '_tax_class', true ) );
$this->set_subtotal( get_metadata( 'order_item', $this->get_id(), '_line_subtotal', true ) );
$this->set_subtotal_tax( get_metadata( 'order_item', $this->get_id(), '_line_subtotal_tax', 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 ) );
}
}
/**
* Save properties specific to this order item.
* @return int Item ID
*/
public function save() {
parent::save();
if ( $this->get_id() ) {
wc_update_order_item_meta( $this->get_id(), '_product_id', $this->get_product_id() );
wc_update_order_item_meta( $this->get_id(), '_variation_id', $this->get_variation_id() );
wc_update_order_item_meta( $this->get_id(), '_qty', $this->get_qty() );
wc_update_order_item_meta( $this->get_id(), '_tax_class', $this->get_tax_class() );
wc_update_order_item_meta( $this->get_id(), '_line_subtotal', $this->get_subtotal() );
wc_update_order_item_meta( $this->get_id(), '_line_subtotal_tax', $this->get_subtotal_tax() );
wc_update_order_item_meta( $this->get_id(), '_line_total', $this->get_total() );
wc_update_order_item_meta( $this->get_id(), '_line_tax', $this->get_total_tax() );
wc_update_order_item_meta( $this->get_id(), '_line_tax_data', $this->get_taxes() );
}
return $this->get_id();
}
/**
* Internal meta keys we don't want exposed as part of meta_data.
* @return array()
*/
protected function get_internal_meta_keys() {
return array( '_product_id', '_variation_id', '_qty', '_tax_class', '_line_subtotal', '_line_subtotal_tax', '_line_total', '_line_tax', '_line_tax_data' );
}
/**
* Get the associated product.
* @return WC_Product|bool
*/
public function get_product() {
if ( $this->get_variation_id() ) {
$product = wc_get_product( $this->get_variation_id() );
} else {
$product = wc_get_product( $this->get_product_id() );
}
// Backwards compatible filter from WC_Order::get_product_from_item()
if ( has_filter( 'woocommerce_get_product_from_item' ) ) {
$product = apply_filters( 'woocommerce_get_product_from_item', $product, $this, wc_get_order( $this->get_order_id() ) );
}
return apply_filters( 'woocommerce_order_item_product', $product, $this );
}
/**
* Get the Download URL.
* @param int $download_id
* @return string
*/
public function get_item_download_url( $download_id ) {
$order = $this->get_order();
return $order ? add_query_arg( array(
'download_file' => $this->get_variation_id() ? $this->get_variation_id() : $this->get_product_id(),
'order' => $order->get_order_key(),
'email' => urlencode( $order->get_billing_email() ),
'key' => $download_id
), trailingslashit( home_url() ) ) : '';
}
/**
* Get any associated downloadable files.
* @return array
*/
public function get_item_downloads() {
global $wpdb;
$files = array();
$product = $this->get_product();
$order = $this->get_order();
if ( $product && $order && $product->is_downloadable() && $order->is_download_permitted() ) {
$download_ids = $wpdb->get_col(
$wpdb->prepare(
"SELECT download_id FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE user_email = %s AND order_key = %s AND product_id = %d ORDER BY permission_id",
$order->get_billing_email(),
$order->get_order_key(),
$this->get_variation_id() ? $this->get_variation_id() : $this->get_product_id()
)
);
foreach ( $download_ids as $download_id ) {
if ( $product->has_file( $download_id ) ) {
$files[ $download_id ] = $product->get_file( $download_id );
$files[ $download_id ]['download_url'] = $this->get_item_download_url( $download_id );
}
}
}
return apply_filters( 'woocommerce_get_item_downloads', $files, $this, $order );
}
/**
* Get tax status.
* @return string
*/
public function get_tax_status() {
$product = $this->get_product();
return $product ? $product->get_tax_status() : 'taxable';
}
/*
|--------------------------------------------------------------------------
| Setters
|--------------------------------------------------------------------------
*/
/**
* Set qty.
* @param int $value
*/
public function set_qty( $value ) {
$this->_data['qty'] = wc_stock_amount( $value );
}
/**
* Set tax class.
* @param string $value
*/
public function set_tax_class( $value ) {
$this->_data['tax_class'] = $value;
}
/**
* Set Product ID
* @param int $value
*/
public function set_product_id( $value ) {
$this->_data['product_id'] = absint( $value );
}
/**
* Set variation ID.
* @param int $value
*/
public function set_variation_id( $value ) {
$this->_data['variation_id'] = absint( $value );
}
/**
* Line subtotal (before discounts).
* @param string $value
*/
public function set_subtotal( $value ) {
$this->_data['subtotal'] = wc_format_decimal( $value );
}
/**
* Line total (after discounts).
* @param string $value
*/
public function set_total( $value ) {
$this->_data['total'] = wc_format_decimal( $value );
}
/**
* Line subtotal tax (before discounts).
* @param string $value
*/
public function set_subtotal_tax( $value ) {
$this->_data['subtotal_tax'] = wc_format_decimal( $value );
}
/**
* Line total tax (after discounts).
* @param string $value
*/
public function set_total_tax( $value ) {
$this->_data['total_tax'] = wc_format_decimal( $value );
}
/**
* Set line taxes.
* @param array $raw_tax_data
*/
public function set_taxes( $raw_tax_data ) {
$raw_tax_data = maybe_unserialize( $raw_tax_data );
$tax_data = array(
'total' => array(),
'subtotal' => array()
);
if ( ! empty( $raw_tax_data['total'] ) && ! empty( $raw_tax_data['subtotal'] ) ) {
$tax_data['total'] = array_map( 'wc_format_decimal', $raw_tax_data['total'] );
$tax_data['subtotal'] = array_map( 'wc_format_decimal', $raw_tax_data['subtotal'] );
}
$this->_data['taxes'] = $tax_data;
}
/**
* Set variation data (stored as meta data - write only).
* @param array $data Key/Value pairs
*/
public function set_variation( $data ) {
foreach ( $data as $key => $value ) {
$this->_meta_data[ str_replace( 'attribute_', '', $key ) ] = $value;
}
}
/**
* Set properties based on passed in product object.
* @param WC_Product $product
*/
public function set_product( $product ) {
if ( $product ) {
$this->set_product_id( $product->get_id() );
$this->set_name( $product->get_title() );
$this->set_tax_class( $product->get_tax_class() );
$this->set_variation_id( is_callable( array( $product, 'get_variation_id' ) ) ? $product->get_variation_id() : 0 );
$this->set_variation( is_callable( array( $product, 'get_variation_attributes' ) ) ? $product->get_variation_attributes() : array() );
}
}
/*
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
*/
/**
* Get order item type.
* @return string
*/
public function get_type() {
return 'line_item';
}
/**
* Get product ID.
* @return int
*/
public function get_product_id() {
return absint( $this->_data['product_id'] );
}
/**
* Get variation ID.
* @return int
*/
public function get_variation_id() {
return absint( $this->_data['variation_id'] );
}
/**
* Get qty.
* @return int
*/
public function get_qty() {
return wc_stock_amount( $this->_data['qty'] );
}
/**
* Get tax class.
* @return string
*/
public function get_tax_class() {
return $this->_data['tax_class'];
}
/**
* Get subtotal.
* @return string
*/
public function get_subtotal() {
return wc_format_decimal( $this->_data['subtotal'] );
}
/**
* Get subtotal tax.
* @return string
*/
public function get_subtotal_tax() {
return wc_format_decimal( $this->_data['subtotal_tax'] );
}
/**
* Get total.
* @return string
*/
public function get_total() {
return wc_format_decimal( $this->_data['total'] );
}
/**
* Get total tax.
* @return string
*/
public function get_total_tax() {
return wc_format_decimal( $this->_data['total_tax'] );
}
/**
* Get fee taxes.
* @return array
*/
public function get_taxes() {
return $this->_data['taxes'];
}
}

View File

@ -0,0 +1,233 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order Line Item (shipping).
*
* @version 2.7.0
* @since 2.7.0
* @package WooCommerce/Classes
* @author WooThemes
*/
class WC_Order_Item_Shipping extends WC_Order_Item {
/**
* Data properties of this order item object.
* @since 2.7.0
* @var array
*/
protected $_data = array(
'order_id' => 0,
'order_item_id' => 0,
'method_title' => '',
'method_id' => '',
'total' => 0,
'total_tax' => 0,
'taxes' => array(
'total' => array()
),
);
/**
* offsetGet for ArrayAccess/Backwards compatibility.
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @return mixed
*/
public function offsetGet( $offset ) {
if ( 'cost' === $offset ) {
$offset = 'total';
}
return parent::offsetGet( $offset );
}
/**
* offsetSet for ArrayAccess/Backwards compatibility.
* @deprecated Add deprecation notices in future release.
* @param string $offset
* @param mixed $value
*/
public function offsetSet( $offset, $value ) {
if ( 'cost' === $offset ) {
$offset = 'total';
}
parent::offsetSet( $offset, $value );
}
/**
* offsetExists for ArrayAccess
* @param string $offset
* @return bool
*/
public function offsetExists( $offset ) {
if ( in_array( $offset, array( 'cost' ) ) ) {
return true;
}
return parent::offsetExists( $offset );
}
/**
* Read/populate data properties specific to this order item.
*/
public function read( $id ) {
parent::read( $id );
if ( $this->get_id() ) {
$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 ) );
}
}
/**
* Save properties specific to this order item.
* @return int Item ID
*/
public function save() {
parent::save();
if ( $this->get_id() ) {
wc_update_order_item_meta( $this->get_id(), 'method_id', $this->get_method_id() );
wc_update_order_item_meta( $this->get_id(), 'cost', $this->get_total() );
wc_update_order_item_meta( $this->get_id(), 'total_tax', $this->get_total_tax() );
wc_update_order_item_meta( $this->get_id(), 'taxes', $this->get_taxes() );
}
return $this->get_id();
}
/**
* Internal meta keys we don't want exposed as part of meta_data.
* @return array()
*/
protected function get_internal_meta_keys() {
return array( 'method_id', 'cost', 'total_tax', 'taxes' );
}
/*
|--------------------------------------------------------------------------
| Setters
|--------------------------------------------------------------------------
*/
/**
* Set order item name.
* @param string $value
*/
public function set_name( $value ) {
$this->set_method_title( $value );
}
/**
* Set code.
* @param string $value
*/
public function set_method_title( $value ) {
$this->_data['method_title'] = wc_clean( $value );
}
/**
* Set shipping method id.
* @param string $value
*/
public function set_method_id( $value ) {
$this->_data['method_id'] = wc_clean( $value );
}
/**
* Set total.
* @param string $value
*/
public function set_total( $value ) {
$this->_data['total'] = wc_format_decimal( $value );
}
/**
* Set total tax.
* @param string $value
*/
public function set_total_tax( $value ) {
$this->_data['total_tax'] = wc_format_decimal( $value );
}
/**
* Set taxes.
*
* This is an array of tax ID keys with total amount values.
* @param array $raw_tax_data
*/
public function set_taxes( $raw_tax_data ) {
$raw_tax_data = maybe_unserialize( $raw_tax_data );
$tax_data = array(
'total' => array()
);
if ( ! empty( $raw_tax_data['total'] ) ) {
$tax_data['total'] = array_map( 'wc_format_decimal', $raw_tax_data['total'] );
}
$this->_data['taxes'] = $tax_data;
$this->set_total_tax( array_sum( $tax_data['total'] ) );
}
/*
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
*/
/**
* Get order item type.
* @return string
*/
public function get_type() {
return 'shipping';
}
/**
* Get order item name.
* @return string
*/
public function get_name() {
return $this->get_method_title();
}
/**
* Get title.
* @return string
*/
public function get_method_title() {
return $this->_data['method_title'] ? $this->_data['method_title'] : __( 'Shipping', 'woocommerce' );
}
/**
* Get method ID.
* @return string
*/
public function get_method_id() {
return $this->_data['method_id'];
}
/**
* Get total cost.
* @return string
*/
public function get_total() {
return wc_format_decimal( $this->_data['total'] );
}
/**
* Get total tax.
* @return string
*/
public function get_total_tax() {
return wc_format_decimal( $this->_data['total_tax'] );
}
/**
* Get taxes.
* @return array
*/
public function get_taxes() {
return $this->_data['taxes'];
}
}

View File

@ -0,0 +1,210 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order Line Item (tax).
*
* @version 2.7.0
* @since 2.7.0
* @package WooCommerce/Classes
* @author WooThemes
*/
class WC_Order_Item_Tax extends WC_Order_Item {
/**
* Data properties of this order item object.
* @since 2.7.0
* @var array
*/
protected $_data = array(
'order_id' => 0,
'order_item_id' => 0,
'rate_code' => '',
'rate_id' => 0,
'label' => '',
'compound' => false,
'tax_total' => 0,
'shipping_tax_total' => 0
);
/**
* Read/populate data properties specific to this order item.
*/
public function read( $id ) {
parent::read( $id );
if ( $this->get_id() ) {
$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 ) );
}
}
/**
* Save properties specific to this order item.
* @return int Item ID
*/
public function save() {
parent::save();
if ( $this->get_id() ) {
wc_update_order_item_meta( $this->get_id(), 'rate_id', $this->get_rate_id() );
wc_update_order_item_meta( $this->get_id(), 'label', $this->get_label() );
wc_update_order_item_meta( $this->get_id(), 'compound', $this->get_compound() );
wc_update_order_item_meta( $this->get_id(), 'tax_amount', $this->get_tax_total() );
wc_update_order_item_meta( $this->get_id(), 'shipping_tax_amount', $this->get_shipping_tax_total() );
}
return $this->get_id();
}
/**
* Internal meta keys we don't want exposed as part of meta_data.
* @return array()
*/
protected function get_internal_meta_keys() {
return array( 'rate_id', 'label', 'compound', 'tax_amount', 'shipping_tax_amount' );
}
/**
* Is this a compound tax rate?
* @return boolean
*/
public function is_compound() {
return $this->get_compound();
}
/*
|--------------------------------------------------------------------------
| Setters
|--------------------------------------------------------------------------
*/
/**
* Set order item name.
* @param string $value
*/
public function set_name( $value ) {
$this->set_rate_code( $value );
}
/**
* Set item name.
* @param string $value
*/
public function set_rate_code( $value ) {
$this->_data['rate_code'] = wc_clean( $value );
}
/**
* Set item name.
* @param string $value
*/
public function set_label( $value ) {
$this->_data['label'] = wc_clean( $value );
}
/**
* Set tax rate id.
* @param int $value
*/
public function set_rate_id( $value ) {
$this->_data['rate_id'] = absint( $value );
}
/**
* Set tax total.
* @param string $value
*/
public function set_tax_total( $value ) {
$this->_data['tax_total'] = wc_format_decimal( $value );
}
/**
* Set shipping_tax_total
* @param string $value
*/
public function set_shipping_tax_total( $value ) {
$this->_data['shipping_tax_total'] = wc_format_decimal( $value );
}
/**
* Set compound
* @param bool $value
*/
public function set_compound( $value ) {
$this->_data['compound'] = (bool) $value;
}
/*
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
*/
/**
* Get order item type.
* @return string
*/
public function get_type() {
return 'tax';
}
/**
* Get rate code/name.
* @return string
*/
public function get_name() {
return $this->get_rate_code();
}
/**
* Get rate code/name.
* @return string
*/
public function get_rate_code() {
return $this->_data['rate_code'];
}
/**
* Get label.
* @return string
*/
public function get_label() {
return $this->_data['label'] ? $this->_data['label'] : __( 'Tax', 'woocommerce' );
}
/**
* Get tax rate ID.
* @return int
*/
public function get_rate_id() {
return absint( $this->_data['rate_id'] );
}
/**
* Get tax_total
* @return string
*/
public function get_tax_total() {
return wc_format_decimal( $this->_data['tax_total'] );
}
/**
* Get shipping_tax_total
* @return string
*/
public function get_shipping_tax_total() {
return wc_format_decimal( $this->_data['shipping_tax_total'] );
}
/**
* Get compound.
* @return bool
*/
public function get_compound() {
return (bool) $this->_data['compound'];
}
}

View File

@ -0,0 +1,428 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Order Item
*
* A class which represents an item within an order and handles CRUD.
* Uses ArrayAccess to be BW compatible with WC_Orders::get_items().
*
* @version 2.7.0
* @since 2.7.0
* @package WooCommerce/Classes
* @author WooThemes
*/
class WC_Order_Item extends WC_Data implements ArrayAccess {
/**
* Data array, with defaults.
* @since 2.7.0
* @var array
*/
protected $_data = array(
'order_id' => 0,
'order_item_id' => 0,
'name' => '',
'type' => '',
);
/**
* May store an order to prevent retriving it multiple times.
* @var object
*/
protected $_order;
/**
* Stores meta in cache for future reads.
* A group must be set to to enable caching.
* @var string
*/
protected $_cache_group = 'order_itemmeta';
/**
* Meta type. This should match up with
* the types avaiable at https://codex.wordpress.org/Function_Reference/add_metadata.
* WP defines 'post', 'user', 'comment', and 'term'.
*/
protected $_meta_type = 'order_item';
/**
* Constructor.
* @param int|object|array $order_item ID to load from the DB (optional) or already queried data.
*/
public function __construct( $item = 0 ) {
if ( $item instanceof WC_Order_Item ) {
if ( $this->is_type( $item->get_type() ) ) {
$this->set_all( $item->get_data() );
}
} elseif ( is_array( $item ) ) {
$this->set_all( $item );
} else {
$this->read( $item );
}
}
/**
* Set all data based on input array.
* @param array $data
* @access private
*/
public function set_all( $data ) {
foreach ( $data as $key => $value ) {
if ( is_callable( array( $this, "set_$key" ) ) ) {
$this->{"set_$key"}( $value );
} else {
$this->_data[ $key ] = $value;
}
}
}
/**
* Type checking
* @param string|array $Type
* @return boolean
*/
public function is_type( $type ) {
return is_array( $type ) ? in_array( $this->get_type(), $type ) : $type === $this->get_type();
}
/**
* Get qty.
* @return int
*/
public function get_qty() {
return 1;
}
/**
* Get parent order object.
* @return int
*/
public function get_order() {
if ( ! $this->_order ) {
$this->_order = wc_get_order( $this->get_order_id() );
}
return $this->_order;
}
/*
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
*/
/**
* Get order item ID.
* @return int
*/
public function get_id() {
return $this->get_order_item_id();
}
/**
* Get order ID this meta belongs to.
* @return int
*/
public function get_order_id() {
return absint( $this->_data['order_id'] );
}
/**
* Get order item ID this meta belongs to.
* @return int
*/
protected function get_order_item_id() {
return absint( $this->_data['order_item_id'] );
}
/**
* Get order item name.
* @return string
*/
public function get_name() {
return $this->_data['name'];
}
/**
* Get order item type.
* @return string
*/
public function get_type() {
return $this->_data['type'];
}
/*
|--------------------------------------------------------------------------
| Setters
|--------------------------------------------------------------------------
*/
/**
* Set ID
* @param int $value
*/
public function set_id( $value ) {
$this->set_order_item_id( $value );
}
/**
* Set order ID.
* @param int $value
*/
public function set_order_id( $value ) {
$this->_data['order_id'] = absint( $value );
}
/**
* Set order item ID.
* @param int $value
*/
protected function set_order_item_id( $value ) {
$this->_data['order_item_id'] = absint( $value );
}
/**
* Set order item name.
* @param string $value
*/
public function set_name( $value ) {
$this->_data['name'] = wc_clean( $value );
}
/**
* Set order item type.
* @param string $value
*/
protected function set_type( $value ) {
$this->_data['type'] = wc_clean( $value );
}
/*
|--------------------------------------------------------------------------
| CRUD methods
|--------------------------------------------------------------------------
|
| Methods which create, read, update and delete data from the database.
|
*/
/**
* Insert data into the database.
* @since 2.7.0
*/
public function create() {
global $wpdb;
$wpdb->insert( $wpdb->prefix . 'woocommerce_order_items', array(
'order_item_name' => $this->get_name(),
'order_item_type' => $this->get_type(),
'order_id' => $this->get_order_id()
) );
$this->set_id( $wpdb->insert_id );
do_action( 'woocommerce_new_order_item', $this->get_id(), $this, $this->get_order_id() );
}
/**
* Update data in the database.
* @since 2.7.0
*/
public function update() {
global $wpdb;
$wpdb->update( $wpdb->prefix . 'woocommerce_order_items', array(
'order_item_name' => $this->get_name(),
'order_item_type' => $this->get_type(),
'order_id' => $this->get_order_id()
), array( 'order_item_id' => $this->get_id() ) );
do_action( 'woocommerce_update_order_item', $this->get_id(), $this, $this->get_order_id() );
}
/**
* Read from the database.
* @since 2.7.0
* @param int|object $item ID of object to read, or already queried object.
*/
public function read( $item ) {
global $wpdb;
if ( is_numeric( $item ) && ! empty( $item ) ) {
$data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d LIMIT 1;", $item ) );
} elseif ( ! empty( $item->order_item_id ) ) {
$data = $item;
} else {
$data = false;
}
if ( $data ) {
$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();
}
}
/**
* Save data to the database.
* @since 2.7.0
* @return int Item ID
*/
public function save() {
if ( ! $this->get_id() ) {
$this->create();
} else {
$this->update();
}
$this->save_meta_data();
return $this->get_id();
}
/**
* Delete data from the database.
* @since 2.7.0
*/
public function delete() {
if ( $this->get_id() ) {
global $wpdb;
do_action( 'woocommerce_before_delete_order_item', $this->get_id() );
$wpdb->delete( $wpdb->prefix . 'woocommerce_order_items', array( 'order_item_id' => $this->get_id() ) );
$wpdb->delete( $wpdb->prefix . 'woocommerce_order_itemmeta', array( 'order_item_id' => $this->get_id() ) );
do_action( 'woocommerce_delete_order_item', $this->get_id() );
}
}
/*
|--------------------------------------------------------------------------
| Meta Data Handling
|--------------------------------------------------------------------------
*/
/**
* Expands things like term slugs before return.
* @param string $hideprefix (default: _)
* @return array
*/
public function get_formatted_meta_data( $hideprefix = '_' ) {
$formatted_meta = array();
$meta_data = $this->get_meta_data();
foreach ( $meta_data as $meta ) {
if ( "" === $meta->value || is_serialized( $meta->value ) || ( ! empty( $hideprefix ) && substr( $meta->key, 0, 1 ) === $hideprefix ) ) {
continue;
}
$attribute_key = urldecode( str_replace( 'attribute_', '', $meta->key ) );
$display_key = wc_attribute_label( $attribute_key, is_callable( array( $this, 'get_product' ) ) ? $this->get_product() : false );
$display_value = $meta->value;
if ( taxonomy_exists( $attribute_key ) ) {
$term = get_term_by( 'slug', $meta->value, $attribute_key );
if ( ! is_wp_error( $term ) && is_object( $term ) && $term->name ) {
$display_value = $term->name;
}
}
$formatted_meta[ $meta->meta_id ] = (object) array(
'key' => $meta->key,
'value' => $meta->key,
'display_key' => apply_filters( 'woocommerce_order_item_display_meta_key', $display_key ),
'display_value' => apply_filters( 'woocommerce_order_item_display_meta_value', $display_value ),
);
}
return $formatted_meta;
}
/*
|--------------------------------------------------------------------------
| Array Access Methods
|--------------------------------------------------------------------------
|
| For backwards compat with legacy arrays.
|
*/
/**
* offsetSet for ArrayAccess
* @param string $offset
* @param mixed $value
*/
public function offsetSet( $offset, $value ) {
if ( 'item_meta_array' === $offset ) {
foreach ( $value as $meta_id => $meta ) {
$this->update_meta_data( $meta->key, $meta->value, $meta_id );
}
return;
}
if ( array_key_exists( $offset, $this->_data ) ) {
$this->_data[ $offset ] = $value;
}
$this->update_meta_data( '_' . $offset, $value );
}
/**
* offsetUnset for ArrayAccess
* @param string $offset
*/
public function offsetUnset( $offset ) {
if ( 'item_meta_array' === $offset || 'item_meta' === $offset ) {
$this->_meta_data = array();
return;
}
if ( array_key_exists( $offset, $this->_data ) ) {
unset( $this->_data[ $offset ] );
}
$this->delete_meta_data( '_' . $offset );
}
/**
* offsetExists for ArrayAccess
* @param string $offset
* @return bool
*/
public function offsetExists( $offset ) {
if ( 'item_meta_array' === $offset || 'item_meta' === $offset || array_key_exists( $offset, $this->_data ) ) {
return true;
}
return array_key_exists( '_' . $offset, wp_list_pluck( $this->_meta_data, 'value', 'key' ) );
}
/**
* offsetGet for ArrayAccess
* @param string $offset
* @return mixed
*/
public function offsetGet( $offset ) {
if ( 'item_meta_array' === $offset ) {
$return = array();
foreach ( $this->_meta_data as $meta ) {
$return[ $meta->meta_id ] = $meta;
}
return $return;
}
$meta_values = wp_list_pluck( $this->_meta_data, 'value', 'key' );
if ( 'item_meta' === $offset ) {
return $meta_values;
} elseif ( array_key_exists( $offset, $this->_data ) ) {
return $this->_data[ $offset ];
} elseif ( array_key_exists( '_' . $offset, $meta_values ) ) {
// Item meta was expanded in previous versions, with prefixes removed. This maintains support.
return $meta_values[ '_' . $offset ];
}
return null;
}
}

View File

@ -1,113 +1,191 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
exit;
}
/**
* Order refund
* Order refund. Refunds are based on orders (essentially negative orders) and
* contain much of the same data.
*
* @class WC_Order_Refund
* @version 2.2.0
* @version 2.7.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
*/
class WC_Order_Refund extends WC_Abstract_Order {
/** @public string Order type */
public $order_type = 'refund';
/** @var string Date */
public $date;
/** @var string Refund reason */
public $reason;
/**
* Extend the abstract _data properties and then read the order object.
*
* @param int|object|WC_Order $order Order to init.
*/
public function __construct( $order = 0 ) {
$this->_data = array_merge( $this->_data, array(
'refund_amount' => '',
'refund_reason' => '',
'refunded_by' => 0,
) );
parent::__construct( $order );
}
/**
* Init/load the refund object. Called from the constructor.
*
* @param string|int|object|WC_Order_Refund $refund Refund to init
* @uses WP_POST
* Insert data into the database.
* @since 2.7.0
*/
protected function init( $refund ) {
if ( is_numeric( $refund ) ) {
$this->id = absint( $refund );
$this->post = get_post( $refund );
$this->get_refund( $this->id );
} elseif ( $refund instanceof WC_Order_Refund ) {
$this->id = absint( $refund->id );
$this->post = $refund->post;
$this->get_refund( $this->id );
} elseif ( isset( $refund->ID ) ) {
$this->id = absint( $refund->ID );
$this->post = $refund;
$this->get_refund( $this->id );
public function create() {
parent::create();
// Store additonal order data
if ( $this->get_id() ) {
$this->update_post_meta( '_refund_amount', $this->get_refund_amount() );
$this->update_post_meta( '_refunded_by', $this->get_refunded_by() );
$this->update_post_meta( '_refund_reason', $this->get_refund_reason() );
}
}
/**
* Gets an refund from the database.
*
* @since 2.2
* @param int $id
* @return bool
* Read from the database.
* @since 2.7.0
* @param int $id ID of object to read.
*/
public function get_refund( $id = 0 ) {
if ( ! $id ) {
return false;
public function read( $id ) {
parent::read( $id );
// Read additonal order data
if ( $this->get_id() ) {
$post_object = get_post( $id );
$this->set_refund_amount( get_post_meta( $this->get_id(), '_refund_amount', true ) );
// post_author was used before refunded_by meta.
$this->set_refunded_by( metadata_exists( 'post', $this->get_id(), '_refunded_by' ) ? get_post_meta( $this->get_id(), '_refunded_by', true ) : absint( $post_object->post_author ) );
// post_excerpt was used before refund_reason meta.
$this->set_refund_reason( metadata_exists( 'post', $this->get_id(), '_refund_reason' ) ? get_post_meta( $this->get_id(), '_refund_reason', true ) : absint( $post_object->post_excerpt ) );
}
if ( $result = get_post( $id ) ) {
$this->populate( $result );
return true;
}
return false;
}
/**
* Populates an refund from the loaded post data.
*
* @param mixed $result
* Update data in the database.
* @since 2.7.0
*/
public function populate( $result ) {
// Standard post data
$this->id = $result->ID;
$this->date = $result->post_date;
$this->modified_date = $result->post_modified;
$this->reason = $result->post_excerpt;
public function update() {
parent::update();
// Store additonal order data
$this->update_post_meta( '_refund_amount', $this->get_refund_amount() );
$this->update_post_meta( '_refunded_by', $this->get_refunded_by() );
$this->update_post_meta( '_refund_reason', $this->get_refund_reason() );
}
/**
* Get internal type (post type.)
* @return string
*/
public function get_type() {
return 'shop_order_refund';
}
/**
* Get a title for the new post type.
*/
protected function get_post_title() {
return sprintf( __( 'Refund &ndash; %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ) ) );
}
/**
* Set refunded amount.
* @param string $value
*/
public function set_refund_amount( $value ) {
$this->_data['refund_amount'] = wc_format_decimal( $value );
}
/**
* Get refunded amount.
*
* @since 2.2
* @return int|float
*/
public function get_refund_amount() {
return apply_filters( 'woocommerce_refund_amount', (double) $this->refund_amount, $this );
return apply_filters( 'woocommerce_refund_amount', (double) $this->_data['refund_amount'], $this );
}
/**
* Get formatted refunded amount.
*
* @since 2.4
* @return string
*/
public function get_formatted_refund_amount() {
return apply_filters( 'woocommerce_formatted_refund_amount', wc_price( $this->refund_amount, array('currency' => $this->get_order_currency()) ), $this );
return apply_filters( 'woocommerce_formatted_refund_amount', wc_price( $this->get_refund_amount(), array( 'currency' => $this->get_currency() ) ), $this );
}
/**
* Set refund reason.
* @param string $value
*/
public function set_refund_reason( $value ) {
$this->_data['refund_reason'] = $value;
}
/**
* Get refunded amount.
*
* Get refund reason.
* @since 2.2
* @return int|float
*/
public function get_refund_reason() {
return apply_filters( 'woocommerce_refund_reason', $this->reason, $this );
return apply_filters( 'woocommerce_refund_reason', $this->_data['refund_reason'], $this );
}
/**
* Set refunded by.
* @param int $value
*/
public function set_refunded_by( $value ) {
$this->_data['refunded_by'] = absint( $value );
}
/**
* Get ID of user who did the refund.
* @since 2.7
* @return int
*/
public function get_refunded_by() {
return absint( $this->_data['refunded_by'] );
}
/**
* Magic __get method for backwards compatibility.
* @param string $key
* @return mixed
*/
public function __get( $key ) {
_doing_it_wrong( $key, 'Refund properties should not be accessed directly.', '2.7' );
/**
* Maps legacy vars to new getters.
*/
if ( 'reason' === $key ) {
return $this->get_refund_reason();
} elseif ( 'refund_amount' === $key ) {
return $this->get_refund_amount();
}
return parent::__get( $key );
}
/**
* Gets an refund from the database.
* @deprecated 2.7
* @param int $id (default: 0).
* @return bool
*/
public function get_refund( $id = 0 ) {
_deprecated_function( 'get_refund', '2.7', 'read' );
if ( ! $id ) {
return false;
}
if ( $result = get_post( $id ) ) {
$this->populate( $result );
return true;
}
return false;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -860,7 +860,7 @@ function wc_create_refund( $args = array() ) {
$order = wc_get_order( $args['order_id'] );
// Refund currency is the same used for the parent order
update_post_meta( $refund_id, '_order_currency', $order->get_order_currency() );
update_post_meta( $refund_id, '_order_currency', $order->get_currency() );
// Negative line items
if ( sizeof( $args['line_items'] ) > 0 ) {
@ -917,7 +917,7 @@ function wc_create_refund( $args = array() ) {
$refund->calculate_totals( false );
// Set total to total refunded which may vary from order items
$refund->set_total( wc_format_decimal( $args['amount'] ) * -1, 'total' );
$refund->set_total( wc_format_decimal( $args['amount'] ) * -1 );
do_action( 'woocommerce_refund_created', $refund_id, $args );
}
@ -1065,3 +1065,134 @@ function wc_order_search( $term ) {
return $post_ids;
}
/**
* Update total sales amount for each product within a paid order.
*
* @since 2.7.0
* @param int $order_id
*/
function wc_update_total_sales_counts( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order || 'yes' === get_post_meta( $order_id, '_recorded_sales', true ) ) {
return;
}
if ( sizeof( $order->get_items() ) > 0 ) {
foreach ( $order->get_items() as $item ) {
if ( $item['product_id'] > 0 ) {
update_post_meta( $item['product_id'], 'total_sales', absint( get_post_meta( $item['product_id'], 'total_sales', true ) ) + absint( $item['qty'] ) );
}
}
}
update_post_meta( $order_id, '_recorded_sales', 'yes' );
/**
* Called when sales for an order are recorded
*
* @param int $order_id order id
*/
do_action( 'woocommerce_recorded_sales', $order_id );
}
add_action( 'woocommerce_order_status_completed', 'wc_update_total_sales_counts' );
add_action( 'woocommerce_order_status_processing', 'wc_update_total_sales_counts' );
add_action( 'woocommerce_order_status_on-hold', 'wc_update_total_sales_counts' );
/**
* Update used coupon amount for each coupon within an order.
*
* @since 2.7.0
* @param int $order_id
*/
function wc_update_coupon_usage_counts( $order_id ) {
$order = wc_get_order( $order_id );
$has_recorded = get_post_meta( $order_id, '_recorded_coupon_usage_counts', true );
if ( ! $order ) {
return;
}
if ( $order->has_status( 'cancelled' ) && 'yes' === $has_recorded ) {
$action = 'reduce';
delete_post_meta( $order_id, '_recorded_coupon_usage_counts' );
} elseif ( ! $order->has_status( 'cancelled' ) && 'yes' !== $has_recorded ) {
$action = 'increase';
update_post_meta( $order_id, '_recorded_coupon_usage_counts', 'yes' );
} else {
return;
}
if ( sizeof( $order->get_used_coupons() ) > 0 ) {
foreach ( $order->get_used_coupons() as $code ) {
if ( ! $code ) {
continue;
}
$coupon = new WC_Coupon( $code );
if ( ! $used_by = $order->get_user_id() ) {
$used_by = $order->get_billing_email();
}
switch ( $action ) {
case 'reduce' :
$coupon->dcr_usage_count( $used_by );
break;
case 'increase' :
$coupon->inc_usage_count( $used_by );
break;
}
}
}
}
add_action( 'woocommerce_order_status_completed', 'wc_update_total_sales_counts' );
add_action( 'woocommerce_order_status_processing', 'wc_update_total_sales_counts' );
add_action( 'woocommerce_order_status_on-hold', 'wc_update_total_sales_counts' );
add_action( 'woocommerce_order_status_cancelled', 'wc_update_total_sales_counts' );
/**
* When a payment is complete, we can reduce stock levels for items within an order.
* @since 2.7.0
* @param int $order_id
*/
function wc_maybe_reduce_stock_levels( $order_id ) {
if ( apply_filters( 'woocommerce_payment_complete_reduce_order_stock', ! get_post_meta( $order_id, '_order_stock_reduced', true ), $order_id ) ) {
wc_reduce_stock_levels( $order_id );
add_post_meta( $order_id, '_order_stock_reduced', '1', true );
}
}
add_action( 'woocommerce_payment_complete', 'wc_maybe_reduce_stock_levels' );
/**
* Reduce stock levels for items within an order.
* @since 2.7.0
* @param int $order_id
*/
function wc_reduce_stock_levels( $order_id ) {
$order = wc_get_order( $order_id );
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) && $order && apply_filters( 'woocommerce_can_reduce_order_stock', true, $order ) && sizeof( $order->get_items() ) > 0 ) {
foreach ( $order->get_items() as $item ) {
if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) && $product->managing_stock() ) {
$qty = apply_filters( 'woocommerce_order_item_quantity', $item['qty'], $order, $item );
$new_stock = $product->reduce_stock( $qty );
$item_name = $product->get_sku() ? $product->get_sku(): $item['product_id'];
if ( ! empty( $item['variation_id'] ) ) {
$order->add_order_note( sprintf( __( 'Item %s variation #%s stock reduced from %s to %s.', 'woocommerce' ), $item_name, $item['variation_id'], $new_stock + $qty, $new_stock ) );
} else {
$order->add_order_note( sprintf( __( 'Item %s stock reduced from %s to %s.', 'woocommerce' ), $item_name, $new_stock + $qty, $new_stock ) );
}
if ( $new_stock < 0 ) {
do_action( 'woocommerce_product_on_backorder', array( 'product' => $product, 'order_id' => $order_id, 'quantity' => $qty_ordered ) );
}
}
}
do_action( 'woocommerce_reduce_order_stock', $order );
}
}

View File

@ -2304,3 +2304,126 @@ if ( ! function_exists( 'woocommerce_account_edit_account' ) ) {
WC_Shortcode_My_Account::edit_account();
}
}
if ( ! function_exists( 'wc_get_email_order_items' ) ) {
/**
* Get HTML for the order items to be shown in emails.
* @param WC_Order $order
* @param array $args
* @since 2.7.0
*/
function wc_get_email_order_items( $order, $args = array() ) {
ob_start();
$defaults = array(
'show_sku' => false,
'show_image' => false,
'image_size' => array( 32, 32 ),
'plain_text' => false
);
$args = wp_parse_args( $args, $defaults );
$template = $args['plain_text'] ? 'emails/plain/email-order-items.php' : 'emails/email-order-items.php';
wc_get_template( $template, array(
'order' => $order,
'items' => $order->get_items(),
'show_download_links' => $order->is_download_permitted(),
'show_sku' => $args['show_sku'],
'show_purchase_note' => $order->is_paid(),
'show_image' => $args['show_image'],
'image_size' => $args['image_size'],
) );
return apply_filters( 'woocommerce_email_order_items_table', ob_get_clean(), $order );
}
}
if ( ! function_exists( 'wc_display_item_meta' ) ) {
/**
* Display item meta data.
* @since 2.7.0
* @param WC_Item $item
* @param array $args
* @return string|void
*/
function wc_display_item_meta( $item, $args = array() ) {
$strings = array();
$html = '';
$args = wp_parse_args( $args, array(
'before' => '<ul class="wc-item-meta"><li>',
'after' => '</li></ul>',
'separator' => '</li><li>',
'echo' => true,
'autop' => false,
) );
foreach ( $item->get_formatted_meta_data() as $meta_id => $meta ) {
if ( '_' === substr( $meta->key, 0, 1 ) ) {
continue;
}
$value = $args['autop'] ? wp_kses_post( wpautop( make_clickable( $meta->display_value ) ) ) : wp_kses_post( make_clickable( $meta->display_value ) );
$strings[] = '<strong class="wc-item-meta-label">' . wp_kses_post( $meta->display_key ) . ':</strong> ' . $value;
}
if ( $strings ) {
$html = $args['before'] . implode( $args['separator'], $strings ) . $args['after'];
}
$html = apply_filters( 'woocommerce_display_item_meta', $html, $item, $args );
if ( $args['echo'] ) {
echo $html;
} else {
return $html;
}
}
}
if ( ! function_exists( 'wc_display_item_downloads' ) ) {
/**
* Display item download links.
* @since 2.7.0
* @param WC_Item $item
* @param array $args
* @return string|void
*/
function wc_display_item_downloads( $item, $args = array() ) {
$strings = array();
$html = '';
$args = wp_parse_args( $args, array(
'before' => '<ul class ="wc-item-downloads"><li>',
'after' => '</li></ul>',
'separator' => '</li><li>',
'echo' => true,
'show_url' => false,
) );
if ( is_object( $item ) && $item->is_type( 'line_item' ) && ( $downloads = $item->get_item_downloads() ) ) {
$i = 0;
foreach ( $downloads as $file ) {
$i ++;
if ( $args['show_url'] ) {
$strings[] = '<strong class="wc-item-download-label">' . esc_html( $file['name'] ) . ':</strong> ' . esc_html( $file['download_url'] );
} else {
$prefix = sizeof( $downloads ) > 1 ? sprintf( __( 'Download %d', 'woocommerce' ), $i ) : __( 'Download', 'woocommerce' );
$strings[] = '<strong class="wc-item-download-label">' . $prefix . ':</strong> <a href="' . esc_url( $file['download_url'] ) . '" target="_blank">' . esc_html( $file['name'] ) . '</a>';
}
}
}
if ( $strings ) {
$html = $args['before'] . implode( $args['separator'], $strings ) . $args['after'];
}
$html = apply_filters( 'woocommerce_display_item_downloads', $html, $item, $args );
if ( $args['echo'] ) {
echo $html;
} else {
return $html;
}
}
}

View File

@ -176,17 +176,18 @@ function wc_update_new_customer_past_orders( $customer_id ) {
* @param int $order_id
*/
function wc_paying_customer( $order_id ) {
$order = wc_get_order( $order_id );
$order = wc_get_order( $order_id );
$customer_id = $order->get_customer_id();
if ( $order->user_id > 0 && 'refund' !== $order->order_type ) {
update_user_meta( $order->user_id, 'paying_customer', 1 );
if ( $customer_id > 0 && 'refund' !== $order->get_type() ) {
update_user_meta( $customer_id, 'paying_customer', 1 );
$old_spent = absint( get_user_meta( $order->user_id, '_money_spent', true ) );
update_user_meta( $order->user_id, '_money_spent', $old_spent + $order->order_total );
$old_spent = absint( get_user_meta( $customer_id, '_money_spent', true ) );
update_user_meta( $customer_id, '_money_spent', $old_spent + $order->order_total );
}
if ( $order->user_id > 0 && 'simple' === $order->order_type ) {
$old_count = absint( get_user_meta( $order->user_id, '_order_count', true ) );
update_user_meta( $order->user_id, '_order_count', $old_count + 1 );
if ( $customer_id > 0 && 'shop_order' === $order->get_type() ) {
$old_count = absint( get_user_meta( $customer_id, '_order_count', true ) );
update_user_meta( $customer_id, '_order_count', $old_count + 1 );
}
}
add_action( 'woocommerce_order_status_completed', 'wc_paying_customer' );

View File

@ -51,7 +51,7 @@ class WC_Helper_Order {
$order = wc_create_order( $order_data );
// Add order products
$item_id = $order->add_product( $product, 4 );
$item_id = $order->add_product( $product, array( 'qty' => 4 ) );
// Set billing address
$billing_address = array(
@ -78,13 +78,13 @@ class WC_Helper_Order {
$order->set_payment_method( $payment_gateways['bacs'] );
// Set totals
$order->set_total( 10, 'shipping' );
$order->set_total( 0, 'cart_discount' );
$order->set_total( 0, 'cart_discount_tax' );
$order->set_total( 0, 'tax' );
$order->set_total( 0, 'shipping_tax' );
$order->set_total( 40, 'total' ); // 4 x $10 simple helper product
$order->set_shipping_total( 10 );
$order->set_discount_total( 0 );
$order->set_discount_tax( 0 );
$order->set_cart_tax( 0 );
$order->set_shipping_tax( 0 );
$order->set_total( 40 ); // 4 x $10 simple helper product
return wc_get_order( $order->id );
return wc_get_order( $order->get_id() );
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,43 @@
<?php
/**
* Meta
* @package WooCommerce\Tests\CRUD
*/
class WC_Tests_CRUD_Refunds extends WC_Unit_Test_Case {
/**
* Test: get_type
*/
function test_get_type() {
$object = new WC_Order_Refund();
$this->assertEquals( 'shop_order_refund', $object->get_type() );
}
/**
* Test: get_refund_amount
*/
function test_get_refund_amount() {
$object = new WC_Order_Refund();
$object->set_refund_amount( 20 );
$this->assertEquals( '20.00', $object->get_refund_amount() );
}
/**
* Test: get_refund_reason
*/
function test_get_refund_reason() {
$object = new WC_Order_Refund();
$object->set_refund_reason( 'Customer is an idiot' );
$this->assertEquals( 'Customer is an idiot', $object->get_refund_reason() );
}
/**
* Test: get_refunded_by
*/
function test_get_refunded_by() {
$object = new WC_Order_Refund();
$object->set_refunded_by( 1 );
$this->assertEquals( 1, $object->get_refunded_by() );
}
}

View File

@ -109,7 +109,7 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$this->assertInstanceOf( 'WC_Order', wc_get_order( $order ) );
// Assert that wc_get_order() accepts a order post id.
$this->assertInstanceOf( 'WC_Order', wc_get_order( $order->id ) );
$this->assertInstanceOf( 'WC_Order', wc_get_order( $order->get_id() ) );
// Assert that a non-shop_order post returns false
$post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) );
@ -132,7 +132,7 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$this->assertEmpty( $order->get_payment_tokens() );
$token = WC_Helper_Payment_Token::create_cc_token();
update_post_meta( $order->id, '_payment_tokens', array( $token->get_id() ) );
update_post_meta( $order->get_id(), '_payment_tokens', array( $token->get_id() ) );
$this->assertCount( 1, $order->get_payment_tokens() );
}

View File

@ -18,12 +18,12 @@ class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case {
*/
function test_wc_payment_tokens_get_order_tokens() {
$order = WC_Helper_Order::create_order();
$this->assertEmpty( WC_Payment_Tokens::get_order_tokens( $order->id ) );
$this->assertEmpty( WC_Payment_Tokens::get_order_tokens( $order->get_id() ) );
$token = WC_Helper_Payment_Token::create_cc_token();
update_post_meta( $order->id, '_payment_tokens', array( $token->get_id() ) );
update_post_meta( $order->get_id(), '_payment_tokens', array( $token->get_id() ) );
$this->assertCount( 1, WC_Payment_Tokens::get_order_tokens( $order->id ) );
$this->assertCount( 1, WC_Payment_Tokens::get_order_tokens( $order->get_id() ) );
}