commit
b0f859f6a2
|
@ -81,8 +81,6 @@ class WC_Autoloader {
|
|||
$path = $this->include_path . 'admin/meta-boxes/';
|
||||
} elseif ( strpos( $class, 'wc_admin' ) === 0 ) {
|
||||
$path = $this->include_path . 'admin/';
|
||||
} elseif ( strpos( $class, 'wc_cli_' ) === 0 ) {
|
||||
$path = $this->include_path . 'cli/';
|
||||
} elseif ( strpos( $class, 'wc_payment_token_' ) === 0 ) {
|
||||
$path = $this->include_path . 'payment-tokens/';
|
||||
}
|
||||
|
|
|
@ -1,23 +1,6 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Manage WooCommerce from CLI.
|
||||
* Deprecated. No longer needed.
|
||||
*
|
||||
* @class WC_CLI
|
||||
* @version 2.5.0
|
||||
* @package WooCommerce/CLI
|
||||
* @category CLI
|
||||
* @author WooThemes
|
||||
* @package WooCommerce
|
||||
*/
|
||||
class WC_CLI extends WP_CLI_Command {
|
||||
}
|
||||
|
||||
WP_CLI::add_command( 'wc', 'WC_CLI' );
|
||||
WP_CLI::add_command( 'wc coupon', 'WC_CLI_Coupon' );
|
||||
WP_CLI::add_command( 'wc customer', 'WC_CLI_Customer' );
|
||||
WP_CLI::add_command( 'wc order', 'WC_CLI_Order' );
|
||||
WP_CLI::add_command( 'wc product', 'WC_CLI_Product' );
|
||||
WP_CLI::add_command( 'wc product category', 'WC_CLI_Product_Category' );
|
||||
WP_CLI::add_command( 'wc report', 'WC_CLI_Report' );
|
||||
WP_CLI::add_command( 'wc tax', 'WC_CLI_Tax' );
|
||||
WP_CLI::add_command( 'wc tool', 'WC_CLI_Tool' );
|
||||
|
|
|
@ -1,407 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* WooCommerce CLI Command.
|
||||
*
|
||||
* Base class that must be extended by any WooCommerce sub commands.
|
||||
*
|
||||
* @class WC_CLI_Command
|
||||
* @version 2.5.0
|
||||
* @package WooCommerce/CLI
|
||||
* @category CLI
|
||||
* @author WooThemes
|
||||
*/
|
||||
class WC_CLI_Command extends WP_CLI_Command {
|
||||
|
||||
/**
|
||||
* Add common cli arguments to argument list before WP_Query is run.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param array $base_args Required arguments for the query (e.g. `post_type`, etc)
|
||||
* @param array $assoc_args Arguments provided in when invoking the command
|
||||
* @return array
|
||||
*/
|
||||
protected function merge_wp_query_args( $base_args, $assoc_args ) {
|
||||
$args = array();
|
||||
|
||||
// date
|
||||
if ( ! empty( $assoc_args['created_at_min'] ) || ! empty( $assoc_args['created_at_max'] ) || ! empty( $assoc_args['updated_at_min'] ) || ! empty( $assoc_args['updated_at_max'] ) ) {
|
||||
|
||||
$args['date_query'] = array();
|
||||
|
||||
// resources created after specified date
|
||||
if ( ! empty( $assoc_args['created_at_min'] ) ) {
|
||||
$args['date_query'][] = array( 'column' => 'post_date_gmt', 'after' => $this->parse_datetime( $assoc_args['created_at_min'] ), 'inclusive' => true );
|
||||
}
|
||||
|
||||
// resources created before specified date
|
||||
if ( ! empty( $assoc_args['created_at_max'] ) ) {
|
||||
$args['date_query'][] = array( 'column' => 'post_date_gmt', 'before' => $this->parse_datetime( $assoc_args['created_at_max'] ), 'inclusive' => true );
|
||||
}
|
||||
|
||||
// resources updated after specified date
|
||||
if ( ! empty( $assoc_args['updated_at_min'] ) ) {
|
||||
$args['date_query'][] = array( 'column' => 'post_modified_gmt', 'after' => $this->parse_datetime( $assoc_args['updated_at_min'] ), 'inclusive' => true );
|
||||
}
|
||||
|
||||
// resources updated before specified date
|
||||
if ( ! empty( $assoc_args['updated_at_max'] ) ) {
|
||||
$args['date_query'][] = array( 'column' => 'post_modified_gmt', 'before' => $this->parse_datetime( $assoc_args['updated_at_max'] ), 'inclusive' => true );
|
||||
}
|
||||
}
|
||||
|
||||
// Search.
|
||||
if ( ! empty( $assoc_args['q'] ) ) {
|
||||
$args['s'] = $assoc_args['q'];
|
||||
}
|
||||
|
||||
// Number of post to show per page.
|
||||
if ( ! empty( $assoc_args['limit'] ) ) {
|
||||
$args['posts_per_page'] = $assoc_args['limit'];
|
||||
}
|
||||
|
||||
// Number of post to displace or pass over.
|
||||
if ( ! empty( $assoc_args['offset'] ) ) {
|
||||
$args['offset'] = $assoc_args['offset'];
|
||||
}
|
||||
|
||||
// order (ASC or DESC, DESC by default).
|
||||
if ( ! empty( $assoc_args['order'] ) ) {
|
||||
$args['order'] = $assoc_args['order'];
|
||||
}
|
||||
|
||||
// orderby.
|
||||
if ( ! empty( $assoc_args['orderby'] ) ) {
|
||||
$args['orderby'] = $assoc_args['orderby'];
|
||||
|
||||
// allow sorting by meta value
|
||||
if ( ! empty( $assoc_args['orderby_meta_key'] ) ) {
|
||||
$args['meta_key'] = $assoc_args['orderby_meta_key'];
|
||||
}
|
||||
}
|
||||
|
||||
// allow post status change
|
||||
if ( ! empty( $assoc_args['post_status'] ) ) {
|
||||
$args['post_status'] = $assoc_args['post_status'];
|
||||
unset( $assoc_args['post_status'] );
|
||||
}
|
||||
|
||||
// filter by a list of post ids
|
||||
if ( ! empty( $assoc_args['in'] ) ) {
|
||||
$args['post__in'] = explode( ',', $assoc_args['in'] );
|
||||
unset( $assoc_args['in'] );
|
||||
}
|
||||
|
||||
// exclude by a list of post ids
|
||||
if ( ! empty( $assoc_args['not_in'] ) ) {
|
||||
$args['post__not_in'] = explode( ',', $assoc_args['not_in'] );
|
||||
unset( $assoc_args['not_in'] );
|
||||
}
|
||||
|
||||
// posts page.
|
||||
$args['paged'] = ( isset( $assoc_args['page'] ) ) ? absint( $assoc_args['page'] ) : 1;
|
||||
|
||||
$args = apply_filters( 'woocommerce_cli_query_args', $args, $assoc_args );
|
||||
|
||||
return array_merge( $base_args, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add common cli arguments to argument list before WP_User_Query is run.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param array $base_args required arguments for the query (e.g. `post_type`, etc)
|
||||
* @param array $assoc_args arguments provided in when invoking the command
|
||||
* @return array
|
||||
*/
|
||||
protected function merge_wp_user_query_args( $base_args, $assoc_args ) {
|
||||
$args = array();
|
||||
|
||||
// Custom Role
|
||||
if ( ! empty( $assoc_args['role'] ) ) {
|
||||
$args['role'] = $assoc_args['role'];
|
||||
}
|
||||
|
||||
// Search
|
||||
if ( ! empty( $assoc_args['q'] ) ) {
|
||||
$args['search'] = $assoc_args['q'];
|
||||
}
|
||||
|
||||
// Limit number of users returned.
|
||||
if ( ! empty( $assoc_args['limit'] ) ) {
|
||||
$args['number'] = absint( $assoc_args['limit'] );
|
||||
}
|
||||
|
||||
// Offset
|
||||
if ( ! empty( $assoc_args['offset'] ) ) {
|
||||
$args['offset'] = absint( $assoc_args['offset'] );
|
||||
}
|
||||
|
||||
// date
|
||||
if ( ! empty( $assoc_args['created_at_min'] ) || ! empty( $assoc_args['created_at_max'] ) ) {
|
||||
|
||||
$args['date_query'] = array();
|
||||
|
||||
// resources created after specified date
|
||||
if ( ! empty( $assoc_args['created_at_min'] ) ) {
|
||||
$args['date_query'][] = array( 'after' => $this->parse_datetime( $assoc_args['created_at_min'] ), 'inclusive' => true );
|
||||
}
|
||||
|
||||
// resources created before specified date
|
||||
if ( ! empty( $assoc_args['created_at_max'] ) ) {
|
||||
$args['date_query'][] = array( 'before' => $this->parse_datetime( $assoc_args['created_at_max'] ), 'inclusive' => true );
|
||||
}
|
||||
}
|
||||
|
||||
// Order (ASC or DESC, ASC by default).
|
||||
if ( ! empty( $assoc_args['order'] ) ) {
|
||||
$args['order'] = $assoc_args['order'];
|
||||
}
|
||||
|
||||
// Orderby.
|
||||
if ( ! empty( $assoc_args['orderby'] ) ) {
|
||||
$args['orderby'] = $assoc_args['orderby'];
|
||||
}
|
||||
|
||||
$args = apply_filters( 'woocommerce_cli_user_query_args', $args, $assoc_args );
|
||||
|
||||
return array_merge( $base_args, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an RFC3339 datetime into a MySQl datetime.
|
||||
*
|
||||
* Invalid dates default to unix epoch.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param string $datetime RFC3339 datetime
|
||||
* @return string MySQl datetime (YYYY-MM-DD HH:MM:SS)
|
||||
*/
|
||||
protected function parse_datetime( $datetime ) {
|
||||
// Strip millisecond precision (a full stop followed by one or more digits)
|
||||
if ( strpos( $datetime, '.' ) !== false ) {
|
||||
$datetime = preg_replace( '/\.\d+/', '', $datetime );
|
||||
}
|
||||
|
||||
// default timezone to UTC
|
||||
$datetime = preg_replace( '/[+-]\d+:+\d+$/', '+00:00', $datetime );
|
||||
|
||||
try {
|
||||
|
||||
$datetime = new DateTime( $datetime, new DateTimeZone( 'UTC' ) );
|
||||
|
||||
} catch ( Exception $e ) {
|
||||
|
||||
$datetime = new DateTime( '@0' );
|
||||
|
||||
}
|
||||
|
||||
return $datetime->format( 'Y-m-d H:i:s' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a unix timestamp or MySQL datetime into an RFC3339 datetime.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param int|string $timestamp unix timestamp or MySQL datetime
|
||||
* @param bool $convert_to_utc
|
||||
* @return string RFC3339 datetime
|
||||
*/
|
||||
protected function format_datetime( $timestamp, $convert_to_utc = false ) {
|
||||
if ( $convert_to_utc ) {
|
||||
$timezone = new DateTimeZone( wc_timezone_string() );
|
||||
} else {
|
||||
$timezone = new DateTimeZone( 'UTC' );
|
||||
}
|
||||
|
||||
try {
|
||||
if ( is_numeric( $timestamp ) ) {
|
||||
$date = new DateTime( "@{$timestamp}" );
|
||||
} else {
|
||||
$date = new DateTime( $timestamp, $timezone );
|
||||
}
|
||||
|
||||
// convert to UTC by adjusting the time based on the offset of the site's timezone
|
||||
if ( $convert_to_utc ) {
|
||||
$date->modify( -1 * $date->getOffset() . ' seconds' );
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
$date = new DateTime( '@0' );
|
||||
}
|
||||
|
||||
return $date->format( 'Y-m-d\TH:i:s\Z' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get formatter object based on supplied arguments.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param array $assoc_args Associative args from CLI to determine formatting
|
||||
* @return \WP_CLI\Formatter
|
||||
*/
|
||||
protected function get_formatter( $assoc_args ) {
|
||||
$args = $this->get_format_args( $assoc_args );
|
||||
return new \WP_CLI\Formatter( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default fields for formatter.
|
||||
*
|
||||
* Class that extends WC_CLI_Command should override this method.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @return null|string|array
|
||||
*/
|
||||
protected function get_default_format_fields() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get format args that will be passed into CLI Formatter.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param array $assoc_args Associative args from CLI
|
||||
* @return array Formatter args
|
||||
*/
|
||||
protected function get_format_args( $assoc_args ) {
|
||||
$format_args = array(
|
||||
'fields' => $this->get_default_format_fields(),
|
||||
'field' => null,
|
||||
'format' => 'table',
|
||||
);
|
||||
|
||||
if ( isset( $assoc_args['fields'] ) ) {
|
||||
$format_args['fields'] = $assoc_args['fields'];
|
||||
}
|
||||
|
||||
if ( isset( $assoc_args['field'] ) ) {
|
||||
$format_args['field'] = $assoc_args['field'];
|
||||
}
|
||||
|
||||
if ( ! empty( $assoc_args['format'] ) && in_array( $assoc_args['format'], array( 'count', 'ids', 'table', 'csv', 'json' ) ) ) {
|
||||
$format_args['format'] = $assoc_args['format'];
|
||||
}
|
||||
|
||||
return $format_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten multidimensional array in which nested array will be prefixed with
|
||||
* parent keys separated with dot char, e.g. given an array:
|
||||
*
|
||||
* array(
|
||||
* 'a' => array(
|
||||
* 'b' => array(
|
||||
* 'c' => ...
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* a flatten array would contain key 'a.b.c' => ...
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param array $arr Array that may contains nested array
|
||||
* @param string $prefix Prefix
|
||||
*
|
||||
* @return array Flattened array
|
||||
*/
|
||||
protected function flatten_array( $arr, $prefix = '' ) {
|
||||
$flattened = array();
|
||||
foreach ( $arr as $key => $value ) {
|
||||
if ( is_array( $value ) ) {
|
||||
if ( sizeof( $value ) > 0 ) {
|
||||
|
||||
// Full access to whole elements if indices are numerical.
|
||||
$flattened[ $prefix . $key ] = $value;
|
||||
|
||||
// This is naive assumption that if element with index zero
|
||||
// exists then array indices are numberical.
|
||||
if ( ! empty( $value[0] ) ) {
|
||||
|
||||
// Allow size of array to be accessed, i.e., a.b.arr.size
|
||||
$flattened[ $prefix . $key . '.size' ] = sizeof( $value );
|
||||
}
|
||||
|
||||
$flattened = array_merge( $flattened, $this->flatten_array( $value, $prefix . $key . '.' ) );
|
||||
} else {
|
||||
$flattened[ $prefix . $key ] = '';
|
||||
|
||||
// Tells user that size of this array is zero.
|
||||
$flattened[ $prefix . $key . '.size' ] = 0;
|
||||
}
|
||||
} else {
|
||||
$flattened[ $prefix . $key ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $flattened;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unflatten array will make key 'a.b.c' becomes nested array:
|
||||
*
|
||||
* array(
|
||||
* 'a' => array(
|
||||
* 'b' => array(
|
||||
* 'c' => ...
|
||||
* )
|
||||
* )
|
||||
* )
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param array $arr Flattened array
|
||||
* @return array
|
||||
*/
|
||||
protected function unflatten_array( $arr ) {
|
||||
$unflatten = array();
|
||||
|
||||
foreach ( $arr as $key => $value ) {
|
||||
$key_list = explode( '.', $key );
|
||||
$first_key = array_shift( $key_list );
|
||||
$first_key = $this->get_normalized_array_key( $first_key );
|
||||
if ( sizeof( $key_list ) > 0 ) {
|
||||
$remaining_keys = implode( '.', $key_list );
|
||||
$subarray = $this->unflatten_array( array( $remaining_keys => $value ) );
|
||||
|
||||
foreach ( $subarray as $sub_key => $sub_value ) {
|
||||
$sub_key = $this->get_normalized_array_key( $sub_key );
|
||||
if ( ! empty( $unflatten[ $first_key ][ $sub_key ] ) ) {
|
||||
$unflatten[ $first_key ][ $sub_key ] = array_merge_recursive( $unflatten[ $first_key ][ $sub_key ], $sub_value );
|
||||
} else {
|
||||
$unflatten[ $first_key ][ $sub_key ] = $sub_value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$unflatten[ $first_key ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $unflatten;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get normalized array key. If key is a numeric one it will be converted
|
||||
* as absolute integer.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param string $key Array key
|
||||
* @return string|int
|
||||
*/
|
||||
protected function get_normalized_array_key( $key ) {
|
||||
if ( is_numeric( $key ) ) {
|
||||
$key = absint( $key );
|
||||
}
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the value is equal to 'yes', 'true' or '1'
|
||||
*
|
||||
* @since 2.5.4
|
||||
* @param string $value
|
||||
* @return boolean
|
||||
*/
|
||||
protected function is_true( $value ) {
|
||||
return ( 'yes' === $value || 'true' === $value || '1' === $value ) ? true : false;
|
||||
}
|
||||
}
|
|
@ -1,672 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Manage Coupons.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @package WooCommerce/CLI
|
||||
* @category CLI
|
||||
* @author WooThemes
|
||||
*/
|
||||
class WC_CLI_Coupon extends WC_CLI_Command {
|
||||
|
||||
/**
|
||||
* Create a coupon.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : Associative args for the new coupon.
|
||||
*
|
||||
* [--porcelain]
|
||||
* : Outputs just the new coupon id.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields are available for create command:
|
||||
*
|
||||
* * code
|
||||
* * type
|
||||
* * amount
|
||||
* * description
|
||||
* * expiry_date
|
||||
* * individual_use
|
||||
* * product_ids
|
||||
* * exclude_product_ids
|
||||
* * usage_limit
|
||||
* * usage_limit_per_user
|
||||
* * limit_usage_to_x_items
|
||||
* * usage_count
|
||||
* * enable_free_shipping
|
||||
* * product_category_ids
|
||||
* * exclude_product_category_ids
|
||||
* * minimum_amount
|
||||
* * maximum_amount
|
||||
* * customer_emails
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc coupon create --code=new-coupon --type=percent
|
||||
*
|
||||
*/
|
||||
public function create( $__, $assoc_args ) {
|
||||
global $wpdb;
|
||||
|
||||
try {
|
||||
$porcelain = isset( $assoc_args['porcelain'] );
|
||||
unset( $assoc_args['porcelain'] );
|
||||
|
||||
$assoc_args = apply_filters( 'woocommerce_cli_create_coupon_data', $assoc_args );
|
||||
|
||||
// Check if coupon code is specified.
|
||||
if ( ! isset( $assoc_args['code'] ) ) {
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_missing_coupon_code', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'code' ) );
|
||||
}
|
||||
|
||||
$coupon_code = apply_filters( 'woocommerce_coupon_code', $assoc_args['code'] );
|
||||
|
||||
// Check for duplicate coupon codes.
|
||||
$coupon_found = $wpdb->get_var( $wpdb->prepare( "
|
||||
SELECT $wpdb->posts.ID
|
||||
FROM $wpdb->posts
|
||||
WHERE $wpdb->posts.post_type = 'shop_coupon'
|
||||
AND $wpdb->posts.post_status = 'publish'
|
||||
AND $wpdb->posts.post_title = '%s'
|
||||
", $coupon_code ) );
|
||||
|
||||
if ( $coupon_found ) {
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
$defaults = array(
|
||||
'type' => 'fixed_cart',
|
||||
'amount' => 0,
|
||||
'individual_use' => false,
|
||||
'product_ids' => array(),
|
||||
'exclude_product_ids' => array(),
|
||||
'usage_limit' => '',
|
||||
'usage_limit_per_user' => '',
|
||||
'limit_usage_to_x_items' => '',
|
||||
'usage_count' => '',
|
||||
'expiry_date' => '',
|
||||
'enable_free_shipping' => false,
|
||||
'product_category_ids' => array(),
|
||||
'exclude_product_category_ids' => array(),
|
||||
'exclude_sale_items' => false,
|
||||
'minimum_amount' => '',
|
||||
'maximum_amount' => '',
|
||||
'customer_emails' => array(),
|
||||
'description' => '',
|
||||
);
|
||||
|
||||
$coupon_data = wp_parse_args( $assoc_args, $defaults );
|
||||
|
||||
// Validate coupon types
|
||||
if ( ! in_array( wc_clean( $coupon_data['type'] ), array_keys( wc_get_coupon_types() ) ) ) {
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_invalid_coupon_type', sprintf( __( 'Invalid coupon type - the coupon type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_coupon_types() ) ) ) );
|
||||
}
|
||||
|
||||
$new_coupon = array(
|
||||
'post_title' => $coupon_code,
|
||||
'post_content' => '',
|
||||
'post_status' => 'publish',
|
||||
'post_author' => get_current_user_id(),
|
||||
'post_type' => 'shop_coupon',
|
||||
'post_excerpt' => $coupon_data['description'],
|
||||
);
|
||||
|
||||
$id = wp_insert_post( $new_coupon, $wp_error = false );
|
||||
|
||||
if ( is_wp_error( $id ) ) {
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_cannot_create_coupon', $id->get_error_message() );
|
||||
}
|
||||
|
||||
// Set coupon meta
|
||||
update_post_meta( $id, 'discount_type', $coupon_data['type'] );
|
||||
update_post_meta( $id, 'coupon_amount', wc_format_decimal( $coupon_data['amount'] ) );
|
||||
update_post_meta( $id, 'individual_use', ( $this->is_true( $coupon_data['individual_use'] ) ) ? 'yes' : 'no' );
|
||||
update_post_meta( $id, 'product_ids', implode( ',', array_filter( array_map( 'intval', $coupon_data['product_ids'] ) ) ) );
|
||||
update_post_meta( $id, 'exclude_product_ids', implode( ',', array_filter( array_map( 'intval', $coupon_data['exclude_product_ids'] ) ) ) );
|
||||
update_post_meta( $id, 'usage_limit', absint( $coupon_data['usage_limit'] ) );
|
||||
update_post_meta( $id, 'usage_limit_per_user', absint( $coupon_data['usage_limit_per_user'] ) );
|
||||
update_post_meta( $id, 'limit_usage_to_x_items', absint( $coupon_data['limit_usage_to_x_items'] ) );
|
||||
update_post_meta( $id, 'usage_count', absint( $coupon_data['usage_count'] ) );
|
||||
update_post_meta( $id, 'expiry_date', $this->get_coupon_expiry_date( wc_clean( $coupon_data['expiry_date'] ) ) );
|
||||
update_post_meta( $id, 'free_shipping', ( $this->is_true( $coupon_data['enable_free_shipping'] ) ) ? 'yes' : 'no' );
|
||||
update_post_meta( $id, 'product_categories', array_filter( array_map( 'intval', $coupon_data['product_category_ids'] ) ) );
|
||||
update_post_meta( $id, 'exclude_product_categories', array_filter( array_map( 'intval', $coupon_data['exclude_product_category_ids'] ) ) );
|
||||
update_post_meta( $id, 'exclude_sale_items', ( $this->is_true( $coupon_data['exclude_sale_items'] ) ) ? 'yes' : 'no' );
|
||||
update_post_meta( $id, 'minimum_amount', wc_format_decimal( $coupon_data['minimum_amount'] ) );
|
||||
update_post_meta( $id, 'maximum_amount', wc_format_decimal( $coupon_data['maximum_amount'] ) );
|
||||
update_post_meta( $id, 'customer_email', array_filter( array_map( 'sanitize_email', $coupon_data['customer_emails'] ) ) );
|
||||
|
||||
do_action( 'woocommerce_cli_create_coupon', $id, $coupon_data );
|
||||
|
||||
if ( $porcelain ) {
|
||||
WP_CLI::line( $id );
|
||||
} else {
|
||||
WP_CLI::success( "Created coupon $id." );
|
||||
}
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete one or more coupons.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <id>...
|
||||
* : The coupon ID to delete.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc coupon delete 123
|
||||
*
|
||||
* wp wc coupon delete $(wp wc coupon list --format=ids)
|
||||
*
|
||||
*/
|
||||
public function delete( $args, $assoc_args ) {
|
||||
$exit_code = 0;
|
||||
foreach ( $this->get_many_coupons_from_ids_or_codes( $args, true ) as $coupon ) {
|
||||
do_action( 'woocommerce_cli_delete_coupon', $coupon->get_id() );
|
||||
$r = wp_delete_post( $coupon->get_id(), true );
|
||||
|
||||
if ( $r ) {
|
||||
WP_CLI::success( "Deleted coupon " . $coupon->get_id() );
|
||||
} else {
|
||||
$exit_code += 1;
|
||||
WP_CLI::warning( "Failed deleting coupon " . $coupon->get_id() );
|
||||
}
|
||||
}
|
||||
exit( $exit_code ? 1 : 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a coupon.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <coupon>
|
||||
* : Coupon ID or code
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Instead of returning the whole coupon fields, returns the value of a single fields.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Get a specific subset of the coupon's fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Accepted values: table, json, csv. Default: table.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields are available for get command:
|
||||
*
|
||||
* * id
|
||||
* * code
|
||||
* * type
|
||||
* * amount
|
||||
* * description
|
||||
* * expiry_date
|
||||
* * individual_use
|
||||
* * product_ids
|
||||
* * exclude_product_ids
|
||||
* * usage_limit
|
||||
* * usage_limit_per_user
|
||||
* * limit_usage_to_x_items
|
||||
* * usage_count
|
||||
* * enable_free_shipping
|
||||
* * product_category_ids
|
||||
* * exclude_product_category_ids
|
||||
* * minimum_amount
|
||||
* * maximum_amount
|
||||
* * customer_emails
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc coupon get 123 --field=discount_type
|
||||
*
|
||||
* wp wc coupon get disc50 --format=json > disc50.json
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function get( $args, $assoc_args ) {
|
||||
global $wpdb;
|
||||
|
||||
try {
|
||||
$coupon = $this->get_coupon_from_id_or_code( $args[0] );
|
||||
if ( ! $coupon ) {
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_invalid_coupon', sprintf( __( 'Invalid coupon ID or code: %s', 'woocommerce' ), $args[0] ) );
|
||||
}
|
||||
|
||||
$coupon_post = get_post( $coupon->get_id() );
|
||||
$coupon_usage_limit = $coupon->get_usage_limit();
|
||||
$coupon_usage_limit_per_user = $coupon->get_usage_limit_per_user();
|
||||
$coupon_date_expires = $coupon->get_date_expires();
|
||||
$coupon_data = array(
|
||||
'id' => $coupon->get_id(),
|
||||
'code' => $coupon->get_code(),
|
||||
'type' => $coupon->get_discount_type(),
|
||||
'created_at' => $this->format_datetime( $coupon_post->post_date_gmt ),
|
||||
'updated_at' => $this->format_datetime( $coupon_post->post_modified_gmt ),
|
||||
'amount' => wc_format_decimal( $coupon->get_amount(), 2 ),
|
||||
'individual_use' => $coupon->get_individual_use(),
|
||||
'product_ids' => implode( ', ', $coupon->get_product_ids() ),
|
||||
'exclude_product_ids' => implode( ', ', $coupon->get_excluded_product_ids() ),
|
||||
'usage_limit' => ( ! empty( $coupon_usage_limit ) ) ? $coupon_usage_limit : null,
|
||||
'usage_limit_per_user' => ( ! empty( $coupon_usage_limit_per_user ) ) ? $coupon_usage_limit_per_user : null,
|
||||
'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(),
|
||||
'usage_count' => (int) $coupon->get_usage_count(),
|
||||
'expiry_date' => ( ! empty( $coupon_date_expires ) ) ? $this->format_datetime( $coupon_date_expires ) : null,
|
||||
'enable_free_shipping' => $coupon->get_free_shipping(),
|
||||
'product_category_ids' => implode( ', ', $coupon->get_product_categories() ),
|
||||
'exclude_product_category_ids' => implode( ', ', $coupon->get_excluded_product_categories() ),
|
||||
'exclude_sale_items' => $coupon->get_exclude_sale_items(),
|
||||
'minimum_amount' => wc_format_decimal( $coupon->get_minimum_amount(), 2 ),
|
||||
'maximum_amount' => wc_format_decimal( $coupon->get_maximum_amount(), 2 ),
|
||||
'customer_emails' => implode( ', ', $coupon->get_email_restrictions() ),
|
||||
'description' => $coupon_post->post_excerpt,
|
||||
);
|
||||
|
||||
$coupon_data = apply_filters( 'woocommerce_cli_get_coupon', $coupon_data );
|
||||
|
||||
if ( empty( $assoc_args['fields'] ) ) {
|
||||
$assoc_args['fields'] = array_keys( $coupon_data );
|
||||
}
|
||||
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
$formatter->display_item( $coupon_data );
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List coupons.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : Filter coupon based on coupon property.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Prints the value of a single field for each coupon.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Limit the output to specific coupon fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Acceptec values: table, csv, json, count, ids. Default: table.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields will be displayed by default for each coupon:
|
||||
*
|
||||
* * id
|
||||
* * code
|
||||
* * type
|
||||
* * amount
|
||||
* * description
|
||||
* * expiry_date
|
||||
*
|
||||
* These fields are optionally available:
|
||||
*
|
||||
* * individual_use
|
||||
* * product_ids
|
||||
* * exclude_product_ids
|
||||
* * usage_limit
|
||||
* * usage_limit_per_user
|
||||
* * limit_usage_to_x_items
|
||||
* * usage_count
|
||||
* * free_shipping
|
||||
* * product_category_ids
|
||||
* * exclude_product_category_ids
|
||||
* * exclude_sale_items
|
||||
* * minimum_amount
|
||||
* * maximum_amount
|
||||
* * customer_emails
|
||||
*
|
||||
* Fields for filtering query result also available:
|
||||
*
|
||||
* * q Filter coupons with search query.
|
||||
* * in Specify coupon IDs to retrieve.
|
||||
* * not_in Specify coupon IDs NOT to retrieve.
|
||||
* * created_at_min Filter coupons created after this date.
|
||||
* * created_at_max Filter coupons created before this date.
|
||||
* * updated_at_min Filter coupons updated after this date.
|
||||
* * updated_at_max Filter coupons updated before this date.
|
||||
* * page Page number.
|
||||
* * offset Number of coupon to displace or pass over.
|
||||
* * order Accepted values: ASC and DESC. Default: DESC.
|
||||
* * orderby Sort retrieved coupons by parameter. One or more options can be passed.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc coupon list
|
||||
*
|
||||
* wp wc coupon list --field=id
|
||||
*
|
||||
* wp wc coupon list --fields=id,code,type --format=json
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @subcommand list
|
||||
*/
|
||||
public function list_( $__, $assoc_args ) {
|
||||
$query_args = $this->merge_wp_query_args( $this->get_list_query_args(), $assoc_args );
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
|
||||
if ( 'ids' === $formatter->format ) {
|
||||
$query_args['fields'] = 'ids';
|
||||
$query = new WP_Query( $query_args );
|
||||
echo implode( ' ', $query->posts );
|
||||
} else {
|
||||
$query = new WP_Query( $query_args );
|
||||
$items = $this->format_posts_to_items( $query->posts );
|
||||
$formatter->display_items( $items );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get coupon types.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc coupon types
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function types( $__, $___ ) {
|
||||
$coupon_types = wc_get_coupon_types();
|
||||
foreach ( $coupon_types as $type => $label ) {
|
||||
WP_CLI::line( sprintf( '%s: %s', $label, $type ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update one or more coupons.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <coupon>
|
||||
* : The ID or code of the coupon to update.
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : One or more fields to update.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields are available for update command:
|
||||
*
|
||||
* * code
|
||||
* * type
|
||||
* * amount
|
||||
* * description
|
||||
* * expiry_date
|
||||
* * individual_use
|
||||
* * product_ids
|
||||
* * exclude_product_ids
|
||||
* * usage_limit
|
||||
* * usage_limit_per_user
|
||||
* * limit_usage_to_x_items
|
||||
* * usage_count
|
||||
* * enable_free_shipping
|
||||
* * product_category_ids
|
||||
* * exclude_product_categories
|
||||
* * exclude_product_category_ids
|
||||
* * minimum_amount
|
||||
* * maximum_amount
|
||||
* * customer_emails
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc coupon update 123 --amount=5
|
||||
*
|
||||
* wp wc coupon update coupon-code --code=new-coupon-code
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function update( $args, $assoc_args ) {
|
||||
try {
|
||||
$coupon = $this->get_coupon_from_id_or_code( $args[0] );
|
||||
if ( ! $coupon ) {
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_invalid_coupon', sprintf( __( 'Invalid coupon ID or code: %s', 'woocommerce' ), $args[0] ) );
|
||||
}
|
||||
|
||||
$id = $coupon->get_id();
|
||||
$coupon_code = $coupon->get_code();
|
||||
$data = apply_filters( 'woocommerce_cli_update_coupon_data', $assoc_args, $id );
|
||||
if ( isset( $data['code'] ) ) {
|
||||
global $wpdb;
|
||||
|
||||
$coupon_code = apply_filters( 'woocommerce_coupon_code', $data['code'] );
|
||||
|
||||
// Check for duplicate coupon codes
|
||||
$coupon_found = $wpdb->get_var( $wpdb->prepare( "
|
||||
SELECT $wpdb->posts.ID
|
||||
FROM $wpdb->posts
|
||||
WHERE $wpdb->posts.post_type = 'shop_coupon'
|
||||
AND $wpdb->posts.post_status = 'publish'
|
||||
AND $wpdb->posts.post_title = '%s'
|
||||
AND $wpdb->posts.ID != %s
|
||||
", $coupon_code, $id ) );
|
||||
|
||||
if ( $coupon_found ) {
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ) );
|
||||
}
|
||||
}
|
||||
|
||||
$id = wp_update_post( array( 'ID' => intval( $id ), 'post_title' => $coupon_code, 'post_excerpt' => isset( $data['description'] ) ? $data['description'] : '' ) );
|
||||
if ( 0 === $id ) {
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_cannot_update_coupon', __( 'Failed to update coupon', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['type'] ) ) {
|
||||
// Validate coupon types.
|
||||
if ( ! in_array( wc_clean( $data['type'] ), array_keys( wc_get_coupon_types() ) ) ) {
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_invalid_coupon_type', sprintf( __( 'Invalid coupon type - the coupon type must be any of these: %s', 'woocommerce' ), implode( ', ', array_keys( wc_get_coupon_types() ) ) ) );
|
||||
}
|
||||
update_post_meta( $id, 'discount_type', $data['type'] );
|
||||
}
|
||||
|
||||
if ( isset( $data['amount'] ) ) {
|
||||
update_post_meta( $id, 'coupon_amount', wc_format_decimal( $data['amount'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['individual_use'] ) ) {
|
||||
update_post_meta( $id, 'individual_use', ( $this->is_true( $data['individual_use'] ) ) ? 'yes' : 'no' );
|
||||
}
|
||||
|
||||
if ( isset( $data['product_ids'] ) ) {
|
||||
update_post_meta( $id, 'product_ids', implode( ',', array_filter( array_map( 'intval', $data['product_ids'] ) ) ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['exclude_product_ids'] ) ) {
|
||||
update_post_meta( $id, 'exclude_product_ids', implode( ',', array_filter( array_map( 'intval', $data['exclude_product_ids'] ) ) ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['usage_limit'] ) ) {
|
||||
update_post_meta( $id, 'usage_limit', absint( $data['usage_limit'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['usage_limit_per_user'] ) ) {
|
||||
update_post_meta( $id, 'usage_limit_per_user', absint( $data['usage_limit_per_user'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['limit_usage_to_x_items'] ) ) {
|
||||
update_post_meta( $id, 'limit_usage_to_x_items', absint( $data['limit_usage_to_x_items'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['usage_count'] ) ) {
|
||||
update_post_meta( $id, 'usage_count', absint( $data['usage_count'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['expiry_date'] ) ) {
|
||||
update_post_meta( $id, 'expiry_date', $this->get_coupon_expiry_date( wc_clean( $data['expiry_date'] ) ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['enable_free_shipping'] ) ) {
|
||||
update_post_meta( $id, 'free_shipping', ( $this->is_true( $data['enable_free_shipping'] ) ) ? 'yes' : 'no' );
|
||||
}
|
||||
|
||||
if ( isset( $data['product_category_ids'] ) ) {
|
||||
update_post_meta( $id, 'product_categories', array_filter( array_map( 'intval', $data['product_category_ids'] ) ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['exclude_product_category_ids'] ) ) {
|
||||
update_post_meta( $id, 'exclude_product_categories', array_filter( array_map( 'intval', $data['exclude_product_category_ids'] ) ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['exclude_sale_items'] ) ) {
|
||||
update_post_meta( $id, 'exclude_sale_items', ( $this->is_true( $data['exclude_sale_items'] ) ) ? 'yes' : 'no' );
|
||||
}
|
||||
|
||||
if ( isset( $data['minimum_amount'] ) ) {
|
||||
update_post_meta( $id, 'minimum_amount', wc_format_decimal( $data['minimum_amount'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['maximum_amount'] ) ) {
|
||||
update_post_meta( $id, 'maximum_amount', wc_format_decimal( $data['maximum_amount'] ) );
|
||||
}
|
||||
|
||||
if ( isset( $data['customer_emails'] ) ) {
|
||||
update_post_meta( $id, 'customer_email', array_filter( array_map( 'sanitize_email', $data['customer_emails'] ) ) );
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_cli_update_coupon', $id, $data );
|
||||
|
||||
WP_CLI::success( "Updated coupon $id." );
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get query args for list subcommand.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @return array
|
||||
*/
|
||||
protected function get_list_query_args() {
|
||||
return array(
|
||||
'post_type' => 'shop_coupon',
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => -1,
|
||||
'order' => 'DESC',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default format fields that will be used in `list` and `get` subcommands.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @return string
|
||||
*/
|
||||
protected function get_default_format_fields() {
|
||||
return 'id,code,type,amount,description,expiry_date';
|
||||
}
|
||||
|
||||
/**
|
||||
* Format posts from WP_Query result to items in which each item contain
|
||||
* common properties of item, for instance `post_title` will be `code`.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param array $posts Array of post
|
||||
* @return array Items
|
||||
*/
|
||||
protected function format_posts_to_items( $posts ) {
|
||||
$items = array();
|
||||
foreach ( $posts as $post ) {
|
||||
$coupon = new WC_Coupon;
|
||||
$coupon->read( $post->ID );
|
||||
$coupon_usage_limit = $coupon->get_usage_limit();
|
||||
$coupon_usage_limit_per_user = $coupon->get_usage_limit_per_user();
|
||||
$coupon_date_expires = $coupon->get_date_expires();
|
||||
$items[] = array(
|
||||
'id' => $post->ID,
|
||||
'code' => $post->post_title,
|
||||
'type' => $coupon->get_discount_type(),
|
||||
'created_at' => $this->format_datetime( $post->post_date_gmt ),
|
||||
'updated_at' => $this->format_datetime( $post->post_modified_gmt ),
|
||||
'amount' => wc_format_decimal( $coupon->get_amount(), 2 ),
|
||||
'individual_use' => $coupon->get_individual_use(),
|
||||
'product_ids' => implode( ', ', is_array( $coupon->get_product_ids() ) ? $coupon->get_product_ids() : array() ),
|
||||
'exclude_product_ids' => implode( ', ', is_array( $coupon->get_excluded_product_ids() ) ? $coupon->get_excluded_product_ids() : array() ),
|
||||
'usage_limit' => ( ! empty( $coupon_usage_limit ) ) ? $coupon_usage_limit : null,
|
||||
'usage_limit_per_user' => ( ! empty( $coupon_usage_limit_per_user ) ) ? $coupon_usage_limit_per_user : null,
|
||||
'limit_usage_to_x_items' => (int) $coupon->get_limit_usage_to_x_items(),
|
||||
'usage_count' => (int) $coupon->get_usage_count(),
|
||||
'expiry_date' => ( ! empty( $coupon_date_expires ) ) ? $this->format_datetime( $coupon_date_expires ) : null,
|
||||
'free_shipping' => $coupon->get_free_shipping(),
|
||||
'product_category_ids' => implode( ', ', is_array( $coupon->get_product_categories() ) ? $coupon->get_product_categories() : array() ),
|
||||
'exclude_product_category_ids' => implode( ', ', is_array( $coupon->get_excluded_product_categories() ) ? $coupon->get_excluded_product_categories() : array() ),
|
||||
'exclude_sale_items' => $coupon->get_exclude_sale_items(),
|
||||
'minimum_amount' => wc_format_decimal( $coupon->get_minimum_amount(), 2 ),
|
||||
'maximum_amount' => wc_format_decimal( $coupon->get_maximum_amount(), 2 ),
|
||||
'customer_emails' => implode( ', ', is_array( $coupon->get_email_restrictions() ) ? $coupon->get_email_restrictions() : array() ),
|
||||
'description' => $post->post_excerpt,
|
||||
);
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get expiry_date format before saved into DB.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param string $expiry_date
|
||||
* @return string
|
||||
*/
|
||||
protected function get_coupon_expiry_date( $expiry_date ) {
|
||||
if ( '' !== $expiry_date ) {
|
||||
return date( 'Y-m-d', strtotime( $expiry_date ) );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get coupon from coupon's ID or code.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param int|string $coupon_id_or_code Coupon's ID or code
|
||||
* @param bool $display_warning Display warning if ID or code is invalid. Default false.
|
||||
* @return WC_Coupon
|
||||
*/
|
||||
protected function get_coupon_from_id_or_code( $coupon_id_or_code, $display_warning = false ) {
|
||||
global $wpdb;
|
||||
|
||||
$code = $wpdb->get_var( $wpdb->prepare( "SELECT post_title FROM $wpdb->posts WHERE (id = %s OR post_title = %s) AND post_type = 'shop_coupon' AND post_status = 'publish' LIMIT 1", $coupon_id_or_code, $coupon_id_or_code ) );
|
||||
if ( ! $code ) {
|
||||
if ( $display_warning ) {
|
||||
WP_CLI::warning( "Invalid coupon ID or code $coupon_id_or_code" );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return new WC_Coupon( $code );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get coupon from coupon's ID or code.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param array $args Coupon's IDs or codes
|
||||
* @param bool $display_warning Display warning if ID or code is invalid. Default false.
|
||||
* @return WC_Coupon
|
||||
*/
|
||||
protected function get_many_coupons_from_ids_or_codes( $args, $display_warning = false ) {
|
||||
$coupons = array();
|
||||
|
||||
foreach ( $args as $arg ) {
|
||||
$code = $this->get_coupon_from_id_or_code( $arg, $display_warning );
|
||||
if ( $code ) {
|
||||
$coupons[] = $code;
|
||||
}
|
||||
}
|
||||
|
||||
return $coupons;
|
||||
}
|
||||
}
|
|
@ -1,742 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Manage Customers.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @package WooCommerce/CLI
|
||||
* @category CLI
|
||||
* @author WooThemes
|
||||
*/
|
||||
class WC_CLI_Customer extends WC_CLI_Command {
|
||||
|
||||
/**
|
||||
* Create a customer.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <email>
|
||||
* : The email address of the customer to create.
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : Associative args for the new customer.
|
||||
*
|
||||
* [--porcelain]
|
||||
* : Outputs just the new customer id.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields are optionally available for create command:
|
||||
*
|
||||
* * username
|
||||
* * password
|
||||
* * first_name
|
||||
* * last_name
|
||||
*
|
||||
* Billing address fields:
|
||||
*
|
||||
* * billing_address.first_name
|
||||
* * billing_address.last_name
|
||||
* * billing_address.company
|
||||
* * billing_address.address_1
|
||||
* * billing_address.address_2
|
||||
* * billing_address.city
|
||||
* * billing_address.state
|
||||
* * billing_address.postcode
|
||||
* * billing_address.country
|
||||
* * billing_address.email
|
||||
* * billing_address.phone
|
||||
*
|
||||
* Shipping address fields:
|
||||
*
|
||||
* * shipping_address.first_name
|
||||
* * shipping_address.last_name
|
||||
* * shipping_address.company
|
||||
* * shipping_address.address_1
|
||||
* * shipping_address.address_2
|
||||
* * shipping_address.city
|
||||
* * shipping_address.state
|
||||
* * shipping_address.postcode
|
||||
* * shipping_address.country
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc customer create new-customer@example.com --first_name=Akeda
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function create( $args, $assoc_args ) {
|
||||
global $wpdb;
|
||||
|
||||
try {
|
||||
$porcelain = isset( $assoc_args['porcelain'] );
|
||||
unset( $assoc_args['porcelain'] );
|
||||
|
||||
$assoc_args['email'] = $args[0];
|
||||
$data = apply_filters( 'woocommerce_cli_create_customer_data', $this->unflatten_array( $assoc_args ) );
|
||||
|
||||
// Sets the username.
|
||||
$data['username'] = ! empty( $data['username'] ) ? $data['username'] : '';
|
||||
|
||||
// Sets the password.
|
||||
$data['password'] = ! empty( $data['password'] ) ? $data['password'] : '';
|
||||
|
||||
// Attempts to create the new customer.
|
||||
$id = wc_create_new_customer( $data['email'], $data['username'], $data['password'] );
|
||||
|
||||
// Checks for an error in the customer creation.
|
||||
if ( is_wp_error( $id ) ) {
|
||||
throw new WC_CLI_Exception( $id->get_error_code(), $id->get_error_message() );
|
||||
}
|
||||
|
||||
// Added customer data.
|
||||
$this->update_customer_data( $id, $data );
|
||||
|
||||
do_action( 'woocommerce_cli_create_customer', $id, $data );
|
||||
|
||||
if ( $porcelain ) {
|
||||
WP_CLI::line( $id );
|
||||
} else {
|
||||
WP_CLI::success( "Created customer $id." );
|
||||
}
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete one or more customers.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <customer>...
|
||||
* : The customer ID, email, or username to delete.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc customer delete 123
|
||||
*
|
||||
* wp wc customer delete $(wp wc customer list --format=ids)
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function delete( $args, $assoc_args ) {
|
||||
$exit_code = 0;
|
||||
foreach ( $args as $arg ) {
|
||||
try {
|
||||
$customer = $this->get_user( $arg );
|
||||
do_action( 'woocommerce_cli_delete_customer', $customer['id'] );
|
||||
$r = wp_delete_user( $customer['id'] );
|
||||
|
||||
if ( $r ) {
|
||||
WP_CLI::success( "Deleted customer {$customer['id']}." );
|
||||
} else {
|
||||
$exit_code += 1;
|
||||
WP_CLI::warning( "Failed deleting customer {$customer['id']}." );
|
||||
}
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::warning( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
exit( $exit_code ? 1 : 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* View customer downloads.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <customer>
|
||||
* : The customer ID, email or username.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Instead of returning the whole customer fields, returns the value of a single fields.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Get a specific subset of the customer's fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Accepted values: table, json, csv. Default: table.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* * download_id
|
||||
* * download_name
|
||||
* * access_expires
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc customer downloads 123
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function downloads( $args, $assoc_args ) {
|
||||
try {
|
||||
$user = $this->get_user( $args[0] );
|
||||
$downloads = array();
|
||||
foreach ( wc_get_customer_available_downloads( $user['id'] ) as $key => $download ) {
|
||||
$downloads[ $key ] = $download;
|
||||
$downloads[ $key ]['access_expires'] = $this->format_datetime( $download['access_expires'] );
|
||||
}
|
||||
$downloads = apply_filters( 'woocommerce_cli_customer_downloads', $downloads, $user, $assoc_args );
|
||||
|
||||
if ( empty( $assoc_args['fields'] ) ) {
|
||||
$assoc_args['fields'] = $this->get_customer_download_fields();
|
||||
}
|
||||
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
$formatter->display_items( $downloads );
|
||||
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a customer.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <customer>
|
||||
* : Customer ID, email, or username.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Instead of returning the whole customer fields, returns the value of a single fields.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Get a specific subset of the customer's fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Accepted values: table, json, csv. Default: table.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* * id
|
||||
* * email
|
||||
* * first_name
|
||||
* * last_name
|
||||
* * created_at
|
||||
* * username
|
||||
* * last_order_id
|
||||
* * last_order_date
|
||||
* * orders_count
|
||||
* * total_spent
|
||||
* * avatar_url
|
||||
*
|
||||
* Billing address fields:
|
||||
*
|
||||
* * billing_address.first_name
|
||||
* * billing_address.last_name
|
||||
* * billing_address.company
|
||||
* * billing_address.address_1
|
||||
* * billing_address.address_2
|
||||
* * billing_address.city
|
||||
* * billing_address.state
|
||||
* * billing_address.postcode
|
||||
* * billing_address.country
|
||||
* * billing_address.email
|
||||
* * billing_address.phone
|
||||
*
|
||||
* Shipping address fields:
|
||||
*
|
||||
* * shipping_address.first_name
|
||||
* * shipping_address.last_name
|
||||
* * shipping_address.company
|
||||
* * shipping_address.address_1
|
||||
* * shipping_address.address_2
|
||||
* * shipping_address.city
|
||||
* * shipping_address.state
|
||||
* * shipping_address.postcode
|
||||
* * shipping_address.country
|
||||
*
|
||||
* Fields for filtering query result also available:
|
||||
*
|
||||
* * role Filter customers associated with certain role.
|
||||
* * q Filter customers with search query.
|
||||
* * created_at_min Filter customers whose registered after this date.
|
||||
* * created_at_max Filter customers whose registered before this date.
|
||||
* * limit The maximum returned number of results.
|
||||
* * offset Offset the returned results.
|
||||
* * order Accepted values: ASC and DESC. Default: DESC.
|
||||
* * orderby Sort retrieved customers by parameter. One or more options can be passed.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc customer get 123 --field=email
|
||||
*
|
||||
* wp wc customer get customer-login --format=json
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function get( $args, $assoc_args ) {
|
||||
try {
|
||||
$user = $this->get_user( $args[0] );
|
||||
|
||||
if ( empty( $assoc_args['fields'] ) ) {
|
||||
$assoc_args['fields'] = array_keys( $user );
|
||||
}
|
||||
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
$formatter->display_item( $user );
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List customers.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : Filter customer based on customer property.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Prints the value of a single field for each customer.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Limit the output to specific customer fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Acceptec values: table, csv, json, count, ids. Default: table.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields will be displayed by default for each customer:
|
||||
*
|
||||
* * id
|
||||
* * email
|
||||
* * first_name
|
||||
* * last_name
|
||||
* * created_at
|
||||
*
|
||||
* These fields are optionally available:
|
||||
*
|
||||
* * username
|
||||
* * last_order_id
|
||||
* * last_order_date
|
||||
* * orders_count
|
||||
* * total_spent
|
||||
* * avatar_url
|
||||
*
|
||||
* Billing address fields:
|
||||
*
|
||||
* * billing_address.first_name
|
||||
* * billing_address.last_name
|
||||
* * billing_address.company
|
||||
* * billing_address.address_1
|
||||
* * billing_address.address_2
|
||||
* * billing_address.city
|
||||
* * billing_address.state
|
||||
* * billing_address.postcode
|
||||
* * billing_address.country
|
||||
* * billing_address.email
|
||||
* * billing_address.phone
|
||||
*
|
||||
* Shipping address fields:
|
||||
*
|
||||
* * shipping_address.first_name
|
||||
* * shipping_address.last_name
|
||||
* * shipping_address.company
|
||||
* * shipping_address.address_1
|
||||
* * shipping_address.address_2
|
||||
* * shipping_address.city
|
||||
* * shipping_address.state
|
||||
* * shipping_address.postcode
|
||||
* * shipping_address.country
|
||||
*
|
||||
* Fields for filtering query result also available:
|
||||
*
|
||||
* * role Filter customers associated with certain role.
|
||||
* * q Filter customers with search query.
|
||||
* * created_at_min Filter customers whose registered after this date.
|
||||
* * created_at_max Filter customers whose registered before this date.
|
||||
* * limit The maximum returned number of results.
|
||||
* * offset Offset the returned results.
|
||||
* * order Accepted values: ASC and DESC. Default: DESC.
|
||||
* * orderby Sort retrieved customers by parameter. One or more options can be passed.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc customer list
|
||||
*
|
||||
* wp wc customer list --field=id
|
||||
*
|
||||
* wp wc customer list --fields=id,email,first_name --format=json
|
||||
*
|
||||
* @subcommand list
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function list_( $__, $assoc_args ) {
|
||||
$query_args = $this->merge_wp_user_query_args( $this->get_list_query_args(), $assoc_args );
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
|
||||
if ( 'ids' === $formatter->format ) {
|
||||
$query_args['fields'] = 'ids';
|
||||
$query = new WP_User_Query( $query_args );
|
||||
echo implode( ' ', $query->results );
|
||||
} else {
|
||||
$query = new WP_User_Query( $query_args );
|
||||
$items = $this->format_users_to_items( $query->results );
|
||||
$formatter->display_items( $items );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* View customer orders.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <customer>
|
||||
* : The customer ID, email or username.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Instead of returning the whole customer fields, returns the value of a single fields.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Get a specific subset of the customer's fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Accepted values: table, json, csv. Default: table.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* For more fields, see: wp wc order list --help
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc customer orders 123
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function orders( $args, $assoc_args ) {
|
||||
try {
|
||||
WP_CLI::run_command( array( 'wc', 'order', 'list' ), array( 'customer_id' => $args[0] ) );
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update one or more customers.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <customer>
|
||||
* : Customer ID, email, or username.
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : One or more fields to update.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields are available for update command:
|
||||
*
|
||||
* * email
|
||||
* * password
|
||||
* * first_name
|
||||
* * last_name
|
||||
*
|
||||
* Billing address fields:
|
||||
*
|
||||
* * billing_address.first_name
|
||||
* * billing_address.last_name
|
||||
* * billing_address.company
|
||||
* * billing_address.address_1
|
||||
* * billing_address.address_2
|
||||
* * billing_address.city
|
||||
* * billing_address.state
|
||||
* * billing_address.postcode
|
||||
* * billing_address.country
|
||||
* * billing_address.email
|
||||
* * billing_address.phone
|
||||
*
|
||||
* Shipping address fields:
|
||||
*
|
||||
* * shipping_address.first_name
|
||||
* * shipping_address.last_name
|
||||
* * shipping_address.company
|
||||
* * shipping_address.address_1
|
||||
* * shipping_address.address_2
|
||||
* * shipping_address.city
|
||||
* * shipping_address.state
|
||||
* * shipping_address.postcode
|
||||
* * shipping_address.country
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc customer update customer-login --first_name=akeda --last_name=bagus
|
||||
*
|
||||
* wp wc customer update customer@example.com --password=new-password
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function update( $args, $assoc_args ) {
|
||||
try {
|
||||
$user = $this->get_user( $args[0] );
|
||||
$data = $this->unflatten_array( $assoc_args );
|
||||
$data = apply_filters( 'woocommerce_cli_update_customer_data', $data );
|
||||
|
||||
// Customer email.
|
||||
if ( isset( $data['email'] ) ) {
|
||||
wp_update_user( array( 'ID' => $user['id'], 'user_email' => sanitize_email( $data['email'] ) ) );
|
||||
}
|
||||
|
||||
// Customer password.
|
||||
if ( isset( $data['password'] ) ) {
|
||||
wp_update_user( array( 'ID' => $user['id'], 'user_pass' => wc_clean( $data['password'] ) ) );
|
||||
}
|
||||
|
||||
// Update customer data.
|
||||
$this->update_customer_data( $user['id'], $data );
|
||||
|
||||
do_action( 'woocommerce_cli_update_customer', $user['id'], $data );
|
||||
|
||||
WP_CLI::success( "Updated customer {$user['id']}." );
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get query args for list subcommand.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @return array
|
||||
*/
|
||||
protected function get_list_query_args() {
|
||||
return array(
|
||||
'role' => 'customer',
|
||||
'orderby' => 'registered',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default format fields that will be used in `list` and `get` subcommands.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @return string
|
||||
*/
|
||||
protected function get_default_format_fields() {
|
||||
return 'id,email,first_name,last_name,created_at';
|
||||
}
|
||||
|
||||
/**
|
||||
* Format users from WP_User_Query result to items in which each item contain
|
||||
* common properties of item.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param array $users Array of user
|
||||
* @return array Items
|
||||
*/
|
||||
protected function format_users_to_items( $users ) {
|
||||
$items = array();
|
||||
foreach ( $users as $user ) {
|
||||
try {
|
||||
$items[] = $this->get_user( $user->ID );
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::warning( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user from given user ID, email, or login
|
||||
*
|
||||
* @throws WC_CLI_Exception
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param mixed $id_email_or_login
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
protected function get_user( $id_email_or_login ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( is_numeric( $id_email_or_login ) ) {
|
||||
$user = get_user_by( 'id', $id_email_or_login );
|
||||
} elseif ( is_email( $id_email_or_login ) ) {
|
||||
$user = get_user_by( 'email', $id_email_or_login );
|
||||
} else {
|
||||
$user = get_user_by( 'login', $id_email_or_login );
|
||||
}
|
||||
|
||||
if ( ! $user ) {
|
||||
/* translators: %s: id email or login */
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_invalid_customer', sprintf( __( 'Invalid customer "%s"', 'woocommerce' ), $id_email_or_login ) );
|
||||
}
|
||||
|
||||
// Get info about user's last order
|
||||
$last_order = $wpdb->get_row( "SELECT id, post_date_gmt
|
||||
FROM $wpdb->posts AS posts
|
||||
LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id
|
||||
WHERE meta.meta_key = '_customer_user'
|
||||
AND meta.meta_value = {$user->ID}
|
||||
AND posts.post_type = 'shop_order'
|
||||
AND posts.post_status IN ( '" . implode( "','", array_keys( wc_get_order_statuses() ) ) . "' )
|
||||
ORDER BY posts.ID DESC
|
||||
" );
|
||||
|
||||
$customer = array(
|
||||
'id' => $user->ID,
|
||||
'created_at' => $this->format_datetime( $user->user_registered ),
|
||||
'email' => $user->user_email,
|
||||
'first_name' => $user->first_name,
|
||||
'last_name' => $user->last_name,
|
||||
'username' => $user->user_login,
|
||||
'role' => $user->roles[0],
|
||||
'last_order_id' => is_object( $last_order ) ? $last_order->get_id() : null,
|
||||
'last_order_date' => is_object( $last_order ) ? $this->format_datetime( $last_order->post_date_gmt ) : null,
|
||||
'orders_count' => wc_get_customer_order_count( $user->ID ),
|
||||
'total_spent' => wc_format_decimal( wc_get_customer_total_spent( $user->ID ), 2 ),
|
||||
'avatar_url' => $this->get_avatar_url( $user->customer_email ),
|
||||
'billing_address' => array(
|
||||
'first_name' => $user->billing_first_name,
|
||||
'last_name' => $user->billing_last_name,
|
||||
'company' => $user->billing_company,
|
||||
'address_1' => $user->billing_address_1,
|
||||
'address_2' => $user->billing_address_2,
|
||||
'city' => $user->billing_city,
|
||||
'state' => $user->billing_state,
|
||||
'postcode' => $user->billing_postcode,
|
||||
'country' => $user->billing_country,
|
||||
'email' => $user->billing_email,
|
||||
'phone' => $user->billing_phone,
|
||||
),
|
||||
'shipping_address' => array(
|
||||
'first_name' => $user->shipping_first_name,
|
||||
'last_name' => $user->shipping_last_name,
|
||||
'company' => $user->shipping_company,
|
||||
'address_1' => $user->shipping_address_1,
|
||||
'address_2' => $user->shipping_address_2,
|
||||
'city' => $user->shipping_city,
|
||||
'state' => $user->shipping_state,
|
||||
'postcode' => $user->shipping_postcode,
|
||||
'country' => $user->shipping_country,
|
||||
),
|
||||
);
|
||||
|
||||
// Allow dot notation for nested array so that user can specifies field
|
||||
// like 'billing_address.first_name'.
|
||||
return $this->flatten_array( $customer );
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for @see get_avatar() which doesn't simply return
|
||||
* the URL so we need to pluck it from the HTML img tag
|
||||
*
|
||||
* Kudos to https://github.com/WP-API/WP-API for offering a better solution
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param string $email the customer's email
|
||||
* @return string the URL to the customer's avatar
|
||||
*/
|
||||
protected function get_avatar_url( $email ) {
|
||||
$avatar_html = get_avatar( $email );
|
||||
|
||||
// Get the URL of the avatar from the provided HTML
|
||||
preg_match( '/src=["|\'](.+)[\&|"|\']/U', $avatar_html, $matches );
|
||||
|
||||
if ( isset( $matches[1] ) && ! empty( $matches[1] ) ) {
|
||||
return esc_url_raw( $matches[1] );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add/Update customer data.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param int $id The customer ID
|
||||
* @param array $data
|
||||
*/
|
||||
protected function update_customer_data( $id, $data ) {
|
||||
// Customer first name.
|
||||
if ( isset( $data['first_name'] ) ) {
|
||||
update_user_meta( $id, 'first_name', wc_clean( $data['first_name'] ) );
|
||||
}
|
||||
|
||||
// Customer last name.
|
||||
if ( isset( $data['last_name'] ) ) {
|
||||
update_user_meta( $id, 'last_name', wc_clean( $data['last_name'] ) );
|
||||
}
|
||||
|
||||
// Customer billing address.
|
||||
if ( isset( $data['billing_address'] ) ) {
|
||||
foreach ( $this->get_customer_billing_address_fields() as $address ) {
|
||||
if ( isset( $data['billing_address'][ $address ] ) ) {
|
||||
update_user_meta( $id, 'billing_' . $address, wc_clean( $data['billing_address'][ $address ] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Customer shipping address.
|
||||
if ( isset( $data['shipping_address'] ) ) {
|
||||
foreach ( $this->get_customer_shipping_address_fields() as $address ) {
|
||||
if ( isset( $data['shipping_address'][ $address ] ) ) {
|
||||
update_user_meta( $id, 'shipping_' . $address, wc_clean( $data['shipping_address'][ $address ] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_cli_update_customer_data', $id, $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get customer billing address fields.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @return array
|
||||
*/
|
||||
protected function get_customer_billing_address_fields() {
|
||||
return apply_filters( 'woocommerce_cli_customer_billing_address_fields', array(
|
||||
'first_name',
|
||||
'last_name',
|
||||
'company',
|
||||
'address_1',
|
||||
'address_2',
|
||||
'city',
|
||||
'state',
|
||||
'postcode',
|
||||
'country',
|
||||
'email',
|
||||
'phone',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get customer shipping address fields.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @return array
|
||||
*/
|
||||
protected function get_customer_shipping_address_fields() {
|
||||
return apply_filters( 'woocommerce_cli_customer_shipping_address_fields', array(
|
||||
'first_name',
|
||||
'last_name',
|
||||
'company',
|
||||
'address_1',
|
||||
'address_2',
|
||||
'city',
|
||||
'state',
|
||||
'postcode',
|
||||
'country',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get customer download fields.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @return array
|
||||
*/
|
||||
protected function get_customer_download_fields() {
|
||||
return apply_filters( 'woocommerce_cli_customer_download_fields', array(
|
||||
'download_id',
|
||||
'download_name',
|
||||
'access_expires',
|
||||
) );
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* WooCommerce CLI Exception Class.
|
||||
*
|
||||
* Extends Exception to provide additional data.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @package WooCommerce/CLI
|
||||
* @category CLI
|
||||
* @author WooThemes
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
class WC_CLI_Exception extends Exception {
|
||||
|
||||
/** @var string sanitized error code */
|
||||
protected $error_code;
|
||||
|
||||
/**
|
||||
* Setup exception, requires 3 params:
|
||||
*
|
||||
* error code - machine-readable, e.g. `woocommerce_invalid_product_id`
|
||||
* error message - friendly message, e.g. 'Product ID is invalid'
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param string $error_code
|
||||
* @param string $error_message user-friendly translated error message
|
||||
*/
|
||||
public function __construct( $error_code, $error_message ) {
|
||||
$this->error_code = $error_code;
|
||||
parent::__construct( $error_message );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error code
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @return string
|
||||
*/
|
||||
public function getErrorCode() {
|
||||
return $this->error_code;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,160 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Manage Product Categories.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @package WooCommerce/CLI
|
||||
* @category CLI
|
||||
* @author WooThemes
|
||||
*/
|
||||
class WC_CLI_Product_Category extends WC_CLI_Command {
|
||||
|
||||
/**
|
||||
* Get product category.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <id>
|
||||
* : Product category ID.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Instead of returning the whole product category fields, returns the value of a single fields.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Get a specific subset of the product category's fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Accepted values: table, json, csv. Default: table.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* * id
|
||||
* * name
|
||||
* * slug
|
||||
* * parent
|
||||
* * description
|
||||
* * display
|
||||
* * image
|
||||
* * count
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc product category get 123
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function get( $args, $assoc_args ) {
|
||||
try {
|
||||
$product_category = $this->get_product_category( $args[0] );
|
||||
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
$formatter->display_item( $product_category );
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List of product categories.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : Filter products based on product property.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Prints the value of a single field for each product.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Limit the output to specific product fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Acceptec values: table, csv, json, count, ids. Default: table.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* * id
|
||||
* * name
|
||||
* * slug
|
||||
* * parent
|
||||
* * description
|
||||
* * display
|
||||
* * image
|
||||
* * count
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc product category list
|
||||
*
|
||||
* wp wc product category list --fields=id,name --format=json
|
||||
*
|
||||
* @subcommand list
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function list_( $__, $assoc_args ) {
|
||||
try {
|
||||
$product_categories = array();
|
||||
$terms = get_terms( 'product_cat', array( 'hide_empty' => false, 'fields' => 'ids' ) );
|
||||
|
||||
foreach ( $terms as $term_id ) {
|
||||
$product_categories[] = $this->get_product_category( $term_id );
|
||||
}
|
||||
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
$formatter->display_items( $product_categories );
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product category properties from given term ID.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param int $term_id Category term ID
|
||||
* @return array
|
||||
* @throws WC_CLI_Exception
|
||||
*/
|
||||
protected function get_product_category( $term_id ) {
|
||||
$term_id = absint( $term_id );
|
||||
$term = get_term( $term_id, 'product_cat' );
|
||||
|
||||
if ( is_wp_error( $term ) || is_null( $term ) ) {
|
||||
/* translators: %s: product category ID */
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_invalid_product_category_id', sprintf( __( 'Invalid product category ID "%s"', 'woocommerce' ), $term_id ) );
|
||||
}
|
||||
|
||||
$term_id = intval( $term->term_id );
|
||||
|
||||
// Get category display type.
|
||||
$display_type = get_woocommerce_term_meta( $term_id, 'display_type' );
|
||||
|
||||
// Get category image.
|
||||
$image = '';
|
||||
if ( $image_id = get_woocommerce_term_meta( $term_id, 'thumbnail_id' ) ) {
|
||||
$image = wp_get_attachment_url( $image_id );
|
||||
}
|
||||
|
||||
return array(
|
||||
'id' => $term_id,
|
||||
'name' => $term->name,
|
||||
'slug' => $term->slug,
|
||||
'parent' => $term->parent,
|
||||
'description' => $term->description,
|
||||
'display' => $display_type ? $display_type : 'default',
|
||||
'image' => $image ? esc_url( $image ) : '',
|
||||
'count' => intval( $term->count ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default format fields that will be used in `list` and `get` subcommands.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @return string
|
||||
*/
|
||||
protected function get_default_format_fields() {
|
||||
return 'id,name,slug,parent,description,display,image,count';
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,371 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Show Reports.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @package WooCommerce/CLI
|
||||
* @category CLI
|
||||
* @author WooThemes
|
||||
*/
|
||||
class WC_CLI_Report extends WC_CLI_Command {
|
||||
|
||||
/**
|
||||
* List reports.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Acceptec values: table, csv, json, count, ids. Default: table.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc report list
|
||||
*
|
||||
* @subcommand list
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function list_( $__, $assoc_args ) {
|
||||
$reports = array( 'sales', 'sales/top_sellers' );
|
||||
$formatter = $this->get_formatter(
|
||||
array_merge(
|
||||
array( 'fields' => array_keys( $reports ) ),
|
||||
$assoc_args
|
||||
)
|
||||
);
|
||||
|
||||
if ( 'ids' === $formatter->format ) {
|
||||
echo implode( ' ', $reports );
|
||||
} else {
|
||||
$formatter->display_item( $reports );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* View sales report.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Instead of returning the whole report fields, returns the value of a single fields.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Get a specific subset of the report's fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Accepted values: table, json, csv. Default: table.
|
||||
*
|
||||
* [--period=<period>]
|
||||
* : The supported periods are: week, month, last_month, and year. If invalid
|
||||
* period is supplied, week is used. If period is not specified, the current
|
||||
* day is used.
|
||||
*
|
||||
* [--date_min]
|
||||
* : Return sales for a specific start date. The date need to be in the YYYY-MM-AA format.
|
||||
*
|
||||
* [--date_max]
|
||||
* : Return sales for a specific end date. The dates need to be in the YYYY-MM-AA format.
|
||||
*
|
||||
* [--limit]
|
||||
* : Limit report result. Default: 12.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields are available for get command:
|
||||
*
|
||||
* * total_sales
|
||||
* * average_sales
|
||||
* * total_orders
|
||||
* * total_items
|
||||
* * total_tax
|
||||
* * total_shipping
|
||||
* * total_discount
|
||||
* * totals_grouped_by
|
||||
* * totals
|
||||
* * total_customers
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc report sales
|
||||
*
|
||||
* wp wc report sales --period=last_month
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function sales( $__, $assoc_args ) {
|
||||
$reporter = $this->get_reporter( $assoc_args );
|
||||
|
||||
// new customers
|
||||
$users_query = new WP_User_Query(
|
||||
array(
|
||||
'fields' => array( 'user_registered' ),
|
||||
'role' => 'customer',
|
||||
)
|
||||
);
|
||||
|
||||
$customers = $users_query->get_results();
|
||||
|
||||
foreach ( $customers as $key => $customer ) {
|
||||
if ( strtotime( $customer->user_registered ) < $reporter->start_date || strtotime( $customer->user_registered ) > $reporter->end_date ) {
|
||||
unset( $customers[ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
$total_customers = count( $customers );
|
||||
$report_data = $reporter->get_report_data();
|
||||
$period_totals = array();
|
||||
|
||||
// setup period totals by ensuring each period in the interval has data
|
||||
for ( $i = 0; $i <= $reporter->chart_interval; $i ++ ) {
|
||||
|
||||
switch ( $reporter->chart_groupby ) {
|
||||
case 'day' :
|
||||
$time = date( 'Y-m-d', strtotime( "+{$i} DAY", $reporter->start_date ) );
|
||||
break;
|
||||
default :
|
||||
$time = date( 'Y-m', strtotime( "+{$i} MONTH", $reporter->start_date ) );
|
||||
break;
|
||||
}
|
||||
|
||||
// set the customer signups for each period
|
||||
$customer_count = 0;
|
||||
foreach ( $customers as $customer ) {
|
||||
if ( date( ( 'day' == $reporter->chart_groupby ) ? 'Y-m-d' : 'Y-m', strtotime( $customer->user_registered ) ) == $time ) {
|
||||
$customer_count++;
|
||||
}
|
||||
}
|
||||
|
||||
$period_totals[ $time ] = array(
|
||||
'sales' => wc_format_decimal( 0.00, 2 ),
|
||||
'orders' => 0,
|
||||
'items' => 0,
|
||||
'tax' => wc_format_decimal( 0.00, 2 ),
|
||||
'shipping' => wc_format_decimal( 0.00, 2 ),
|
||||
'discount' => wc_format_decimal( 0.00, 2 ),
|
||||
'customers' => $customer_count,
|
||||
);
|
||||
}
|
||||
|
||||
// add total sales, total order count, total tax and total shipping for each period
|
||||
foreach ( $report_data->orders as $order ) {
|
||||
$time = ( 'day' === $reporter->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) );
|
||||
|
||||
if ( ! isset( $period_totals[ $time ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$period_totals[ $time ]['sales'] = wc_format_decimal( $order->total_sales, 2 );
|
||||
$period_totals[ $time ]['tax'] = wc_format_decimal( $order->total_tax + $order->total_shipping_tax, 2 );
|
||||
$period_totals[ $time ]['shipping'] = wc_format_decimal( $order->total_shipping, 2 );
|
||||
}
|
||||
|
||||
foreach ( $report_data->order_counts as $order ) {
|
||||
$time = ( 'day' === $reporter->chart_groupby ) ? date( 'Y-m-d', strtotime( $order->post_date ) ) : date( 'Y-m', strtotime( $order->post_date ) );
|
||||
|
||||
if ( ! isset( $period_totals[ $time ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$period_totals[ $time ]['orders'] = (int) $order->count;
|
||||
}
|
||||
|
||||
// add total order items for each period
|
||||
foreach ( $report_data->order_items as $order_item ) {
|
||||
$time = ( 'day' === $reporter->chart_groupby ) ? date( 'Y-m-d', strtotime( $order_item->post_date ) ) : date( 'Y-m', strtotime( $order_item->post_date ) );
|
||||
|
||||
if ( ! isset( $period_totals[ $time ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$period_totals[ $time ]['items'] = (int) $order_item->order_item_count;
|
||||
}
|
||||
|
||||
// add total discount for each period
|
||||
foreach ( $report_data->coupons as $discount ) {
|
||||
$time = ( 'day' === $reporter->chart_groupby ) ? date( 'Y-m-d', strtotime( $discount->post_date ) ) : date( 'Y-m', strtotime( $discount->post_date ) );
|
||||
|
||||
if ( ! isset( $period_totals[ $time ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$period_totals[ $time ]['discount'] = wc_format_decimal( $discount->discount_amount, 2 );
|
||||
}
|
||||
|
||||
$sales_data = array(
|
||||
'total_sales' => $report_data->total_sales,
|
||||
'net_sales' => $report_data->net_sales,
|
||||
'average_sales' => $report_data->average_sales,
|
||||
'total_orders' => $report_data->total_orders,
|
||||
'total_items' => $report_data->total_items,
|
||||
'total_tax' => wc_format_decimal( $report_data->total_tax + $report_data->total_shipping_tax, 2 ),
|
||||
'total_shipping' => $report_data->total_shipping,
|
||||
'total_refunds' => $report_data->total_refunds,
|
||||
'total_discount' => $report_data->total_coupons,
|
||||
'totals_grouped_by' => $reporter->chart_groupby,
|
||||
'totals' => $period_totals,
|
||||
'total_customers' => $total_customers,
|
||||
);
|
||||
|
||||
$sales_data = apply_filters( 'woocommerce_cli_sales_report', $sales_data );
|
||||
|
||||
if ( empty( $assoc_args['fields'] ) ) {
|
||||
$assoc_args['fields'] = array_keys( $sales_data );
|
||||
}
|
||||
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
$formatter->display_item( $sales_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* View report of top sellers.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : Filter report based on report property.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Prints the value of a single field for each seller.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Limit the output to specific report fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Acceptec values: table, csv, json, count, ids. Default: table.
|
||||
*
|
||||
* [--period=<period>]
|
||||
* : The supported periods are: week, month, last_month, and year. If invalid
|
||||
* period is supplied, week is used. If period is not specified, the current
|
||||
* day is used.
|
||||
*
|
||||
* [--date_min]
|
||||
* : Return sales for a specific start date. The date need to be in the YYYY-MM-AA format.
|
||||
*
|
||||
* [--date_max]
|
||||
* : Return sales for a specific end date. The dates need to be in the YYYY-MM-AA format.
|
||||
*
|
||||
* [--limit]
|
||||
* : Limit report result. Default: 12.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields will be displayed by default for each row:
|
||||
*
|
||||
* * title
|
||||
* * product_id
|
||||
* * quantity
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc report top_sellers
|
||||
*
|
||||
* wp wc report top_sellers --period=last_month
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function top_sellers( $__, $assoc_args ) {
|
||||
$reporter = $this->get_reporter( $assoc_args );
|
||||
$top_sellers = $reporter->get_order_report_data( array(
|
||||
'data' => array(
|
||||
'_product_id' => array(
|
||||
'type' => 'order_item_meta',
|
||||
'order_item_type' => 'line_item',
|
||||
'function' => '',
|
||||
'name' => 'product_id',
|
||||
),
|
||||
'_qty' => array(
|
||||
'type' => 'order_item_meta',
|
||||
'order_item_type' => 'line_item',
|
||||
'function' => 'SUM',
|
||||
'name' => 'order_item_qty',
|
||||
),
|
||||
),
|
||||
'order_by' => 'order_item_qty DESC',
|
||||
'group_by' => 'product_id',
|
||||
'limit' => isset( $assoc_args['limit'] ) ? absint( $assoc_args['limit'] ) : 12,
|
||||
'query_type' => 'get_results',
|
||||
'filter_range' => true,
|
||||
) );
|
||||
|
||||
$top_sellers_data = array();
|
||||
foreach ( $top_sellers as $top_seller ) {
|
||||
$product = wc_get_product( $top_seller->product_id );
|
||||
|
||||
if ( $product ) {
|
||||
$top_sellers_data[] = array(
|
||||
'title' => $product->get_title(),
|
||||
'product_id' => $top_seller->product_id,
|
||||
'quantity' => $top_seller->order_item_qty,
|
||||
);
|
||||
}
|
||||
}
|
||||
$top_sellers_data = apply_filters( 'woocommerce_cli_top_sellers_report', $top_sellers_data );
|
||||
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
if ( 'ids' === $formatter->format ) {
|
||||
$query_args['fields'] = 'ids';
|
||||
echo implode( ' ', wp_list_pluck( $top_sellers_data, 'product_id' ) );
|
||||
} else {
|
||||
$formatter->display_items( $top_sellers_data );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the report object and parse any date filtering
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param array $assoc_args Arguments provided in when invoking the command
|
||||
* @return WC_Report_Sales_By_Date
|
||||
*/
|
||||
private function get_reporter( $assoc_args ) {
|
||||
|
||||
include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-admin-report.php' );
|
||||
include_once( WC()->plugin_path() . '/includes/admin/reports/class-wc-report-sales-by-date.php' );
|
||||
|
||||
$report = new WC_Report_Sales_By_Date();
|
||||
|
||||
if ( empty( $assoc_args['period'] ) ) {
|
||||
|
||||
// custom date range
|
||||
$assoc_args['period'] = 'custom';
|
||||
|
||||
if ( ! empty( $assoc_args['date_min'] ) || ! empty( $assoc_args['date_max'] ) ) {
|
||||
|
||||
// overwrite _GET to make use of WC_Admin_Report::calculate_current_range() for custom date ranges
|
||||
$_GET['start_date'] = $this->parse_datetime( $assoc_args['date_min'] );
|
||||
$_GET['end_date'] = isset( $assoc_args['date_max'] ) ? $this->parse_datetime( $assoc_args['date_max'] ) : null;
|
||||
|
||||
} else {
|
||||
|
||||
// default custom range to today
|
||||
$_GET['start_date'] = $_GET['end_date'] = date( 'Y-m-d', current_time( 'timestamp' ) );
|
||||
}
|
||||
} else {
|
||||
|
||||
// ensure period is valid
|
||||
if ( ! in_array( $assoc_args['period'], array( 'week', 'month', 'last_month', 'year' ) ) ) {
|
||||
$assoc_args['period'] = 'week';
|
||||
}
|
||||
|
||||
// TODO: change WC_Admin_Report class to use "week" instead, as it's more consistent with other periods
|
||||
// allow "week" for period instead of "7day"
|
||||
if ( 'week' === $assoc_args['period'] ) {
|
||||
$assoc_args['period'] = '7day';
|
||||
}
|
||||
}
|
||||
|
||||
$report->calculate_current_range( $assoc_args['period'] );
|
||||
|
||||
return $report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default format fields that will be used in `list` and `get` subcommands.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @return string
|
||||
*/
|
||||
protected function get_default_format_fields() {
|
||||
return 'title,product_id,quantity';
|
||||
}
|
||||
}
|
|
@ -1,685 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Manage Taxes.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @package WooCommerce/CLI
|
||||
* @category CLI
|
||||
* @author WooThemes
|
||||
*/
|
||||
class WC_CLI_Tax extends WC_CLI_Command {
|
||||
|
||||
/**
|
||||
* Create a tax rate.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : Associative args for the new tax rate.
|
||||
*
|
||||
* [--porcelain]
|
||||
* : Outputs just the new tax rate id.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields are available for create command:
|
||||
*
|
||||
* * country
|
||||
* * state
|
||||
* * postcode
|
||||
* * city
|
||||
* * rate
|
||||
* * name
|
||||
* * priority
|
||||
* * compound
|
||||
* * shipping
|
||||
* * class
|
||||
* * order
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc tax create --country=US --rate=5 --class=standard --type=percent
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function create( $__, $assoc_args ) {
|
||||
$porcelain = isset( $assoc_args['porcelain'] );
|
||||
unset( $assoc_args['porcelain'] );
|
||||
|
||||
$assoc_args = apply_filters( 'woocommerce_cli_create_tax_rate_data', $assoc_args );
|
||||
|
||||
$tax_data = array(
|
||||
'tax_rate_country' => '',
|
||||
'tax_rate_state' => '',
|
||||
'tax_rate' => '',
|
||||
'tax_rate_name' => '',
|
||||
'tax_rate_priority' => 1,
|
||||
'tax_rate_compound' => 0,
|
||||
'tax_rate_shipping' => 1,
|
||||
'tax_rate_order' => 0,
|
||||
'tax_rate_class' => '',
|
||||
);
|
||||
|
||||
foreach ( $tax_data as $key => $value ) {
|
||||
$new_key = str_replace( 'tax_rate_', '', $key );
|
||||
$new_key = 'tax_rate' === $new_key ? 'rate' : $new_key;
|
||||
|
||||
if ( isset( $assoc_args[ $new_key ] ) ) {
|
||||
if ( in_array( $new_key, array( 'compound', 'shipping' ) ) ) {
|
||||
$tax_data[ $key ] = $assoc_args[ $new_key ] ? 1 : 0;
|
||||
} else {
|
||||
$tax_data[ $key ] = $assoc_args[ $new_key ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create tax rate.
|
||||
$id = WC_Tax::_insert_tax_rate( $tax_data );
|
||||
|
||||
// Add locales.
|
||||
if ( ! empty( $assoc_args['postcode'] ) ) {
|
||||
WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $assoc_args['postcode'] ) );
|
||||
}
|
||||
|
||||
if ( ! empty( $assoc_args['city'] ) ) {
|
||||
WC_Tax::_update_tax_rate_cities( $id, wc_clean( $assoc_args['city'] ) );
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_cli_create_tax_rate', $id, $tax_data );
|
||||
|
||||
if ( $porcelain ) {
|
||||
WP_CLI::line( $id );
|
||||
} else {
|
||||
WP_CLI::success( "Created tax rate $id." );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a tax class.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : Associative args for the new tax class.
|
||||
*
|
||||
* [--porcelain]
|
||||
* : Outputs just the new tax class slug.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields are available for create command:
|
||||
*
|
||||
* * name
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc tax create_class --name="Reduced Rate"
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function create_class( $__, $assoc_args ) {
|
||||
try {
|
||||
$porcelain = isset( $assoc_args['porcelain'] );
|
||||
unset( $assoc_args['porcelain'] );
|
||||
|
||||
$assoc_args = apply_filters( 'woocommerce_cli_create_tax_class_data', $assoc_args );
|
||||
|
||||
// Check if name is specified.
|
||||
if ( ! isset( $assoc_args['name'] ) ) {
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_missing_name', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'name' ) );
|
||||
}
|
||||
|
||||
$name = sanitize_text_field( $assoc_args['name'] );
|
||||
$slug = sanitize_title( $name );
|
||||
$classes = WC_Tax::get_tax_classes();
|
||||
$exists = false;
|
||||
|
||||
// Check if class exists.
|
||||
foreach ( $classes as $key => $class ) {
|
||||
if ( sanitize_title( $class ) === $slug ) {
|
||||
$exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Return error if tax class already exists.
|
||||
if ( $exists ) {
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_cannot_create_tax_class', __( 'Tax class already exists', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
// Add the new class
|
||||
$classes[] = $name;
|
||||
|
||||
update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) );
|
||||
|
||||
do_action( 'woocommerce_cli_create_tax_class', $slug, array( 'name' => $name ) );
|
||||
|
||||
if ( $porcelain ) {
|
||||
WP_CLI::line( $slug );
|
||||
} else {
|
||||
WP_CLI::success( "Created tax class $slug." );
|
||||
}
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete one or more tax rates.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <id>...
|
||||
* : The tax rate ID to delete.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc tax delete 123
|
||||
*
|
||||
* wp wc tax delete $(wp wc tax list --format=ids)
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function delete( $args, $assoc_args ) {
|
||||
$exit_code = 0;
|
||||
|
||||
foreach ( $args as $tax_id ) {
|
||||
$tax_id = absint( $tax_id );
|
||||
$tax = WC_Tax::_get_tax_rate( $tax_id );
|
||||
|
||||
if ( is_null( $tax ) ) {
|
||||
$exit_code += 1;
|
||||
WP_CLI::warning( "Failed deleting tax rate {$tax_id}." );
|
||||
continue;
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_cli_delete_tax_rate', $tax_id );
|
||||
|
||||
WC_Tax::_delete_tax_rate( $tax_id );
|
||||
WP_CLI::success( "Deleted tax rate {$tax_id}." );
|
||||
}
|
||||
exit( $exit_code ? 1 : 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete one or more tax classes.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <slug>...
|
||||
* : The tax class slug to delete.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc tax delete_class reduced-rate
|
||||
*
|
||||
* wp wc tax delete_class $(wp wc tax list_class --format=ids)
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function delete_class( $args, $assoc_args ) {
|
||||
$classes = WC_Tax::get_tax_classes();
|
||||
$exit_code = 0;
|
||||
|
||||
foreach ( $args as $slug ) {
|
||||
$slug = sanitize_title( $slug );
|
||||
$deleted = false;
|
||||
|
||||
foreach ( $classes as $key => $class ) {
|
||||
if ( sanitize_title( $class ) === $slug ) {
|
||||
unset( $classes[ $key ] );
|
||||
$deleted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $deleted ) {
|
||||
WP_CLI::success( "Deleted tax class {$slug}." );
|
||||
} else {
|
||||
$exit_code += 1;
|
||||
WP_CLI::warning( "Failed deleting tax class {$slug}." );
|
||||
}
|
||||
}
|
||||
|
||||
update_option( 'woocommerce_tax_classes', implode( "\n", $classes ) );
|
||||
|
||||
exit( $exit_code ? 1 : 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a tax rate.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <id>
|
||||
* : Tax rate ID
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Instead of returning the whole tax rate fields, returns the value of a single fields.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Get a specific subset of the tax rates fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Accepted values: table, json, csv. Default: table.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields are available for get command:
|
||||
*
|
||||
* * id
|
||||
* * country
|
||||
* * state
|
||||
* * postcode
|
||||
* * city
|
||||
* * rate
|
||||
* * name
|
||||
* * priority
|
||||
* * compound
|
||||
* * shipping
|
||||
* * order
|
||||
* * class
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc tax get 123 --field=rate
|
||||
*
|
||||
* wp wc tax get 321 --format=json > rate321.json
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function get( $args, $assoc_args ) {
|
||||
global $wpdb;
|
||||
|
||||
try {
|
||||
|
||||
$tax_data = $this->format_taxes_to_items( array( $args[0] ) );
|
||||
|
||||
if ( empty( $tax_data ) ) {
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_invalid_tax_rate', sprintf( __( 'Invalid tax rate ID: %s', 'woocommerce' ), $args[0] ) );
|
||||
}
|
||||
|
||||
$tax_data = apply_filters( 'woocommerce_cli_get_tax_rate', $tax_data[0] );
|
||||
|
||||
if ( empty( $assoc_args['fields'] ) ) {
|
||||
$assoc_args['fields'] = array_keys( $tax_data );
|
||||
}
|
||||
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
$formatter->display_item( $tax_data );
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List taxes.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : Filter tax based on tax property.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Prints the value of a single field for each tax.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Limit the output to specific tax fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Acceptec values: table, csv, json, count, ids. Default: table.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields will be displayed by default for each tax:
|
||||
*
|
||||
* * id
|
||||
* * country
|
||||
* * state
|
||||
* * postcode
|
||||
* * city
|
||||
* * rate
|
||||
* * name
|
||||
* * priority
|
||||
* * compound
|
||||
* * shipping
|
||||
* * class
|
||||
*
|
||||
* These fields are optionally available:
|
||||
*
|
||||
* * order
|
||||
*
|
||||
* Fields for filtering query result also available:
|
||||
*
|
||||
* * class Sort by tax class.
|
||||
* * page Page number.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc tax list
|
||||
*
|
||||
* wp wc tax list --field=id
|
||||
*
|
||||
* wp wc tax list --fields=id,rate,class --format=json
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @subcommand list
|
||||
*/
|
||||
public function list_( $__, $assoc_args ) {
|
||||
$query_args = $this->merge_tax_query_args( array(), $assoc_args );
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
|
||||
$taxes = $this->query_tax_rates( $query_args );
|
||||
|
||||
if ( 'ids' === $formatter->format ) {
|
||||
$_taxes = array();
|
||||
foreach ( $taxes as $tax ) {
|
||||
$_taxes[] = $tax->tax_rate_id;
|
||||
}
|
||||
echo implode( ' ', $_taxes );
|
||||
} else {
|
||||
$items = $this->format_taxes_to_items( $taxes );
|
||||
$formatter->display_items( $items );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List tax classes.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : Filter tax class based on tax class property.
|
||||
*
|
||||
* [--field=<field>]
|
||||
* : Prints the value of a single field for each tax class.
|
||||
*
|
||||
* [--fields=<fields>]
|
||||
* : Limit the output to specific tax class fields.
|
||||
*
|
||||
* [--format=<format>]
|
||||
* : Acceptec values: table, csv, json, count, ids. Default: table.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields will be displayed by default for each tax class:
|
||||
*
|
||||
* * slug
|
||||
* * name
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc tax list_class
|
||||
*
|
||||
* wp wc tax list_class --field=slug
|
||||
*
|
||||
* wp wc tax list_class --format=json
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @subcommand list_class
|
||||
*/
|
||||
public function list_class( $__, $assoc_args ) {
|
||||
// Set default fields for tax classes
|
||||
if ( empty( $assoc_args['fields'] ) ) {
|
||||
$assoc_args['fields'] = 'slug,name';
|
||||
}
|
||||
|
||||
$formatter = $this->get_formatter( $assoc_args );
|
||||
$items = array();
|
||||
|
||||
// Add standard class
|
||||
$items[] = array(
|
||||
'slug' => 'standard',
|
||||
'name' => __( 'Standard rate', 'woocommerce' ),
|
||||
);
|
||||
|
||||
$classes = WC_Tax::get_tax_classes();
|
||||
|
||||
foreach ( $classes as $class ) {
|
||||
$items[] = apply_filters( 'woocommerce_cli_tax_class_response', array(
|
||||
'slug' => sanitize_title( $class ),
|
||||
'name' => $class,
|
||||
), $class, $assoc_args, $this );
|
||||
}
|
||||
|
||||
if ( 'ids' === $formatter->format ) {
|
||||
$_slugs = array();
|
||||
foreach ( $items as $item ) {
|
||||
$_slugs[] = $item['slug'];
|
||||
}
|
||||
echo implode( ' ', $_slugs );
|
||||
} else {
|
||||
$formatter->display_items( $items );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a tax rate.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <id>
|
||||
* : The ID of the tax rate to update.
|
||||
*
|
||||
* [--<field>=<value>]
|
||||
* : One or more fields to update.
|
||||
*
|
||||
* ## AVAILABLE FIELDS
|
||||
*
|
||||
* These fields are available for update command:
|
||||
*
|
||||
* * country
|
||||
* * state
|
||||
* * postcode
|
||||
* * city
|
||||
* * rate
|
||||
* * name
|
||||
* * priority
|
||||
* * compound
|
||||
* * shipping
|
||||
* * class
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc tax update 123 --rate=5
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function update( $args, $assoc_args ) {
|
||||
try {
|
||||
// Get current tax rate data
|
||||
$tax_data = $this->format_taxes_to_items( array( $args[0] ) );
|
||||
|
||||
if ( empty( $tax_data ) ) {
|
||||
throw new WC_CLI_Exception( 'woocommerce_cli_invalid_tax_rate', sprintf( __( 'Invalid tax rate ID: %s', 'woocommerce' ), $args[0] ) );
|
||||
}
|
||||
|
||||
$current_data = $tax_data[0];
|
||||
$id = $current_data['id'];
|
||||
$data = apply_filters( 'woocommerce_cli_update_tax_rate_data', $assoc_args, $id );
|
||||
$new_data = array();
|
||||
$default_fields = array(
|
||||
'tax_rate_country',
|
||||
'tax_rate_state',
|
||||
'tax_rate',
|
||||
'tax_rate_name',
|
||||
'tax_rate_priority',
|
||||
'tax_rate_compound',
|
||||
'tax_rate_shipping',
|
||||
'tax_rate_order',
|
||||
'tax_rate_class',
|
||||
);
|
||||
|
||||
foreach ( $data as $key => $value ) {
|
||||
$new_key = 'rate' === $key ? 'tax_rate' : 'tax_rate_' . $key;
|
||||
|
||||
// Check if the key is valid
|
||||
if ( ! in_array( $new_key, $default_fields ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Test new data against current data
|
||||
if ( $value === $current_data[ $key ] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Fix compund and shipping values
|
||||
if ( in_array( $key, array( 'compound', 'shipping' ) ) ) {
|
||||
$value = $value ? 1 : 0;
|
||||
}
|
||||
|
||||
$new_data[ $new_key ] = $value;
|
||||
}
|
||||
|
||||
// Update tax rate
|
||||
WC_Tax::_update_tax_rate( $id, $new_data );
|
||||
|
||||
// Update locales
|
||||
if ( ! empty( $data['postcode'] ) && $current_data['postcode'] != $data['postcode'] ) {
|
||||
WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $data['postcode'] ) );
|
||||
}
|
||||
|
||||
if ( ! empty( $data['city'] ) && $current_data['city'] != $data['city'] ) {
|
||||
WC_Tax::_update_tax_rate_cities( $id, wc_clean( $data['city'] ) );
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_cli_update_tax_rate', $id, $data );
|
||||
|
||||
WP_CLI::success( "Updated tax rate $id." );
|
||||
} catch ( WC_CLI_Exception $e ) {
|
||||
WP_CLI::error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add common cli arguments to argument list before $wpdb->get_results() is run.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param array $base_args Required arguments for the query (e.g. `limit`, etc)
|
||||
* @param array $assoc_args Arguments provided in when invoking the command
|
||||
* @return array
|
||||
*/
|
||||
protected function merge_tax_query_args( $base_args, $assoc_args ) {
|
||||
$args = array();
|
||||
|
||||
if ( ! empty( $assoc_args['class'] ) ) {
|
||||
$args['class'] = $assoc_args['class'];
|
||||
}
|
||||
|
||||
// Number of post to show per page.
|
||||
if ( ! empty( $assoc_args['limit'] ) ) {
|
||||
$args['posts_per_page'] = $assoc_args['limit'];
|
||||
}
|
||||
|
||||
// posts page.
|
||||
$args['paged'] = ( isset( $assoc_args['page'] ) ) ? absint( $assoc_args['page'] ) : 1;
|
||||
|
||||
$args = apply_filters( 'woocommerce_cli_tax_query_args', $args, $assoc_args );
|
||||
|
||||
return array_merge( $base_args, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to get tax rates objects
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param array $args
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function query_tax_rates( $args ) {
|
||||
global $wpdb;
|
||||
|
||||
$query = "
|
||||
SELECT tax_rate_id
|
||||
FROM {$wpdb->prefix}woocommerce_tax_rates
|
||||
WHERE 1 = 1
|
||||
";
|
||||
|
||||
// Filter by tax class
|
||||
if ( ! empty( $args['class'] ) ) {
|
||||
$class = 'standard' !== $args['class'] ? sanitize_title( $args['class'] ) : '';
|
||||
$query .= " AND tax_rate_class = '$class'";
|
||||
}
|
||||
|
||||
// Order tax rates
|
||||
$order_by = ' ORDER BY tax_rate_order';
|
||||
|
||||
// Pagination
|
||||
$per_page = isset( $args['posts_per_page'] ) ? $args['posts_per_page'] : get_option( 'posts_per_page' );
|
||||
$offset = 1 < $args['paged'] ? ( $args['paged'] - 1 ) * $per_page : 0;
|
||||
$pagination = sprintf( ' LIMIT %d, %d', $offset, $per_page );
|
||||
|
||||
return $wpdb->get_results( $query . $order_by . $pagination );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default format fields that will be used in `list` and `get` subcommands.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @return string
|
||||
*/
|
||||
protected function get_default_format_fields() {
|
||||
return 'id,country,state,postcode,city,rate,name,priority,compound,shipping,class';
|
||||
}
|
||||
|
||||
/**
|
||||
* Format taxes from query result to items in which each item contain
|
||||
* common properties of item, for instance `tax_rate_id` will be `id`.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @param array $taxes Array of tax rate.
|
||||
* @return array Items
|
||||
*/
|
||||
protected function format_taxes_to_items( $taxes ) {
|
||||
global $wpdb;
|
||||
|
||||
$items = array();
|
||||
|
||||
foreach ( $taxes as $tax_id ) {
|
||||
$id = is_object( $tax_id ) ? $tax_id->tax_rate_id : $tax_id;
|
||||
$id = absint( $id );
|
||||
|
||||
// Get tax rate details
|
||||
$tax = WC_Tax::_get_tax_rate( $id );
|
||||
|
||||
if ( is_wp_error( $tax ) || empty( $tax ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tax_data = array(
|
||||
'id' => $tax['tax_rate_id'],
|
||||
'country' => $tax['tax_rate_country'],
|
||||
'state' => $tax['tax_rate_state'],
|
||||
'postcode' => '',
|
||||
'city' => '',
|
||||
'rate' => $tax['tax_rate'],
|
||||
'name' => $tax['tax_rate_name'],
|
||||
'priority' => (int) $tax['tax_rate_priority'],
|
||||
'compound' => (bool) $tax['tax_rate_compound'],
|
||||
'shipping' => (bool) $tax['tax_rate_shipping'],
|
||||
'order' => (int) $tax['tax_rate_order'],
|
||||
'class' => $tax['tax_rate_class'] ? $tax['tax_rate_class'] : 'standard',
|
||||
);
|
||||
|
||||
// Get locales from a tax rate
|
||||
$locales = $wpdb->get_results( $wpdb->prepare( "
|
||||
SELECT location_code, location_type
|
||||
FROM {$wpdb->prefix}woocommerce_tax_rate_locations
|
||||
WHERE tax_rate_id = %d
|
||||
", $id ) );
|
||||
|
||||
if ( ! is_wp_error( $tax ) && ! is_null( $tax ) ) {
|
||||
foreach ( $locales as $locale ) {
|
||||
$tax_data[ $locale->location_type ] = $locale->location_code;
|
||||
}
|
||||
}
|
||||
|
||||
$items[] = $tax_data;
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Tools for WooCommerce.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @package WooCommerce/CLI
|
||||
* @category CLI
|
||||
* @author WooThemes
|
||||
*/
|
||||
class WC_CLI_Tool extends WC_CLI_Command {
|
||||
|
||||
/**
|
||||
* Clear the product/shop transients cache.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp wc tool clear_transients
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
public function clear_transients( $args, $assoc_args ) {
|
||||
wc_delete_product_transients();
|
||||
wc_delete_shop_order_transients();
|
||||
WC_Cache_Helper::get_transient_version( 'shipping', true );
|
||||
|
||||
WP_CLI::success( 'Product transients and shop order transients were cleared.' );
|
||||
}
|
||||
}
|
|
@ -290,10 +290,6 @@ final class WooCommerce {
|
|||
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-data-store-cpt.php' );
|
||||
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-coupon-data-store-cpt.php' );
|
||||
|
||||
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
||||
include_once( WC_ABSPATH . 'includes/class-wc-cli.php' );
|
||||
}
|
||||
|
||||
$this->query = new WC_Query();
|
||||
$this->api = new WC_API();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue