Merge branch 'master' into update/order-screen-refinements

This commit is contained in:
Mike Jolley 2017-12-04 13:44:27 +00:00
commit 5d42a64b73
57 changed files with 2193 additions and 1500 deletions

View File

@ -27,6 +27,22 @@
],
"post-update-cmd": [
"WooCommerce\\GitHooks\\Hooks::postHooks"
],
"test": [
"phpunit"
],
"phpcs": [
"phpcs -s -p --standard=./phpcs.ruleset.xml"
],
"phpcbf": [
"phpcs -p --standard=./phpcs.ruleset.xml"
]
},
"extra": {
"scripts-description": {
"test": "Run unit tests",
"phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer",
"phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier"
}
}
}

View File

@ -14,30 +14,30 @@ if ( ! defined( 'ABSPATH' ) ) {
}
$states['IE'] = array(
'CW' => __( 'Carlow', 'woocommerce' ),
'CN' => __( 'Cavan', 'woocommerce' ),
'CE' => __( 'Clare', 'woocommerce' ),
'CK' => __( 'Cork', 'woocommerce' ),
'CN' => __( 'Cavan', 'woocommerce' ),
'CW' => __( 'Carlow', 'woocommerce' ),
'DL' => __( 'Donegal', 'woocommerce' ),
'DN' => __( 'Dublin', 'woocommerce' ),
'GY' => __( 'Galway', 'woocommerce' ),
'KY' => __( 'Kerry', 'woocommerce' ),
'KE' => __( 'Kildare', 'woocommerce' ),
'KK' => __( 'Kilkenny', 'woocommerce' ),
'KY' => __( 'Kerry', 'woocommerce' ),
'LS' => __( 'Laois', 'woocommerce' ),
'LM' => __( 'Leitrim', 'woocommerce' ),
'LK' => __( 'Limerick', 'woocommerce' ),
'LD' => __( 'Longford', 'woocommerce' ),
'LH' => __( 'Louth', 'woocommerce' ),
'LK' => __( 'Limerick', 'woocommerce' ),
'LM' => __( 'Leitrim', 'woocommerce' ),
'LS' => __( 'Laois', 'woocommerce' ),
'MO' => __( 'Mayo', 'woocommerce' ),
'MH' => __( 'Meath', 'woocommerce' ),
'MN' => __( 'Monaghan', 'woocommerce' ),
'MO' => __( 'Mayo', 'woocommerce' ),
'OY' => __( 'Offaly', 'woocommerce' ),
'RN' => __( 'Roscommon', 'woocommerce' ),
'SO' => __( 'Sligo', 'woocommerce' ),
'TY' => __( 'Tipperary', 'woocommerce' ),
'WD' => __( 'Waterford', 'woocommerce' ),
'WH' => __( 'Westmeath', 'woocommerce' ),
'WW' => __( 'Wicklow', 'woocommerce' ),
'WX' => __( 'Wexford', 'woocommerce' ),
'WW' => __( 'Wicklow', 'woocommerce' )
);

View File

@ -14,51 +14,51 @@ if ( ! defined( 'ABSPATH' ) ) {
}
$states['JP'] = array(
'JP01' => __( 'Hokkaido', 'woocommerce' ),
'JP02' => __( 'Aomori', 'woocommerce' ),
'JP03' => __( 'Iwate', 'woocommerce' ),
'JP04' => __( 'Miyagi', 'woocommerce' ),
'JP05' => __( 'Akita', 'woocommerce' ),
'JP06' => __( 'Yamagata', 'woocommerce' ),
'JP07' => __( 'Fukushima', 'woocommerce' ),
'JP08' => __( 'Ibaraki', 'woocommerce' ),
'JP09' => __( 'Tochigi', 'woocommerce' ),
'JP10' => __( 'Gunma', 'woocommerce' ),
'JP11' => __( 'Saitama', 'woocommerce' ),
'JP12' => __( 'Chiba', 'woocommerce' ),
'JP13' => __( 'Tokyo', 'woocommerce' ),
'JP14' => __( 'Kanagawa', 'woocommerce' ),
'JP15' => __( 'Niigata', 'woocommerce' ),
'JP16' => __( 'Toyama', 'woocommerce' ),
'JP17' => __( 'Ishikawa', 'woocommerce' ),
'JP18' => __( 'Fukui', 'woocommerce' ),
'JP19' => __( 'Yamanashi', 'woocommerce' ),
'JP20' => __( 'Nagano', 'woocommerce' ),
'JP21' => __( 'Gifu', 'woocommerce' ),
'JP22' => __( 'Shizuoka', 'woocommerce' ),
'JP23' => __( 'Aichi', 'woocommerce' ),
'JP24' => __( 'Mie', 'woocommerce' ),
'JP25' => __( 'Shiga', 'woocommerce' ),
'JP26' => __( 'Kyoto', 'woocommerce' ),
'JP27' => __( 'Osaka', 'woocommerce' ),
'JP28' => __( 'Hyogo', 'woocommerce' ),
'JP29' => __( 'Nara', 'woocommerce' ),
'JP30' => __( 'Wakayama', 'woocommerce' ),
'JP31' => __( 'Tottori', 'woocommerce' ),
'JP32' => __( 'Shimane', 'woocommerce' ),
'JP33' => __( 'Okayama', 'woocommerce' ),
'JP34' => __( 'Hiroshima', 'woocommerce' ),
'JP35' => __( 'Yamaguchi', 'woocommerce' ),
'JP36' => __( 'Tokushima', 'woocommerce' ),
'JP37' => __( 'Kagawa', 'woocommerce' ),
'JP38' => __( 'Ehime', 'woocommerce' ),
'JP39' => __( 'Kochi', 'woocommerce' ),
'JP40' => __( 'Fukuoka', 'woocommerce' ),
'JP41' => __( 'Saga', 'woocommerce' ),
'JP42' => __( 'Nagasaki', 'woocommerce' ),
'JP43' => __( 'Kumamoto', 'woocommerce' ),
'JP44' => __( 'Oita', 'woocommerce' ),
'JP45' => __( 'Miyazaki', 'woocommerce' ),
'JP46' => __( 'Kagoshima', 'woocommerce' ),
'JP47' => __( 'Okinawa', 'woocommerce' ),
'JP01' => __( 'Hokkaido-dō', 'woocommerce' ),
'JP02' => __( 'Aomori-ken', 'woocommerce' ),
'JP03' => __( 'Iwate-ken', 'woocommerce' ),
'JP04' => __( 'Miyagi-ken', 'woocommerce' ),
'JP05' => __( 'Akita-ken', 'woocommerce' ),
'JP06' => __( 'Yamagata-ken', 'woocommerce' ),
'JP07' => __( 'Fukushima-ken', 'woocommerce' ),
'JP08' => __( 'Ibaraki-ken', 'woocommerce' ),
'JP09' => __( 'Tochigi-ken', 'woocommerce' ),
'JP10' => __( 'Gunma-ken', 'woocommerce' ),
'JP11' => __( 'Saitama-ken', 'woocommerce' ),
'JP12' => __( 'Chiba-ken', 'woocommerce' ),
'JP13' => __( 'Tokyo-to', 'woocommerce' ),
'JP14' => __( 'Kanagawa-ken', 'woocommerce' ),
'JP15' => __( 'Niigata-ken', 'woocommerce' ),
'JP16' => __( 'Toyama-ken', 'woocommerce' ),
'JP17' => __( 'Ishikawa-ken', 'woocommerce' ),
'JP18' => __( 'Fukui-ken', 'woocommerce' ),
'JP19' => __( 'Yamanashi-ken', 'woocommerce' ),
'JP20' => __( 'Nagano-ken', 'woocommerce' ),
'JP21' => __( 'Gifu-ken', 'woocommerce' ),
'JP22' => __( 'Shizuoka-ken', 'woocommerce' ),
'JP23' => __( 'Aichi-ken', 'woocommerce' ),
'JP24' => __( 'Mie-ken', 'woocommerce' ),
'JP25' => __( 'Shiga-ken', 'woocommerce' ),
'JP26' => __( 'Kyoto-fu', 'woocommerce' ),
'JP27' => __( 'Osaka-fu', 'woocommerce' ),
'JP28' => __( 'Hyogo-ken', 'woocommerce' ),
'JP29' => __( 'Nara-ken', 'woocommerce' ),
'JP30' => __( 'Wakayama-ken', 'woocommerce' ),
'JP31' => __( 'Tottori-ken', 'woocommerce' ),
'JP32' => __( 'Shimane-ken', 'woocommerce' ),
'JP33' => __( 'Okayama-ken', 'woocommerce' ),
'JP34' => __( 'Hiroshima-ken', 'woocommerce' ),
'JP35' => __( 'Yamaguchi-ken', 'woocommerce' ),
'JP36' => __( 'Tokushima-ken', 'woocommerce' ),
'JP37' => __( 'Kagawa-ken', 'woocommerce' ),
'JP38' => __( 'Ehime-ken', 'woocommerce' ),
'JP39' => __( 'Kochi-ken', 'woocommerce' ),
'JP40' => __( 'Fukuoka-ken', 'woocommerce' ),
'JP41' => __( 'Saga-ken', 'woocommerce' ),
'JP42' => __( 'Nagasaki-ken', 'woocommerce' ),
'JP43' => __( 'Kumamoto-ken', 'woocommerce' ),
'JP44' => __( 'Oita-ken', 'woocommerce' ),
'JP45' => __( 'Miyazaki-ken', 'woocommerce' ),
'JP46' => __( 'Kagoshima-ken', 'woocommerce' ),
'JP47' => __( 'Okinawa-ken', 'woocommerce' ),
);

View File

@ -1,4 +1,12 @@
<?php
/**
* Abstract deprecated hooks
*
* @package WooCommerce\Abstracts
* @since 3.0.0
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -7,8 +15,6 @@ if ( ! defined( 'ABSPATH' ) ) {
* WC_Deprecated_Hooks class maps old actions and filters to new ones. This is the base class for handling those deprecated hooks.
*
* Based on the WCS_Hook_Deprecator class by Prospress.
*
* @since 3.0.0
*/
abstract class WC_Deprecated_Hooks {
@ -19,6 +25,13 @@ abstract class WC_Deprecated_Hooks {
*/
protected $deprecated_hooks = array();
/**
* Array of versions on each hook has been deprecated.
*
* @var array
*/
protected $deprecated_version = array();
/**
* Constructor.
*/
@ -30,14 +43,14 @@ abstract class WC_Deprecated_Hooks {
/**
* Hook into the new hook so we can handle deprecated hooks once fired.
*
* @param string $hook_name
* @param string $hook_name Hook name.
*/
abstract function hook_in( $hook_name );
abstract public function hook_in( $hook_name );
/**
* Get old hooks to map to new hook.
*
* @param string $new_hook
* @param string $new_hook New hook name.
* @return array
*/
public function get_old_hooks( $new_hook ) {
@ -66,29 +79,39 @@ abstract class WC_Deprecated_Hooks {
/**
* If the old hook is in-use, trigger it.
*
* @param string $new_hook
* @param string $old_hook
* @param array $new_callback_args
* @param mixed $return_value
* @param string $new_hook New hook name.
* @param string $old_hook Old hook name.
* @param array $new_callback_args New callback args.
* @param mixed $return_value Returned value.
* @return mixed
*/
abstract function handle_deprecated_hook( $new_hook, $old_hook, $new_callback_args, $return_value );
abstract public function handle_deprecated_hook( $new_hook, $old_hook, $new_callback_args, $return_value );
/**
* Get deprecated version.
*
* @param string $old_hook Old hook name.
* @return string
*/
protected function get_deprecated_version( $old_hook ) {
return ! empty( $this->deprecated_version[ $old_hook ] ) ? $this->deprecated_version[ $old_hook ] : WC_VERSION;
}
/**
* Display a deprecated notice for old hooks.
*
* @param string $old_hook
* @param string $new_hook
* @param string $old_hook Old hook.
* @param string $new_hook New hook.
*/
protected function display_notice( $old_hook, $new_hook ) {
wc_deprecated_function( sprintf( 'The "%s" hook uses out of date data structures and', esc_html( $old_hook ) ), WC_VERSION, esc_html( $new_hook ) );
wc_deprecated_hook( esc_html( $old_hook ), esc_html( $this->get_deprecated_version( $old_hook ) ), esc_html( $new_hook ) );
}
/**
* Fire off a legacy hook with it's args.
*
* @param string $old_hook
* @param array $new_callback_args
* @param string $old_hook Old hook name.
* @param array $new_callback_args New callback args.
* @return mixed
*/
abstract protected function trigger_hook( $old_hook, $new_callback_args );

View File

@ -708,7 +708,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
}
}
return apply_filters( 'woocommerce_order_get_items', $items, $this );
return apply_filters( 'woocommerce_order_get_items', $items, $this, $types );
}
/**

View File

@ -83,11 +83,11 @@ class WC_Admin_Settings {
self::add_message( __( 'Your settings have been saved.', 'woocommerce' ) );
self::check_download_folder_protection();
// Clear any unwanted data and flush rules
// Clear any unwanted data and flush rules on next init.
add_option( 'woocommerce_queue_flush_rewrite_rules', 'true' );
delete_transient( 'woocommerce_cache_excluded_uris' );
WC()->query->init_query_vars();
WC()->query->add_endpoints();
wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' );
do_action( 'woocommerce_settings_saved' );
}

View File

@ -115,7 +115,7 @@ class WC_Admin_Status {
}
// Bulk actions
if ( isset( $_GET['action'] ) && isset( $_GET['log'] ) ) {
if ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['log'] ) ) {
self::log_table_bulk_actions();
}
@ -315,9 +315,9 @@ class WC_Admin_Status {
wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
}
$log_ids = array_map( 'absint', (array) $_GET['log'] );
$log_ids = array_map( 'absint', (array) $_REQUEST['log'] );
if ( 'delete' === $_GET['action'] || 'delete' === $_GET['action2'] ) {
if ( 'delete' === $_REQUEST['action'] || 'delete' === $_REQUEST['action2'] ) {
WC_Log_Handler_DB::delete( $log_ids );
wp_safe_redirect( esc_url_raw( admin_url( 'admin.php?page=wc-status&tab=logs' ) ) );
exit();

View File

@ -321,11 +321,9 @@ class WC_Helper {
/**
* Get available subscriptions filters.
*
* @param array Optional subscriptions array to generate counts.
*
* @return array An array of filter keys and labels.
*/
public static function get_filters( $subscriptions = null ) {
public static function get_filters() {
$filters = array(
'all' => __( 'All', 'woocommerce' ),
'active' => __( 'Active', 'woocommerce' ),

View File

@ -232,7 +232,7 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
$termlist[] = '<a href="' . esc_url( admin_url( 'edit.php?product_cat=' . $term->slug . '&post_type=product' ) ) . ' ">' . esc_html( $term->name ) . '</a>';
}
echo implode( ', ', $termlist ); // WPCS: XSS ok.
echo apply_filters( 'woocommerce_admin_product_term_list', implode( ', ', $termlist ), 'product_cat', $this->object->get_id(), $termlist, $terms ); // WPCS: XSS ok.
}
}
@ -248,7 +248,7 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
$termlist[] = '<a href="' . esc_url( admin_url( 'edit.php?product_tag=' . $term->slug . '&post_type=product' ) ) . ' ">' . esc_html( $term->name ) . '</a>';
}
echo implode( ', ', $termlist ); // WPCS: XSS ok.
echo apply_filters( 'woocommerce_admin_product_term_list', implode( ', ', $termlist ), 'product_tag', $this->object->get_id(), $termlist, $terms ); // WPCS: XSS ok.
}
}
@ -298,11 +298,16 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
* Render any custom filters and search inputs for the list table.
*/
protected function render_filters() {
$current_category_slug = isset( $_REQUEST['product_cat'] ) ? wc_clean( wp_unslash( $_REQUEST['product_cat'] ) ) : false; // WPCS: input var ok, sanitization ok.
$current_product_type = isset( $_REQUEST['product_type'] ) ? wc_clean( wp_unslash( $_REQUEST['product_type'] ) ) : false; // WPCS: input var ok, sanitization ok.
// @codingStandardsIgnoreStart
$current_category = $current_category_slug ? get_term_by( 'slug', $current_category_slug, 'product_cat' ): false;
// @codingStandardsIgnoreEnd
// Category Filtering.
$categories_count = (int) wp_count_terms( 'product_cat' );
if ( $categories_count <= apply_filters( 'woocommerce_product_category_filter_threshold', 100 ) ) {
wc_product_dropdown_categories( array(
'option_select_text' => __( 'Filter by category', 'woocommerce' ),
) );
} else {
$current_category_slug = isset( $_GET['product_cat'] ) ? wc_clean( wp_unslash( $_GET['product_cat'] ) ) : false; // WPCS: input var ok, CSRF ok.
$current_category = $current_category_slug ? get_term_by( 'slug', $current_category_slug, 'product_cat' ) : false;
?>
<select class="wc-category-search" name="product_cat" data-placeholder="<?php esc_attr_e( 'Filter by category', 'woocommerce' ); ?>" data-allow_clear="true">
<?php if ( $current_category_slug && $current_category ) : ?>
@ -310,10 +315,12 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
<?php endif; ?>
</select>
<?php
}
// Product type filtering.
$current_product_type = isset( $_REQUEST['product_type'] ) ? wc_clean( wp_unslash( $_REQUEST['product_type'] ) ) : false; // WPCS: input var ok, sanitization ok.
$terms = get_terms( 'product_type' );
$output = '<select name="product_type" id="dropdown_product_type">';
$output .= '<option value="">' . __( 'Filter by product type', 'woocommerce' ) . '</option>';
$output = '<select name="product_type" id="dropdown_product_type"><option value="">' . __( 'Filter by product type', 'woocommerce' ) . '</option>';
foreach ( $terms as $term ) {
$output .= '<option value="' . sanitize_title( $term->name ) . '" ';

View File

@ -658,8 +658,12 @@ class WC_Admin_Report {
return;
}
if ( ! isset( $_GET['wc_reports_nonce'] ) || ! wp_verify_nonce( $_GET['wc_reports_nonce'], 'custom_range' ) ) {
wp_safe_redirect( remove_query_arg( array( 'start_date', 'end_date', 'range', 'wc_reports_nonce' ) ) );
if ( ! isset( $_GET['wc_reports_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_GET['wc_reports_nonce'] ), 'custom_range' ) ) { // WPCS: input var ok, CSRF ok.
wp_die(
/* translators: %1$s: open link, %2$s: close link */
sprintf( esc_html__( 'This report link has expired. %1$sClick here to view the filtered report%2$s.', 'woocommerce' ), '<a href="' . esc_url( wp_nonce_url( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'custom_range', 'wc_reports_nonce' ) ) . '">', '</a>' ), // @codingStandardsIgnoreLine.
esc_attr__( 'Confirm navigation', 'woocommerce' )
);
exit;
}
}

View File

@ -185,7 +185,7 @@ class WC_REST_Product_Categories_Controller extends WC_REST_Product_Categories_V
'format' => 'uri',
'context' => array( 'view', 'edit' ),
),
'name' => array(
'title' => array(
'description' => __( 'Image name.', 'woocommerce' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),

View File

@ -240,7 +240,7 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller
'format' => 'uri',
'context' => array( 'view', 'edit' ),
),
'name' => array(
'title' => array(
'description' => __( 'Image name.', 'woocommerce' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),

View File

@ -378,7 +378,7 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller {
),
'date_min' => array(
/* translators: %s: date format */
'description' => sprintf( __( 'Return sales for a specific start date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-AA' ),
'description' => sprintf( __( 'Return sales for a specific start date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ),
'type' => 'string',
'format' => 'date',
'validate_callback' => 'wc_rest_validate_reports_request_arg',
@ -386,7 +386,7 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller {
),
'date_max' => array(
/* translators: %s: date format */
'description' => sprintf( __( 'Return sales for a specific end date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-AA' ),
'description' => sprintf( __( 'Return sales for a specific end date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ),
'type' => 'string',
'format' => 'date',
'validate_callback' => 'wc_rest_validate_reports_request_arg',

View File

@ -1664,9 +1664,6 @@ class WC_AJAX {
wp_send_json_success( $response_data );
} catch ( Exception $e ) {
if ( $refund && is_a( $refund, 'WC_Order_Refund' ) ) {
wp_delete_post( $refund->get_id(), true );
}
wp_send_json_error( array( 'error' => $e->getMessage() ) );
}
}

View File

@ -423,7 +423,7 @@ final class WC_Cart_Totals {
* @return object
*/
protected function remove_item_base_taxes( $item ) {
if ( $item->price_includes_tax ) {
if ( $item->price_includes_tax && $item->taxable ) {
$base_tax_rates = WC_Tax::get_base_tax_rates( $item->product->get_tax_class( 'unfiltered' ) );
// Work out a new base price without the shop's base tax.
@ -449,7 +449,7 @@ final class WC_Cart_Totals {
* @return object
*/
protected function adjust_non_base_location_price( $item ) {
if ( $item->price_includes_tax ) {
if ( $item->price_includes_tax && $item->taxable ) {
$base_tax_rates = WC_Tax::get_base_tax_rates( $item->product->get_tax_class( 'unfiltered' ) );
if ( $item->tax_rates !== $base_tax_rates ) {

View File

@ -218,7 +218,10 @@ class WC_Comments {
$stats = get_transient( 'wc_count_comments' );
if ( ! $stats ) {
$stats = array();
$stats = array(
'total_comments' => 0,
'all' => 0,
);
$count = $wpdb->get_results( "
SELECT comment_approved, COUNT(*) AS num_comments
@ -227,7 +230,6 @@ class WC_Comments {
GROUP BY comment_approved
", ARRAY_A );
$total = 0;
$approved = array(
'0' => 'moderated',
'1' => 'approved',
@ -238,16 +240,17 @@ class WC_Comments {
foreach ( (array) $count as $row ) {
// Don't count post-trashed toward totals.
if ( 'post-trashed' !== $row['comment_approved'] && 'trash' !== $row['comment_approved'] ) {
$total += $row['num_comments'];
if ( ! in_array( $row['comment_approved'], array( 'post-trashed', 'trash', 'spam' ), true ) ) {
$stats['all'] += $row['num_comments'];
$stats['total_comments'] += $row['num_comments'];
} elseif ( ! in_array( $row['comment_approved'], array( 'post-trashed', 'trash' ), true ) ) {
$stats['total_comments'] += $row['num_comments'];
}
if ( isset( $approved[ $row['comment_approved'] ] ) ) {
$stats[ $approved[ $row['comment_approved'] ] ] = $row['num_comments'];
}
}
$stats['total_comments'] = $total;
$stats['all'] = $total;
foreach ( $approved as $key ) {
if ( empty( $stats[ $key ] ) ) {
$stats[ $key ] = 0;

View File

@ -1,12 +1,18 @@
<?php
/**
* Deprecated action hooks
*
* @package WooCommerce\Abstracts
* @since 3.0.0
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Handles deprecation notices and triggering of legacy action hooks.
*
* @since 3.0.0
*/
class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
@ -34,12 +40,36 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
),
'woocommerce_new_payment_token' => 'woocommerce_payment_token_created',
'woocommerce_new_product_variation' => 'woocommerce_create_product_variation',
'woocommerce_order_details_after_order_table_items' => 'woocommerce_order_items_table'
'woocommerce_order_details_after_order_table_items' => 'woocommerce_order_items_table',
);
/**
* Array of versions on each hook has been deprecated.
*
* @var array
*/
protected $deprecated_version = array(
'woocommerce_order_add_shipping' => '3.0.0',
'woocommerce_order_add_coupon' => '3.0.0',
'woocommerce_order_add_tax' => '3.0.0',
'woocommerce_order_add_fee' => '3.0.0',
'woocommerce_add_shipping_order_item' => '3.0.0',
'woocommerce_add_order_item_meta' => '3.0.0',
'woocommerce_add_order_fee_meta' => '3.0.0',
'woocommerce_order_edit_product' => '3.0.0',
'woocommerce_order_update_coupon' => '3.0.0',
'woocommerce_order_update_shipping' => '3.0.0',
'woocommerce_order_update_fee' => '3.0.0',
'woocommerce_order_update_tax' => '3.0.0',
'woocommerce_payment_token_created' => '3.0.0',
'woocommerce_create_product_variation' => '3.0.0',
'woocommerce_order_items_table' => '3.0.0',
);
/**
* Hook into the new hook so we can handle deprecated hooks once fired.
* @param string $hook_name
*
* @param string $hook_name Hook name.
*/
public function hook_in( $hook_name ) {
add_action( $hook_name, array( $this, 'maybe_handle_deprecated_hook' ), -1000, 8 );
@ -48,10 +78,10 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
/**
* If the old hook is in-use, trigger it.
*
* @param string $new_hook
* @param string $old_hook
* @param array $new_callback_args
* @param mixed $return_value
* @param string $new_hook New hook name.
* @param string $old_hook Old hook name.
* @param array $new_callback_args New callback args.
* @param mixed $return_value Returned value.
* @return mixed
*/
public function handle_deprecated_hook( $new_hook, $old_hook, $new_callback_args, $return_value ) {
@ -65,14 +95,14 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
/**
* Fire off a legacy hook with it's args.
*
* @param string $old_hook
* @param array $new_callback_args
* @param string $old_hook Old hook name.
* @param array $new_callback_args New callback args.
* @return mixed
*/
protected function trigger_hook( $old_hook, $new_callback_args ) {
switch ( $old_hook ) {
case 'woocommerce_order_add_shipping' :
case 'woocommerce_order_add_fee' :
case 'woocommerce_order_add_shipping':
case 'woocommerce_order_add_fee':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -80,7 +110,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $order_id, $item_id, $item );
}
break;
case 'woocommerce_order_add_coupon' :
case 'woocommerce_order_add_coupon':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -88,7 +118,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $order_id, $item_id, $item->get_code(), $item->get_discount(), $item->get_discount_tax() );
}
break;
case 'woocommerce_order_add_tax' :
case 'woocommerce_order_add_tax':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -96,7 +126,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $order_id, $item_id, $item->get_rate_id(), $item->get_tax_total(), $item->get_shipping_tax_total() );
}
break;
case 'woocommerce_add_shipping_order_item' :
case 'woocommerce_add_shipping_order_item':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -104,7 +134,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $order_id, $item_id, $item->legacy_package_key );
}
break;
case 'woocommerce_add_order_item_meta' :
case 'woocommerce_add_order_item_meta':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -112,7 +142,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $item_id, $item->legacy_values, $item->legacy_cart_item_key );
}
break;
case 'woocommerce_add_order_fee_meta' :
case 'woocommerce_add_order_fee_meta':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -120,7 +150,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $order_id, $item_id, $item->legacy_fee, $item->legacy_fee_key );
}
break;
case 'woocommerce_order_edit_product' :
case 'woocommerce_order_edit_product':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -128,15 +158,15 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $order_id, $item_id, $item, $item->get_product() );
}
break;
case 'woocommerce_order_update_coupon' :
case 'woocommerce_order_update_shipping' :
case 'woocommerce_order_update_fee' :
case 'woocommerce_order_update_tax' :
case 'woocommerce_order_update_coupon':
case 'woocommerce_order_update_shipping':
case 'woocommerce_order_update_fee':
case 'woocommerce_order_update_tax':
if ( ! is_a( $item, 'WC_Order_Item_Product' ) ) {
do_action( $old_hook, $order_id, $item_id, $item );
}
break;
default :
default:
do_action_ref_array( $old_hook, $new_callback_args );
break;
}

View File

@ -1,12 +1,18 @@
<?php
/**
* Deprecated filter hooks
*
* @package WooCommerce\Abstracts
* @since 3.0.0
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Handles deprecation notices and triggering of legacy filter hooks.
*
* @since 3.0.0
* Handles deprecation notices and triggering of legacy filter hooks
*/
class WC_Deprecated_Filter_Hooks extends WC_Deprecated_Hooks {
@ -54,9 +60,53 @@ class WC_Deprecated_Filter_Hooks extends WC_Deprecated_Hooks {
'woocommerce_credit_card_type_labels' => 'wocommerce_credit_card_type_labels',
);
/**
* Array of versions on each hook has been deprecated.
*
* @var array
*/
protected $deprecated_version = array(
'woocommerce_email_order_schema_markup' => '3.0.0',
'add_to_cart_fragments' => '3.0.0',
'add_to_cart_redirect' => '3.0.0',
'woocommerce_product_width' => '3.0.0',
'woocommerce_product_height' => '3.0.0',
'woocommerce_product_length' => '3.0.0',
'woocommerce_product_weight' => '3.0.0',
'woocommerce_get_sku' => '3.0.0',
'woocommerce_get_price' => '3.0.0',
'woocommerce_get_regular_price' => '3.0.0',
'woocommerce_get_sale_price' => '3.0.0',
'woocommerce_product_tax_class' => '3.0.0',
'woocommerce_get_stock_quantity' => '3.0.0',
'woocommerce_get_product_attributes' => '3.0.0',
'woocommerce_product_gallery_attachment_ids' => '3.0.0',
'woocommerce_product_review_count' => '3.0.0',
'woocommerce_product_files' => '3.0.0',
'woocommerce_get_currency' => '3.0.0',
'woocommerce_order_amount_discount_total' => '3.0.0',
'woocommerce_order_amount_discount_tax' => '3.0.0',
'woocommerce_order_amount_shipping_total' => '3.0.0',
'woocommerce_order_amount_shipping_tax' => '3.0.0',
'woocommerce_order_amount_cart_tax' => '3.0.0',
'woocommerce_order_amount_total' => '3.0.0',
'woocommerce_order_amount_total_tax' => '3.0.0',
'woocommerce_order_amount_total_discount' => '3.0.0',
'woocommerce_order_amount_subtotal' => '3.0.0',
'woocommerce_order_tax_totals' => '3.0.0',
'woocommerce_refund_amount' => '3.0.0',
'woocommerce_refund_reason' => '3.0.0',
'default_checkout_country' => '3.0.0',
'default_checkout_state' => '3.0.0',
'default_checkout_postcode' => '3.0.0',
'woocommerce_debug_posting' => '3.0.0',
'wocommerce_credit_card_type_labels' => '3.0.0',
);
/**
* Hook into the new hook so we can handle deprecated hooks once fired.
* @param string $hook_name
*
* @param string $hook_name Hook name.
*/
public function hook_in( $hook_name ) {
add_filter( $hook_name, array( $this, 'maybe_handle_deprecated_hook' ), -1000, 8 );
@ -65,10 +115,10 @@ class WC_Deprecated_Filter_Hooks extends WC_Deprecated_Hooks {
/**
* If the old hook is in-use, trigger it.
*
* @param string $new_hook
* @param string $old_hook
* @param array $new_callback_args
* @param mixed $return_value
* @param string $new_hook New hook name.
* @param string $old_hook Old hook name.
* @param array $new_callback_args New callback args.
* @param mixed $return_value Returned value.
* @return mixed
*/
public function handle_deprecated_hook( $new_hook, $old_hook, $new_callback_args, $return_value ) {
@ -82,8 +132,8 @@ class WC_Deprecated_Filter_Hooks extends WC_Deprecated_Hooks {
/**
* Fire off a legacy hook with it's args.
*
* @param string $old_hook
* @param array $new_callback_args
* @param string $old_hook Old hook name.
* @param array $new_callback_args New callback args.
* @return mixed
*/
protected function trigger_hook( $old_hook, $new_callback_args ) {

View File

@ -974,7 +974,7 @@ class WC_Form_Handler {
$redirect = wc_get_page_permalink( 'myaccount' );
}
wp_redirect( wp_validate_redirect( apply_filters( 'woocommerce_login_redirect', $redirect, $user ), wc_get_page_permalink( 'myaccount' ) ) );
wp_redirect( wp_validate_redirect( apply_filters( 'woocommerce_login_redirect', remove_query_arg( 'wc_error', $redirect ), $user ), wc_get_page_permalink( 'myaccount' ) ) );
exit;
}
} catch ( Exception $e ) {

View File

@ -21,11 +21,21 @@ if ( ! defined( 'ABSPATH' ) ) {
*/
class WC_Geolocation {
/** URL to the geolocation database we're using */
/**
* GeoLite IPv4 DB.
*/
const GEOLITE_DB = 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz';
/**
* GeoLite IPv6 DB.
*/
const GEOLITE_IPV6_DB = 'http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz';
/** @var array API endpoints for looking up user IP address */
/**
* API endpoints for looking up user IP address.
*
* @var array
*/
private static $ip_lookup_apis = array(
'icanhazip' => 'http://icanhazip.com',
'ipify' => 'http://api.ipify.org/',
@ -35,7 +45,11 @@ class WC_Geolocation {
'ip.appspot' => 'http://ip.appspot.com',
);
/** @var array API endpoints for geolocating an IP address */
/**
* API endpoints for geolocating an IP address
*
* @var array
*/
private static $geoip_apis = array(
'freegeoip' => 'https://freegeoip.net/json/%s',
'ipinfo.io' => 'https://ipinfo.io/%s/json',
@ -46,7 +60,7 @@ class WC_Geolocation {
* Hook in tabs.
*/
public static function init() {
// Only download the database from MaxMind if the geolocation function is enabled, or a plugin specifically requests it
// Only download the database from MaxMind if the geolocation function is enabled, or a plugin specifically requests it.
if ( 'geolocation' === get_option( 'woocommerce_default_customer_address' ) || apply_filters( 'woocommerce_geolocation_update_database_periodically', false ) ) {
add_action( 'woocommerce_geoip_updater', array( __CLASS__, 'update_database' ) );
}
@ -55,8 +69,9 @@ class WC_Geolocation {
/**
* Maybe trigger a DB update for the first time.
* @param string $new_value
* @param string $old_value
*
* @param string $new_value New value.
* @param string $old_value Old value.
* @return string
*/
public static function maybe_update_database( $new_value, $old_value ) {
@ -66,46 +81,20 @@ class WC_Geolocation {
return $new_value;
}
/**
* Check if is a valid IP address.
*
* @since 3.0.6
* @param string $ip_address IP address.
* @return string|bool The valid IP address, otherwise false.
*/
private static function is_ip_address( $ip_address ) {
// WP 4.7+ only.
if ( function_exists( 'rest_is_ip_address' ) ) {
return rest_is_ip_address( $ip_address );
}
// Support for WordPress 4.4 to 4.6.
if ( ! class_exists( 'Requests_IPv6', false ) ) {
include_once( dirname( __FILE__ ) . '/vendor/class-requests-ipv6.php' );
}
$ipv4_pattern = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/';
if ( ! preg_match( $ipv4_pattern, $ip_address ) && ! Requests_IPv6::check_ipv6( $ip_address ) ) {
return false;
}
return $ip_address;
}
/**
* Get current user IP Address.
*
* @return string
*/
public static function get_ip_address() {
if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) {
return $_SERVER['HTTP_X_REAL_IP'];
} elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) { // WPCS: input var ok, CSRF ok.
return sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_REAL_IP'] ) ); // WPCS: input var ok, CSRF ok.
} elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { // WPCS: input var ok, CSRF ok.
// Proxy servers can send through this header like this: X-Forwarded-For: client1, proxy1, proxy2
// Make sure we always only send through the first IP in the list which should always be the client IP.
return (string) self::is_ip_address( trim( current( explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) );
} elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
return $_SERVER['REMOTE_ADDR'];
return (string) rest_is_ip_address( trim( current( explode( ',', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) ) ) ); // WPCS: input var ok, CSRF ok.
} elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) { // @codingStandardsIgnoreLine
return sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); // @codingStandardsIgnoreLine
}
return '';
}
@ -114,6 +103,7 @@ class WC_Geolocation {
* Get user IP Address using an external service.
* This is used mainly as a fallback for users on localhost where
* get_ip_address() will be a local IP and non-geolocatable.
*
* @return string
*/
public static function get_external_ip_address() {
@ -148,7 +138,8 @@ class WC_Geolocation {
/**
* Geolocate an IP address.
* @param string $ip_address
*
* @param string $ip_address IP Address.
* @param bool $fallback If true, fallbacks to alternative IP detection (can be slower).
* @param bool $api_fallback If true, uses geolocation APIs if the database file doesn't exist (can be slower).
* @return array
@ -158,19 +149,19 @@ class WC_Geolocation {
$country_code = apply_filters( 'woocommerce_geolocate_ip', false, $ip_address, $fallback, $api_fallback );
if ( false === $country_code ) {
// If GEOIP is enabled in CloudFlare, we can use that (Settings -> CloudFlare Settings -> Settings Overview)
if ( ! empty( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ) {
$country_code = sanitize_text_field( strtoupper( $_SERVER['HTTP_CF_IPCOUNTRY'] ) );
// If GEOIP is enabled in CloudFlare, we can use that (Settings -> CloudFlare Settings -> Settings Overview).
if ( ! empty( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ) { // WPCS: input var ok, CSRF ok.
$country_code = strtoupper( sanitize_text_field( wp_unslash( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ) ); // WPCS: input var ok, CSRF ok.
} elseif ( ! empty( $_SERVER['GEOIP_COUNTRY_CODE'] ) ) { // WPCS: input var ok, CSRF ok.
// WP.com VIP has a variable available.
} elseif ( ! empty( $_SERVER['GEOIP_COUNTRY_CODE'] ) ) {
$country_code = sanitize_text_field( strtoupper( $_SERVER['GEOIP_COUNTRY_CODE'] ) );
$country_code = strtoupper( sanitize_text_field( wp_unslash( $_SERVER['GEOIP_COUNTRY_CODE'] ) ) ); // WPCS: input var ok, CSRF ok.
} elseif ( ! empty( $_SERVER['HTTP_X_COUNTRY_CODE'] ) ) { // WPCS: input var ok, CSRF ok.
// VIP Go has a variable available also.
} elseif ( ! empty( $_SERVER['HTTP_X_COUNTRY_CODE'] ) ) {
$country_code = sanitize_text_field( strtoupper( $_SERVER['HTTP_X_COUNTRY_CODE'] ) );
$country_code = strtoupper( sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_COUNTRY_CODE'] ) ) ); // WPCS: input var ok, CSRF ok.
} else {
$ip_address = $ip_address ? $ip_address : self::get_ip_address();
if ( self::is_IPv6( $ip_address ) ) {
if ( self::is_ipv6( $ip_address ) ) {
$database = self::get_local_database_path( 'v6' );
} else {
$database = self::get_local_database_path();
@ -185,7 +176,7 @@ class WC_Geolocation {
}
if ( ! $country_code && $fallback ) {
// May be a local environment - find external IP
// May be a local environment - find external IP.
return self::geolocate_ip( self::get_external_ip_address(), false, $api_fallback );
}
}
@ -199,11 +190,12 @@ class WC_Geolocation {
/**
* Path to our local db.
* @param string $version
*
* @param string $version Version.
* @return string
*/
public static function get_local_database_path( $version = 'v4' ) {
$version = ( 'v4' == $version ) ? '' : 'v6';
$version = 'v4' === $version ? '' : 'v6';
$upload_dir = wp_upload_dir();
return apply_filters( 'woocommerce_geolocation_local_database_path', $upload_dir['basedir'] . '/GeoIP' . $version . '.dat', $version );
@ -220,7 +212,7 @@ class WC_Geolocation {
return;
}
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once ABSPATH . 'wp-admin/includes/file.php';
$tmp_databases = array(
'v4' => download_url( self::GEOLITE_DB ),
@ -229,20 +221,20 @@ class WC_Geolocation {
foreach ( $tmp_databases as $tmp_database_version => $tmp_database_path ) {
if ( ! is_wp_error( $tmp_database_path ) ) {
$gzhandle = @gzopen( $tmp_database_path, 'r' );
$handle = @fopen( self::get_local_database_path( $tmp_database_version ), 'w' );
$gzhandle = @gzopen( $tmp_database_path, 'r' ); // @codingStandardsIgnoreLine
$handle = @fopen( self::get_local_database_path( $tmp_database_version ), 'w' ); // @codingStandardsIgnoreLine
if ( $gzhandle && $handle ) {
while ( $string = gzread( $gzhandle, 4096 ) ) {
fwrite( $handle, $string, strlen( $string ) );
while ( $string = gzread( $gzhandle, 4096 ) ) { // @codingStandardsIgnoreLine
fwrite( $handle, $string, strlen( $string ) ); // @codingStandardsIgnoreLine
}
gzclose( $gzhandle );
$s_array = fstat( $handle );
fclose( $handle );
fclose( $handle ); // @codingStandardsIgnoreLine
if ( ! isset( $s_array['size'] ) || 0 === $s_array['size'] ) {
$logger->notice( 'Empty database file, deleting local copy.', array( 'source' => 'geolocation' ) );
// Delete empty DB, we do not want to keep empty files around.
@unlink( self::get_local_database_path( $tmp_database_version ) );
@unlink( self::get_local_database_path( $tmp_database_version ) ); // @codingStandardsIgnoreLine
// Reschedule download of DB.
wp_clear_scheduled_hook( 'woocommerce_geoip_updater' );
wp_schedule_event( strtotime( 'first tuesday of next month' ), 'monthly', 'woocommerce_geoip_updater' );
@ -250,7 +242,7 @@ class WC_Geolocation {
} else {
$logger->notice( 'Unable to open database file', array( 'source' => 'geolocation' ) );
}
@unlink( $tmp_database_path );
@unlink( $tmp_database_path ); // @codingStandardsIgnoreLine
} else {
$logger->notice(
'Unable to download GeoIP Database: ' . $tmp_database_path->get_error_message(),
@ -262,17 +254,18 @@ class WC_Geolocation {
/**
* Use MAXMIND GeoLite database to geolocation the user.
* @param string $ip_address
*
* @param string $ip_address IP address.
* @return string
*/
private static function geolocate_via_db( $ip_address ) {
if ( ! class_exists( 'WC_Geo_IP', false ) ) {
include_once( WC_ABSPATH . 'includes/class-wc-geo-ip.php' );
include_once WC_ABSPATH . 'includes/class-wc-geo-ip.php';
}
$gi = new WC_Geo_IP();
if ( self::is_IPv6( $ip_address ) ) {
if ( self::is_ipv6( $ip_address ) ) {
$database = self::get_local_database_path( 'v6' );
if ( ! self::get_file_size( $database ) ) {
return false;
@ -301,14 +294,14 @@ class WC_Geolocation {
* @return bool|int
*/
private static function get_file_size( $filename ) {
$handle = @fopen( $filename, 'r' );
$s_array = fstat( $handle );
@fclose( $handle );
$handle = @fopen( $filename, 'r' ); // @codingStandardsIgnoreLine
$s_array = fstat( $handle ); // @codingStandardsIgnoreLine
@fclose( $handle ); // @codingStandardsIgnoreLine
if ( ! isset( $s_array['size'] ) || 0 === $s_array['size'] ) {
$logger = wc_get_logger();
$logger->notice( 'Empty database file, deleting local copy.', array( 'source' => 'geolocation' ) );
// Delete the file as we do not want to keep empty files around.
@unlink( $filename );
@unlink( $filename ); // @codingStandardsIgnoreLine
return false;
}
return $s_array['size'];
@ -316,7 +309,8 @@ class WC_Geolocation {
/**
* Use APIs to Geolocate the user.
* @param string $ip_address
*
* @param string $ip_address IP address.
* @return string|bool
*/
private static function geolocate_via_api( $ip_address ) {
@ -333,19 +327,19 @@ class WC_Geolocation {
if ( ! is_wp_error( $response ) && $response['body'] ) {
switch ( $service_name ) {
case 'ipinfo.io' :
case 'ipinfo.io':
$data = json_decode( $response['body'] );
$country_code = isset( $data->country ) ? $data->country : '';
break;
case 'ip-api.com' :
case 'ip-api.com':
$data = json_decode( $response['body'] );
$country_code = isset( $data->countryCode ) ? $data->countryCode : '';
$country_code = isset( $data->countryCode ) ? $data->countryCode : ''; // @codingStandardsIgnoreLine
break;
case 'freegeoip' :
case 'freegeoip':
$data = json_decode( $response['body'] );
$country_code = isset( $data->country_code ) ? $data->country_code : '';
break;
default :
default:
$country_code = apply_filters( 'woocommerce_geolocation_geoip_response_' . $service_name, '', $response['body'] );
break;
}
@ -369,10 +363,10 @@ class WC_Geolocation {
*
* @since 2.4.0
*
* @param string $ip_address
* @param string $ip_address IP Address.
* @return bool
*/
private static function is_IPv6( $ip_address ) {
private static function is_ipv6( $ip_address ) {
return false !== filter_var( $ip_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 );
}
}

View File

@ -98,6 +98,7 @@ class WC_Install {
),
'3.3.0' => array(
'wc_update_330_image_options',
'wc_update_330_set_default_product_cat',
'wc_update_330_db_version',
),
);
@ -128,7 +129,7 @@ class WC_Install {
* Init background updates
*/
public static function init_background_updater() {
include_once( dirname( __FILE__ ) . '/class-wc-background-updater.php' );
include_once dirname( __FILE__ ) . '/class-wc-background-updater.php';
self::$background_updater = new WC_Background_Updater();
}
@ -202,7 +203,7 @@ class WC_Install {
* @since 3.2.0
*/
private static function remove_admin_notices() {
include_once( dirname( __FILE__ ) . '/admin/class-wc-admin-notices.php' );
include_once dirname( __FILE__ ) . '/admin/class-wc-admin-notices.php';
WC_Admin_Notices::remove_all_notices();
}
@ -319,7 +320,8 @@ class WC_Install {
/**
* Update DB version to current.
* @param string $version
*
* @param string|null $version New WooCommerce DB version or null.
*/
public static function update_db_version( $version = null ) {
delete_option( 'woocommerce_db_version' );
@ -328,7 +330,8 @@ class WC_Install {
/**
* Add more cron schedules.
* @param array $schedules
*
* @param array $schedules List of WP scheduled cron jobs.
* @return array
*/
public static function cron_schedules( $schedules ) {
@ -368,9 +371,10 @@ class WC_Install {
* Create pages that the plugin relies on, storing page IDs in variables.
*/
public static function create_pages() {
include_once( dirname( __FILE__ ) . '/admin/wc-admin-functions.php' );
include_once dirname( __FILE__ ) . '/admin/wc-admin-functions.php';
$pages = apply_filters( 'woocommerce_create_pages', array(
$pages = apply_filters(
'woocommerce_create_pages', array(
'shop' => array(
'name' => _x( 'shop', 'Page slug', 'woocommerce' ),
'title' => _x( 'Shop', 'Page title', 'woocommerce' ),
@ -391,7 +395,8 @@ class WC_Install {
'title' => _x( 'My account', 'Page title', 'woocommerce' ),
'content' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']',
),
) );
)
);
foreach ( $pages as $key => $page ) {
wc_create_page( esc_sql( $page['name'] ), 'woocommerce_' . $key . '_page_id', $page['title'], $page['content'], ! empty( $page['parent'] ) ? wc_get_page_id( $page['parent'] ) : '' );
@ -406,8 +411,8 @@ class WC_Install {
* Sets up the default options used on the settings page.
*/
private static function create_options() {
// Include settings so that we can run through defaults
include_once( dirname( __FILE__ ) . '/admin/class-wc-admin-settings.php' );
// Include settings so that we can run through defaults.
include_once dirname( __FILE__ ) . '/admin/class-wc-admin-settings.php';
$settings = WC_Admin_Settings::get_settings_pages();
@ -454,11 +459,33 @@ class WC_Install {
foreach ( $taxonomies as $taxonomy => $terms ) {
foreach ( $terms as $term ) {
if ( ! get_term_by( 'name', $term, $taxonomy ) ) {
if ( ! get_term_by( 'name', $term, $taxonomy ) ) { // @codingStandardsIgnoreLine.
wp_insert_term( $term, $taxonomy );
}
}
}
$woocommerce_default_category = get_option( 'default_product_cat', 0 );
if ( ! $woocommerce_default_category || ! term_exists( $woocommerce_default_category, 'product_cat' ) ) {
$default_product_cat_id = 0;
$default_product_cat_slug = sanitize_title( _x( 'Uncategorized', 'Default category slug', 'woocommerce' ) );
$default_product_cat = get_term_by( 'slug', $default_product_cat_slug, 'product_cat' ); // @codingStandardsIgnoreLine.
if ( $default_product_cat ) {
$default_product_cat_id = absint( $default_product_cat->term_taxonomy_id );
} else {
$result = wp_insert_term( _x( 'Uncategorized', 'Default category slug', 'woocommerce' ), 'product_cat', array( 'slug' => $default_product_cat_slug ) );
if ( ! empty( $result['term_taxonomy_id'] ) ) {
$default_product_cat_id = absint( $result['term_taxonomy_id'] );
}
}
if ( $default_product_cat_id ) {
update_option( 'default_product_cat', $default_product_cat_id );
}
}
}
/**
@ -479,7 +506,7 @@ class WC_Install {
$wpdb->hide_errors();
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
/**
* Before updating with DBDELTA, remove any primary keys which could be
@ -505,7 +532,7 @@ class WC_Install {
/**
* Get Table schema.
*
* https://github.com/woocommerce/woocommerce/wiki/Database-Description/
* See https://github.com/woocommerce/woocommerce/wiki/Database-Description/
*
* A note on indexes; Indexes have a maximum size of 767 bytes. Historically, we haven't need to be concerned about that.
* As of WordPress 4.2, however, we moved to utf8mb4, which uses 4 bytes per character. This means that an index which
@ -713,16 +740,23 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
}
if ( ! isset( $wp_roles ) ) {
$wp_roles = new WP_Roles();
$wp_roles = new WP_Roles(); // @codingStandardsIgnoreLine
}
// Customer role
add_role( 'customer', __( 'Customer', 'woocommerce' ), array(
// Customer role.
add_role(
'customer',
__( 'Customer', 'woocommerce' ),
array(
'read' => true,
) );
)
);
// Shop manager role
add_role( 'shop_manager', __( 'Shop manager', 'woocommerce' ), array(
// Shop manager role.
add_role(
'shop_manager',
__( 'Shop manager', 'woocommerce' ),
array(
'level_9' => true,
'level_8' => true,
'level_7' => true,
@ -762,7 +796,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
'export' => true,
'import' => true,
'list_users' => true,
) );
)
);
$capabilities = self::get_core_capabilities();
@ -792,7 +827,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
foreach ( $capability_types as $capability_type ) {
$capabilities[ $capability_type ] = array(
// Post type
// Post type.
"edit_{$capability_type}",
"read_{$capability_type}",
"delete_{$capability_type}",
@ -807,7 +842,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
"edit_private_{$capability_type}s",
"edit_published_{$capability_type}s",
// Terms
// Terms.
"manage_{$capability_type}_terms",
"edit_{$capability_type}_terms",
"delete_{$capability_type}_terms",
@ -819,7 +854,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
}
/**
* woocommerce_remove_roles function.
* Remove WooCommerce roles.
*/
public static function remove_roles() {
global $wp_roles;
@ -829,7 +864,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
}
if ( ! isset( $wp_roles ) ) {
$wp_roles = new WP_Roles();
$wp_roles = new WP_Roles(); // @codingStandardsIgnoreLine
}
$capabilities = self::get_core_capabilities();
@ -849,12 +884,12 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
* Create files/directories.
*/
private static function create_files() {
// Bypass if filesystem is read-only and/or non-standard upload system is used
// Bypass if filesystem is read-only and/or non-standard upload system is used.
if ( apply_filters( 'woocommerce_install_skip_create_files', false ) ) {
return;
}
// Install files and folders for uploading files and prevent hotlinking
// Install files and folders for uploading files and prevent hotlinking.
$upload_dir = wp_upload_dir();
$download_method = get_option( 'woocommerce_file_download_method', 'force' );
@ -886,7 +921,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
foreach ( $files as $file ) {
if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
if ( $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ) ) {
$file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' );
if ( $file_handle ) {
fwrite( $file_handle, $file['content'] );
fclose( $file_handle );
}
@ -897,7 +933,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/**
* Show action links on the plugin screen.
*
* @param mixed $links Plugin Action links
* @param mixed $links Plugin Action links.
* @return array
*/
public static function plugin_action_links( $links ) {
@ -911,8 +947,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/**
* Show row meta on the plugin screen.
*
* @param mixed $links Plugin Row Meta
* @param mixed $file Plugin Base file
* @param mixed $links Plugin Row Meta.
* @param mixed $file Plugin Base file.
* @return array
*/
public static function plugin_row_meta( $links, $file ) {
@ -931,7 +967,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/**
* Uninstall tables when MU blog is deleted.
* @param array $tables
*
* @param array $tables List of tables that will be deleted by WP.
* @return string[]
*/
public static function wpmu_drop_tables( $tables ) {
@ -956,7 +993,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/**
* Get slug from path
* @param string $key
*
* @param string $key Plugin relative path. Example: woocommerce/woocommerce.php.
* @return string
*/
private static function format_plugin_slug( $key ) {
@ -968,8 +1006,10 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/**
* Install a plugin from .org in the background via a cron job (used by
* installer - opt in).
* @param string $plugin_to_install_id
* @param array $plugin_to_install
*
* @param string $plugin_to_install_id Plugin ID.
* @param array $plugin_to_install Plugin information.
* @throws Exception If unable to proceed with plugin installation.
* @since 2.6.0
*/
public static function background_installer( $plugin_to_install_id, $plugin_to_install ) {
@ -977,14 +1017,14 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
wp_clear_scheduled_hook( 'woocommerce_plugin_background_installer', func_get_args() );
if ( ! empty( $plugin_to_install['repo-slug'] ) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
require_once ABSPATH . 'wp-admin/includes/plugin.php';
WP_Filesystem();
$skin = new Automatic_Upgrader_Skin;
$skin = new Automatic_Upgrader_Skin();
$upgrader = new WP_Upgrader( $skin );
$installed_plugins = array_map( array( __CLASS__, 'format_plugin_slug' ), array_keys( get_plugins() ) );
$plugin_slug = $plugin_to_install['repo-slug'];
@ -992,7 +1032,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
$installed = false;
$activate = false;
// See if the plugin is installed already
// See if the plugin is installed already.
if ( in_array( $plugin_to_install['repo-slug'], $installed_plugins ) ) {
$installed = true;
$activate = ! is_plugin_active( $plugin );
@ -1000,11 +1040,13 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
// Install this thing!
if ( ! $installed ) {
// Suppress feedback
// Suppress feedback.
ob_start();
try {
$plugin_information = plugins_api( 'plugin_information', array(
$plugin_information = plugins_api(
'plugin_information',
array(
'slug' => $plugin_to_install['repo-slug'],
'fields' => array(
'short_description' => false,
@ -1021,7 +1063,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
'author_profile' => false,
'author' => false,
),
) );
)
);
if ( is_wp_error( $plugin_information ) ) {
throw new Exception( $plugin_information->get_error_message() );
@ -1040,7 +1083,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
throw new Exception( $working_dir->get_error_message() );
}
$result = $upgrader->install_package( array(
$result = $upgrader->install_package(
array(
'source' => $working_dir,
'destination' => WP_PLUGIN_DIR,
'clear_destination' => false,
@ -1050,7 +1094,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
'type' => 'plugin',
'action' => 'install',
),
) );
)
);
if ( is_wp_error( $result ) ) {
throw new Exception( $result->get_error_message() );
@ -1062,6 +1107,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
WC_Admin_Notices::add_custom_notice(
$plugin_to_install_id . '_install_error',
sprintf(
// translators: 1: plugin name, 2: error message, 3: URL to install plugin manually.
__( '%1$s could not be installed (%2$s). <a href="%3$s">Please install it manually by clicking here.</a>', 'woocommerce' ),
$plugin_to_install['name'],
$e->getMessage(),
@ -1070,13 +1116,13 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
);
}
// Discard feedback
// Discard feedback.
ob_end_clean();
}
wp_clean_plugins_cache();
// Activate this thing
// Activate this thing.
if ( $activate ) {
try {
$result = activate_plugin( $plugin );
@ -1088,6 +1134,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
WC_Admin_Notices::add_custom_notice(
$plugin_to_install_id . '_install_error',
sprintf(
// translators: 1: plugin name, 2: URL to WP plugin page.
__( '%1$s was installed but could not be activated. <a href="%2$s">Please activate it manually by clicking here.</a>', 'woocommerce' ),
$plugin_to_install['name'],
admin_url( 'plugins.php' )
@ -1101,7 +1148,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/**
* Install a theme from .org in the background via a cron job (used by installer - opt in).
*
* @param string $theme_slug
* @param string $theme_slug Theme slug.
* @throws Exception If unable to proceed with theme installation.
* @since 3.1.0
*/
public static function theme_background_installer( $theme_slug ) {
@ -1109,25 +1157,27 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
wp_clear_scheduled_hook( 'woocommerce_theme_background_installer', func_get_args() );
if ( ! empty( $theme_slug ) ) {
// Suppress feedback
// Suppress feedback.
ob_start();
try {
$theme = wp_get_theme( $theme_slug );
if ( ! $theme->exists() ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
include_once( ABSPATH . 'wp-admin/includes/theme.php' );
require_once ABSPATH . 'wp-admin/includes/file.php';
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
include_once ABSPATH . 'wp-admin/includes/theme.php';
WP_Filesystem();
$skin = new Automatic_Upgrader_Skin;
$skin = new Automatic_Upgrader_Skin();
$upgrader = new Theme_Upgrader( $skin );
$api = themes_api( 'theme_information', array(
$api = themes_api(
'theme_information', array(
'slug' => $theme_slug,
'fields' => array( 'sections' => false ),
) );
)
);
$result = $upgrader->install( $api->download_link );
if ( is_wp_error( $result ) ) {
@ -1144,6 +1194,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
WC_Admin_Notices::add_custom_notice(
$theme_slug . '_install_error',
sprintf(
// translators: 1: theme slug, 2: error message, 3: URL to install theme manually.
__( '%1$s could not be installed (%2$s). <a href="%3$s">Please install it manually by clicking here.</a>', 'woocommerce' ),
$theme_slug,
$e->getMessage(),
@ -1152,7 +1203,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
);
}
// Discard feedback
// Discard feedback.
ob_end_clean();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@ class WC_Post_Data {
add_filter( 'post_type_link', array( __CLASS__, 'variation_post_link' ), 10, 2 );
add_action( 'shutdown', array( __CLASS__, 'do_deferred_product_sync' ), 10 );
add_action( 'set_object_terms', array( __CLASS__, 'set_object_terms' ), 10, 6 );
add_action( 'set_object_terms', array( __CLASS__, 'force_default_term' ), 10, 5 );
add_action( 'transition_post_status', array( __CLASS__, 'transition_post_status' ), 10, 3 );
add_action( 'woocommerce_product_set_stock_status', array( __CLASS__, 'delete_product_query_transients' ) );
@ -500,6 +501,27 @@ class WC_Post_Data {
public static function flush_object_meta_cache( $meta_id, $object_id, $meta_key, $meta_value ) {
WC_Cache_Helper::incr_cache_prefix( 'object_' . $object_id );
}
/**
* Ensure default category gets set.
*
* @since 3.3.0
* @param int $object_id Product ID.
* @param array $terms Terms array.
* @param array $tt_ids Term ids array.
* @param string $taxonomy Taxonomy name.
* @param bool $append Are we appending or setting terms.
*/
public static function force_default_term( $object_id, $terms, $tt_ids, $taxonomy, $append ) {
if ( ! $append && 'product_cat' === $taxonomy && empty( $tt_ids ) && 'product' === get_post_type( $object_id ) ) {
$default_term = absint( get_option( 'default_product_cat', 0 ) );
$tt_ids = array_map( 'absint', $tt_ids );
if ( $default_term && ! in_array( $default_term, $tt_ids, true ) ) {
wp_set_post_terms( $object_id, array( $default_term ), 'product_cat', true );
}
}
}
}
WC_Post_Data::init();

View File

@ -29,6 +29,7 @@ class WC_Post_types {
add_action( 'init', array( __CLASS__, 'register_post_status' ), 9 );
add_action( 'init', array( __CLASS__, 'support_jetpack_omnisearch' ) );
add_filter( 'rest_api_allowed_post_types', array( __CLASS__, 'rest_api_allowed_post_types' ) );
add_action( 'woocommerce_after_register_post_type', array( __CLASS__, 'maybe_flush_rewrite_rules' ) );
add_action( 'woocommerce_flush_rewrite_rules', array( __CLASS__, 'flush_rewrite_rules' ) );
}
@ -529,6 +530,18 @@ class WC_Post_types {
}
}
/**
* Flush rules if the event is queued.
*
* @since 3.3.0
*/
public static function maybe_flush_rewrite_rules() {
if ( 'true' === get_option( 'woocommerce_queue_flush_rewrite_rules' ) ) {
delete_option( 'woocommerce_queue_flush_rewrite_rules' );
self::flush_rewrite_rules();
}
}
/**
* Flush rewrite rules.
*/

View File

@ -42,6 +42,7 @@ class WC_Query {
add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
add_action( 'wp', array( $this, 'remove_product_query' ) );
add_action( 'wp', array( $this, 'remove_ordering_args' ) );
add_filter( 'get_pagenum_link', array( $this, 'remove_add_to_cart_pagination' ), 10, 1 );
}
$this->init_query_vars();
}
@ -840,4 +841,14 @@ class WC_Query {
public function layered_nav_query( $deprecated ) {
wc_deprecated_function( 'layered_nav_query', '2.6' );
}
/**
* Remove the add-to-cart param from pagination urls.
*
* @param string $url URL.
* @return string
*/
public function remove_add_to_cart_pagination( $url ) {
return remove_query_arg( 'add-to-cart', $url );
}
}

View File

@ -66,13 +66,14 @@ class WC_Regenerate_Images {
$size_settings = wc_get_image_size( $size );
if ( isset( $imagemeta['sizes'], $imagemeta['sizes'][ $size ] ) ) {
if ( in_array( $size, array( 'woocommerce_thumbnail' ), true ) && isset( $imagemeta['sizes'], $imagemeta['sizes'][ $size ] ) ) {
if ( $imagemeta['sizes'][ $size ]['width'] !== $size_settings['width'] || $imagemeta['sizes'][ $size ]['height'] !== $size_settings['height'] ) {
$image = self::resize_and_return_image( $attachment_id, $image, $size, $icon );
}
} else {
$image = self::resize_and_return_image( $attachment_id, $image, $size, $icon );
}
return $image;
}

View File

@ -87,6 +87,10 @@ class WC_Validation {
case 'PL':
$valid = (bool) preg_match( '/^([0-9]{2})([-])([0-9]{3})$/', $postcode );
break;
case 'CZ':
case 'SK':
$valid = (bool) preg_match( '/^([0-9]{3})(\s?)([0-9]{2})$/', $postcode );
break;
default :
$valid = true;

View File

@ -773,7 +773,12 @@ class WC_Webhook {
break;
}
$prev_post_status = $this->get_status();
$wpdb->update( $wpdb->posts, array( 'post_status' => $post_status ), array( 'ID' => $this->id ) );
do_action( 'woocommerce_webhook_updated_status', $this->id, $post_status, $prev_post_status );
clean_post_cache( $this->id );
}

View File

@ -1,4 +1,10 @@
<?php
/**
* Abstract_WC_Order_Data_Store_CPT class file.
*
* @package WooCommerce/Classes
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -46,14 +52,18 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/**
* Method to create a new order in the database.
* @param WC_Order $order
*
* @param WC_Order $order Order object.
*/
public function create( &$order ) {
$order->set_version( WC_VERSION );
$order->set_date_created( current_time( 'timestamp', true ) );
$order->set_currency( $order->get_currency() ? $order->get_currency() : get_woocommerce_currency() );
$id = wp_insert_post( apply_filters( 'woocommerce_new_order_data', array(
$id = wp_insert_post(
apply_filters(
'woocommerce_new_order_data',
array(
'post_date' => gmdate( 'Y-m-d H:i:s', $order->get_date_created( 'edit' )->getOffsetTimestamp() ),
'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $order->get_date_created( 'edit' )->getTimestamp() ),
'post_type' => $order->get_type( 'edit' ),
@ -64,7 +74,9 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
'post_password' => uniqid( 'order_' ),
'post_parent' => $order->get_parent_id( 'edit' ),
'post_excerpt' => $this->get_post_excerpt( $order ),
) ), true );
)
), true
);
if ( $id && ! is_wp_error( $id ) ) {
$order->set_id( $id );
@ -78,23 +90,26 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/**
* Method to read an order from the database.
*
* @param WC_Data $order
* @param WC_Data $order Order object.
*
* @throws Exception
* @throws Exception If passed order is invalid.
*/
public function read( &$order ) {
$order->set_defaults();
$post_object = get_post( $order->get_id() );
if ( ! $order->get_id() || ! ( $post_object = get_post( $order->get_id() ) ) || ! in_array( $post_object->post_type, wc_get_order_types() ) ) {
if ( ! $order->get_id() || ! $post_object || ! in_array( $post_object->post_type, wc_get_order_types() ) ) {
throw new Exception( __( 'Invalid order.', 'woocommerce' ) );
}
$order->set_props( array(
$order->set_props(
array(
'parent_id' => $post_object->post_parent,
'date_created' => 0 < $post_object->post_date_gmt ? wc_string_to_timestamp( $post_object->post_date_gmt ) : null,
'date_modified' => 0 < $post_object->post_modified_gmt ? wc_string_to_timestamp( $post_object->post_modified_gmt ) : null,
'status' => $post_object->post_status,
) );
)
);
$this->read_order_data( $order, $post_object );
$order->read_meta_data();
@ -112,7 +127,8 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/**
* Method to update an order in the database.
* @param WC_Order $order
*
* @param WC_Order $order Order object.
*/
public function update( &$order ) {
$order->save_meta_data();
@ -155,14 +171,20 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/**
* Method to delete an order from the database.
* @param WC_Order $order
*
* @param WC_Order $order Order object.
* @param array $args Array of args to pass to the delete method.
*
* @return void
*/
public function delete( &$order, $args = array() ) {
$id = $order->get_id();
$args = wp_parse_args( $args, array(
$args = wp_parse_args(
$args,
array(
'force_delete' => false,
) );
)
);
if ( ! $id ) {
return;
@ -188,7 +210,7 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/**
* Excerpt for post.
*
* @param WC_order $order
* @param WC_order $order Order object.
* @return string
*/
protected function get_post_excerpt( $order ) {
@ -210,14 +232,15 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/**
* Read order data. Can be overridden by child classes to load other props.
*
* @param WC_Order $order
* @param object $post_object
* @param WC_Order $order Order object.
* @param object $post_object Post object.
* @since 3.0.0
*/
protected function read_order_data( &$order, $post_object ) {
$id = $order->get_id();
$order->set_props( array(
$order->set_props(
array(
'currency' => get_post_meta( $id, '_order_currency', true ),
'discount_total' => get_post_meta( $id, '_cart_discount', true ),
'discount_tax' => get_post_meta( $id, '_cart_discount_tax', true ),
@ -227,7 +250,8 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
'total' => get_post_meta( $id, '_order_total', true ),
'version' => get_post_meta( $id, '_order_version', true ),
'prices_include_tax' => metadata_exists( 'post', $id, '_prices_include_tax' ) ? 'yes' === get_post_meta( $id, '_prices_include_tax', true ) : 'yes' === get_option( 'woocommerce_prices_include_tax' ),
) );
)
);
// Gets extra data associated with the order if needed.
foreach ( $order->get_extra_data_keys() as $key ) {
@ -241,7 +265,7 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/**
* Helper method that updates all the post meta for an order based on it's settings in the WC_Order class.
*
* @param $order WC_Order
* @param WC_Order $order Order object.
* @since 3.0.0
*/
protected function update_post_meta( &$order ) {
@ -278,7 +302,7 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/**
* Clear any caches.
*
* @param WC_Order $order
* @param WC_Order $order Order object.
* @since 3.0.0
*/
protected function clear_caches( &$order ) {
@ -290,8 +314,8 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/**
* Read order items of a specific type from the database for this order.
*
* @param WC_Order $order
* @param string $type
* @param WC_Order $order Order object.
* @param string $type Order item type.
* @return array
*/
public function read_items( $order, $type ) {
@ -301,8 +325,9 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
$items = wp_cache_get( 'order-items-' . $order->get_id(), 'orders' );
if ( false === $items ) {
$get_items_sql = $wpdb->prepare( "SELECT order_item_type, order_item_id, order_id, order_item_name FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d ORDER BY order_item_id;", $order->get_id() );
$items = $wpdb->get_results( $get_items_sql );
$items = $wpdb->get_results(
$wpdb->prepare( "SELECT order_item_type, order_item_id, order_id, order_item_name FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d ORDER BY order_item_id;", $order->get_id() )
);
foreach ( $items as $item ) {
wp_cache_set( 'item-' . $item->order_item_id, $item, 'order-items' );
}
@ -323,7 +348,7 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/**
* Remove all line items (products, coupons, shipping, taxes) from the order.
*
* @param WC_Order $order
* @param WC_Order $order Order object.
* @param string $type Order item type. Default null.
*/
public function delete_items( $order, $type = null ) {
@ -341,7 +366,7 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/**
* Get token ids for an order.
*
* @param WC_Order $order
* @param WC_Order $order Order object.
* @return array
*/
public function get_payment_token_ids( $order ) {
@ -352,8 +377,8 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/**
* Update token ids for an order.
*
* @param WC_Order $order
* @param array $token_ids
* @param WC_Order $order Order object.
* @param array $token_ids Payment token ids.
*/
public function update_payment_token_ids( $order, $token_ids ) {
update_post_meta( $order->get_id(), '_payment_tokens', $token_ids );

View File

@ -1,4 +1,10 @@
<?php
/**
* WC_Order_Data_Store_CPT class file.
*
* @package WooCommerce/Classes
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -14,6 +20,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Data stored in meta keys, but not considered "meta" for an order.
*
* @since 3.0.0
* @var array
*/
@ -70,7 +77,8 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Method to create a new order in the database.
* @param WC_Order $order
*
* @param WC_Order $order Order object.
*/
public function create( &$order ) {
$order->set_order_key( 'wc_' . apply_filters( 'woocommerce_generate_order_key', uniqid( 'order_' ) ) );
@ -81,8 +89,8 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Read order data. Can be overridden by child classes to load other props.
*
* @param WC_Order $order
* @param object $post_object
* @param WC_Order $order Order object.
* @param object $post_object Post object.
* @since 3.0.0
*/
protected function read_order_data( &$order, $post_object ) {
@ -99,7 +107,8 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
$date_paid = get_post_meta( $id, '_paid_date', true );
}
$order->set_props( array(
$order->set_props(
array(
'order_key' => get_post_meta( $id, '_order_key', true ),
'customer_id' => get_post_meta( $id, '_customer_user', true ),
'billing_first_name' => get_post_meta( $id, '_billing_first_name', true ),
@ -132,12 +141,14 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
'date_paid' => $date_paid,
'cart_hash' => get_post_meta( $id, '_cart_hash', true ),
'customer_note' => $post_object->post_excerpt,
) );
)
);
}
/**
* Method to update an order in the database.
* @param WC_Order $order
*
* @param WC_Order $order Order object.
*/
public function update( &$order ) {
// Before updating, ensure date paid is set if missing.
@ -154,7 +165,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Helper method that updates all the post meta for an order based on it's settings in the WC_Order class.
*
* @param WC_Order $order
* @param WC_Order $order Order object.
* @since 3.0.0
*/
protected function update_post_meta( &$order ) {
@ -259,7 +270,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Excerpt for post.
*
* @param WC_Order $order
* @param WC_Order $order Order object.
* @return string
*/
protected function get_post_excerpt( $order ) {
@ -269,19 +280,22 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Get amount already refunded.
*
* @param WC_Order $order
* @param WC_Order $order Order object.
* @return string
*/
public function get_total_refunded( $order ) {
global $wpdb;
$total = $wpdb->get_var( $wpdb->prepare( "
SELECT SUM( postmeta.meta_value )
$total = $wpdb->get_var(
$wpdb->prepare(
"SELECT SUM( postmeta.meta_value )
FROM $wpdb->postmeta AS postmeta
INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )
WHERE postmeta.meta_key = '_refund_amount'
AND postmeta.post_id = posts.ID
", $order->get_id() ) );
AND postmeta.post_id = posts.ID",
$order->get_id()
)
);
return $total;
}
@ -289,20 +303,23 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Get the total tax refunded.
*
* @param WC_Order $order
* @param WC_Order $order Order object.
* @return float
*/
public function get_total_tax_refunded( $order ) {
global $wpdb;
$total = $wpdb->get_var( $wpdb->prepare( "
SELECT SUM( order_itemmeta.meta_value )
$total = $wpdb->get_var(
$wpdb->prepare(
"SELECT SUM( order_itemmeta.meta_value )
FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta
INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'tax' )
WHERE order_itemmeta.order_item_id = order_items.order_item_id
AND order_itemmeta.meta_key IN ('tax_amount', 'shipping_tax_amount')
", $order->get_id() ) );
AND order_itemmeta.meta_key IN ('tax_amount', 'shipping_tax_amount')",
$order->get_id()
)
);
return abs( $total );
}
@ -310,20 +327,23 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Get the total shipping refunded.
*
* @param WC_Order $order
* @param WC_Order $order Order object.
* @return float
*/
public function get_total_shipping_refunded( $order ) {
global $wpdb;
$total = $wpdb->get_var( $wpdb->prepare( "
SELECT SUM( order_itemmeta.meta_value )
$total = $wpdb->get_var(
$wpdb->prepare(
"SELECT SUM( order_itemmeta.meta_value )
FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta
INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'shipping' )
WHERE order_itemmeta.order_item_id = order_items.order_item_id
AND order_itemmeta.meta_key IN ('cost')
", $order->get_id() ) );
AND order_itemmeta.meta_key IN ('cost')",
$order->get_id()
)
);
return abs( $total );
}
@ -331,7 +351,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Finds an Order ID based on an order key.
*
* @param string $order_key An order key has generated by
* @param string $order_key An order key has generated by.
* @return int The ID of an order, or 0 if the order could not be found
*/
public function get_order_id_by_order_key( $order_key ) {
@ -342,7 +362,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Return count of orders with a specific status.
*
* @param string $status
* @param string $status Order status. Function wc_get_order_statuses() returns a list of valid statuses.
* @return int
*/
public function get_order_count( $status ) {
@ -356,7 +376,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
* @deprecated 3.1.0 - Use wc_get_orders instead.
* @see wc_get_orders()
*
* @param array $args
* @param array $args List of args passed to wc_get_orders().
*
* @return array|object
*/
@ -368,8 +388,8 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Generate meta query for wc_get_orders.
*
* @param array $values
* @param string $relation
* @param array $values List of customers ids or emails.
* @param string $relation 'or' or 'and' relation used to build the WP meta_query.
* @return array
*/
private function get_orders_generate_customer_meta_query( $values, $relation = 'or' ) {
@ -418,19 +438,24 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Get unpaid orders after a certain date,
*
* @param int $date timestamp
* @param int $date Timestamp.
* @return array
*/
public function get_unpaid_orders( $date ) {
global $wpdb;
$unpaid_orders = $wpdb->get_col( $wpdb->prepare( "
SELECT posts.ID
$unpaid_orders = $wpdb->get_col(
$wpdb->prepare(
// @codingStandardsIgnoreStart
"SELECT posts.ID
FROM {$wpdb->posts} AS posts
WHERE posts.post_type IN ('" . implode( "','", wc_get_order_types() ) . "')
AND posts.post_status = 'wc-pending'
AND posts.post_modified < %s
", date( 'Y-m-d H:i:s', absint( $date ) ) ) );
AND posts.post_modified < %s",
// @codingStandardsIgnoreEnd
date( 'Y-m-d H:i:s', absint( $date ) )
)
);
return $unpaid_orders;
}
@ -438,7 +463,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Search order data for a term and return ids.
*
* @param string $term
* @param string $term Searched term.
* @return array of ids
*/
public function search_orders( $term ) {
@ -448,14 +473,19 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
* Searches on meta data can be slow - this lets you choose what fields to search.
* 3.0.0 added _billing_address and _shipping_address meta which contains all address data to make this faster.
* This however won't work on older orders unless updated, so search a few others (expand this using the filter if needed).
*
* @var array
*/
$search_fields = array_map( 'wc_clean', apply_filters( 'woocommerce_shop_order_search_fields', array(
$search_fields = array_map(
'wc_clean', apply_filters(
'woocommerce_shop_order_search_fields', array(
'_billing_address_index',
'_shipping_address_index',
'_billing_last_name',
'_billing_email',
) ) );
)
)
);
$order_ids = array();
if ( is_numeric( $term ) ) {
@ -463,21 +493,25 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
}
if ( ! empty( $search_fields ) ) {
$order_ids = array_unique( array_merge(
$order_ids = array_unique(
array_merge(
$order_ids,
$wpdb->get_col(
$wpdb->prepare( "SELECT DISTINCT p1.post_id FROM {$wpdb->postmeta} p1 WHERE p1.meta_value LIKE '%%%s%%'", $wpdb->esc_like( wc_clean( $term ) ) ) . " AND p1.meta_key IN ('" . implode( "','", array_map( 'esc_sql', $search_fields ) ) . "')"
$wpdb->prepare(
"SELECT DISTINCT p1.post_id FROM {$wpdb->postmeta} p1 WHERE p1.meta_value LIKE %s AND p1.meta_key IN ('" . implode( "','", array_map( 'esc_sql', $search_fields ) ) . "')", // @codingStandardsIgnoreLine
'%' . $wpdb->esc_like( wc_clean( $term ) ) . '%'
)
),
$wpdb->get_col(
$wpdb->prepare( "
SELECT order_id
$wpdb->prepare(
"SELECT order_id
FROM {$wpdb->prefix}woocommerce_order_items as order_items
WHERE order_item_name LIKE '%%%s%%'
",
$wpdb->esc_like( wc_clean( $term ) )
WHERE order_item_name LIKE %s",
'%' . $wpdb->esc_like( wc_clean( $term ) ) . '%'
)
)
) );
)
);
}
return apply_filters( 'woocommerce_shop_order_search_results', $order_ids, $term, $search_fields );
@ -486,7 +520,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Gets information about whether permissions were generated yet.
*
* @param WC_Order|int $order
* @param WC_Order|int $order Order ID or order object.
* @return bool
*/
public function get_download_permissions_granted( $order ) {
@ -497,8 +531,8 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Stores information about whether permissions were generated yet.
*
* @param WC_Order|int $order
* @param bool $set
* @param WC_Order|int $order Order ID or order object.
* @param bool $set True or false.
*/
public function set_download_permissions_granted( $order, $set ) {
$order_id = WC_Order_Factory::get_order_id( $order );
@ -508,7 +542,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Gets information about whether sales were recorded.
*
* @param WC_Order|int $order
* @param WC_Order|int $order Order ID or order object.
* @return bool
*/
public function get_recorded_sales( $order ) {
@ -519,8 +553,8 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Stores information about whether sales were recorded.
*
* @param WC_Order|int $order
* @param bool $set
* @param WC_Order|int $order Order ID or order object.
* @param bool $set True or false.
*/
public function set_recorded_sales( $order, $set ) {
$order_id = WC_Order_Factory::get_order_id( $order );
@ -530,7 +564,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Gets information about whether coupon counts were updated.
*
* @param WC_Order|int $order
* @param WC_Order|int $order Order ID or order object.
* @return bool
*/
public function get_recorded_coupon_usage_counts( $order ) {
@ -541,8 +575,8 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Stores information about whether coupon counts were updated.
*
* @param WC_Order|int $order
* @param bool $set
* @param WC_Order|int $order Order ID or order object.
* @param bool $set True or false.
*/
public function set_recorded_coupon_usage_counts( $order, $set ) {
$order_id = WC_Order_Factory::get_order_id( $order );
@ -552,7 +586,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Gets information about whether stock was reduced.
*
* @param WC_Order|int $order
* @param WC_Order|int $order Order ID or order object.
* @return bool
*/
public function get_stock_reduced( $order ) {
@ -563,8 +597,8 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/**
* Stores information about whether stock was reduced.
*
* @param WC_Order|int $order
* @param bool $set
* @param WC_Order|int $order Order ID or order object.
* @param bool $set True or false.
*/
public function set_stock_reduced( $order, $set ) {
$order_id = WC_Order_Factory::get_order_id( $order );
@ -575,7 +609,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
* Get the order type based on Order ID.
*
* @since 3.0.0
* @param int $order_id
* @param int $order_id Order ID.
* @return string
*/
public function get_order_type( $order_id ) {
@ -586,7 +620,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
* Get valid WP_Query args from a WC_Order_Query's query variables.
*
* @since 3.1.0
* @param array $query_vars query vars from a WC_Order_Query
* @param array $query_vars query vars from a WC_Order_Query.
* @return array
*/
protected function get_wp_query_args( $query_vars ) {
@ -675,7 +709,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
*
* @since 3.1.0
*
* @param array $query_vars query vars from a WC_Order_Query
* @param array $query_vars query vars from a WC_Order_Query.
*
* @return array|object
*/

View File

@ -585,15 +585,21 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
/**
* For all stored terms in all taxonomies, save them to the DB.
*
* @param WC_Product
* @param bool Force update. Used during create.
* @param WC_Product $product Product object.
* @param bool $force Force update. Used during create.
* @since 3.0.0
*/
protected function update_terms( &$product, $force = false ) {
$changes = $product->get_changes();
if ( $force || array_key_exists( 'category_ids', $changes ) ) {
wp_set_post_terms( $product->get_id(), $product->get_category_ids( 'edit' ), 'product_cat', false );
$categories = $product->get_category_ids( 'edit' );
if ( empty( $categories ) && get_option( 'default_product_cat', 0 ) ) {
$categories = array( get_option( 'default_product_cat', 0 ) );
}
wp_set_post_terms( $product->get_id(), $categories, 'product_cat', false );
}
if ( $force || array_key_exists( 'tag_ids', $changes ) ) {
wp_set_post_terms( $product->get_id(), $product->get_tag_ids( 'edit' ), 'product_tag', false );

View File

@ -342,8 +342,12 @@ class WC_Gateway_BACS extends WC_Payment_Gateway {
$order = wc_get_order( $order_id );
if ( $order->get_total() > 0 ) {
// Mark as on-hold (we're awaiting the payment)
$order->update_status( 'on-hold', __( 'Awaiting BACS payment', 'woocommerce' ) );
} else {
$order->payment_complete();
}
// Reduce stock levels
wc_reduce_stock_levels( $order_id );

View File

@ -113,8 +113,12 @@ class WC_Gateway_Cheque extends WC_Payment_Gateway {
$order = wc_get_order( $order_id );
if ( $order->get_total() > 0 ) {
// Mark as on-hold (we're awaiting the cheque)
$order->update_status( 'on-hold', _x( 'Awaiting check payment', 'Check payment method', 'woocommerce' ) );
} else {
$order->payment_complete();
}
// Reduce stock levels
wc_reduce_stock_levels( $order_id );

View File

@ -178,8 +178,12 @@ class WC_Gateway_COD extends WC_Payment_Gateway {
public function process_payment( $order_id ) {
$order = wc_get_order( $order_id );
if ( $order->get_total() > 0 ) {
// Mark as processing or on-hold (payment won't be taken until delivery)
$order->update_status( apply_filters( 'woocommerce_cod_process_payment_order_status', $order->has_downloadable_item() ? 'on-hold' : 'processing', $order ), __( 'Payment to be made upon delivery.', 'woocommerce' ) );
} else {
$order->payment_complete();
}
// Reduce stock levels
wc_reduce_stock_levels( $order_id );

View File

@ -503,7 +503,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
* @param int $product_id Product ID.
* @return int
*/
protected function get_attachment_id_from_url( $url, $product_id ) {
public function get_attachment_id_from_url( $url, $product_id ) {
if ( empty( $url ) ) {
return 0;
}
@ -590,7 +590,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
* @param string $name Attribute name.
* @return int
*/
protected function get_attribute_taxonomy_id( $raw_name ) {
public function get_attribute_taxonomy_id( $raw_name ) {
global $wpdb, $wc_product_attributes;
// These are exported as labels, so convert the label to a name if possible first.

View File

@ -128,23 +128,23 @@ class WC_Legacy_API {
public function includes() {
// API server / response handlers.
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-exception.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-server.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/interface-wc-api-handler.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-json-handler.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v3/class-wc-api-exception.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v3/class-wc-api-server.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v3/interface-wc-api-handler.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v3/class-wc-api-json-handler.php' );
// Authentication.
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-authentication.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v3/class-wc-api-authentication.php' );
$this->authentication = new WC_API_Authentication();
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-resource.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-coupons.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-customers.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-orders.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-products.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-reports.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-taxes.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-webhooks.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v3/class-wc-api-resource.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v3/class-wc-api-coupons.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v3/class-wc-api-customers.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v3/class-wc-api-orders.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v3/class-wc-api-products.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v3/class-wc-api-reports.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v3/class-wc-api-taxes.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v3/class-wc-api-webhooks.php' );
// Allow plugins to load other response handlers or resource classes.
do_action( 'woocommerce_api_loaded' );
@ -186,20 +186,20 @@ class WC_Legacy_API {
private function handle_v1_rest_api_request() {
// Include legacy required files for v1 REST API request.
include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-server.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v1/interface-wc-api-handler.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-json-handler.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-xml-handler.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v1/class-wc-api-server.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v1/interface-wc-api-handler.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v1/class-wc-api-json-handler.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v1/class-wc-api-xml-handler.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-authentication.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v1/class-wc-api-authentication.php' );
$this->authentication = new WC_API_Authentication();
include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-resource.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-coupons.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-customers.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-orders.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-products.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-reports.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v1/class-wc-api-resource.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v1/class-wc-api-coupons.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v1/class-wc-api-customers.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v1/class-wc-api-orders.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v1/class-wc-api-products.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v1/class-wc-api-reports.php' );
// Allow plugins to load other response handlers or resource classes.
do_action( 'woocommerce_api_loaded' );
@ -232,21 +232,21 @@ class WC_Legacy_API {
* @deprecated 2.6.0
*/
private function handle_v2_rest_api_request() {
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-exception.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-server.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/interface-wc-api-handler.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-json-handler.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v2/class-wc-api-exception.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v2/class-wc-api-server.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v2/interface-wc-api-handler.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v2/class-wc-api-json-handler.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-authentication.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v2/class-wc-api-authentication.php' );
$this->authentication = new WC_API_Authentication();
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-resource.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-coupons.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-customers.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-orders.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-products.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-reports.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-webhooks.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v2/class-wc-api-resource.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v2/class-wc-api-coupons.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v2/class-wc-api-customers.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v2/class-wc-api-orders.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v2/class-wc-api-products.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v2/class-wc-api-reports.php' );
include_once( dirname( __FILE__ ) . '/../api/legacy/v2/class-wc-api-webhooks.php' );
// allow plugins to load other response handlers or resource classes.
do_action( 'woocommerce_api_loaded' );

View File

@ -266,9 +266,7 @@ class WC_Shortcode_Products {
$ordering_args = WC()->query->get_catalog_ordering_args( $query_args['orderby'], $query_args['order'] );
$query_args['orderby'] = $ordering_args['orderby'];
$query_args['order'] = $ordering_args['order'];
// @codingStandardsIgnoreStart
$query_args['meta_key'] = $ordering_args['meta_key'];
// @codingStandardsIgnoreEnd
$query_args['meta_key'] = $ordering_args['meta_key']; // @codingStandardsIgnoreLine
$query_args['tax_query'][] = array(
'taxonomy' => 'product_cat',
@ -296,9 +294,7 @@ class WC_Shortcode_Products {
* @param array $query_args Query args.
*/
protected function set_best_selling_products_query_args( &$query_args ) {
// @codingStandardsIgnoreStart
$query_args['meta_key'] = 'total_sales';
// @codingStandardsIgnoreEnd
$query_args['meta_key'] = 'total_sales'; // @codingStandardsIgnoreLine
$query_args['order'] = 'DESC';
$query_args['orderby'] = 'meta_value_num';
}
@ -515,9 +511,8 @@ class WC_Shortcode_Products {
woocommerce_product_loop_start();
foreach ( $products_ids as $product_id ) {
$post_object = get_post( $product_id );
$GLOBALS['post'] =& $post_object; // WPCS: override ok.
setup_postdata( $post_object );
$GLOBALS['post'] = get_post( $product_id ); // WPCS: override ok.
setup_postdata( $GLOBALS['post'] );
// Set custom product visibility when quering hidden products.
add_action( 'woocommerce_product_is_visible', array( $this, 'set_product_as_visible' ) );

View File

@ -1,188 +0,0 @@
<?php
/**
* Class to validate and to work with IPv6 addresses
*
* @package Requests
* @subpackage Utilities
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class to validate and to work with IPv6 addresses
*
* This was originally based on the PEAR class of the same name, but has been
* entirely rewritten.
*
* @package Requests
* @subpackage Utilities
*/
class Requests_IPv6 {
/**
* Uncompresses an IPv6 address
*
* RFC 4291 allows you to compress consecutive zero pieces in an address to
* '::'. This method expects a valid IPv6 address and expands the '::' to
* the required number of zero pieces.
*
* Example: FF01::101 -> FF01:0:0:0:0:0:0:101
* ::1 -> 0:0:0:0:0:0:0:1
*
* @author Alexander Merz <alexander.merz@web.de>
* @author elfrink at introweb dot nl
* @author Josh Peck <jmp at joshpeck dot org>
* @copyright 2003-2005 The PHP Group
* @license http://www.opensource.org/licenses/bsd-license.php
* @param string $ip An IPv6 address
* @return string The uncompressed IPv6 address
*/
public static function uncompress( $ip ) {
if ( substr_count( $ip, '::' ) !== 1 ) {
return $ip;
}
list($ip1, $ip2) = explode( '::', $ip );
$c1 = ( '' == $ip1 ) ? -1 : substr_count( $ip1, ':' );
$c2 = ( '' == $ip2 ) ? -1 : substr_count( $ip2, ':' );
if ( strpos( $ip2, '.' ) !== false ) {
$c2++;
}
// ::
if ( -1 === $c1 && -1 === $c2 ) {
$ip = '0:0:0:0:0:0:0:0';
} // ::xxx
elseif ( -1 === $c1 ) {
$fill = str_repeat( '0:', 7 - $c2 );
$ip = str_replace( '::', $fill, $ip );
} // xxx::
elseif ( -1 === $c2 ) {
$fill = str_repeat( ':0', 7 - $c1 );
$ip = str_replace( '::', $fill, $ip );
} // xxx::xxx
else {
$fill = ':' . str_repeat( '0:', 6 - $c2 - $c1 );
$ip = str_replace( '::', $fill, $ip );
}
return $ip;
}
/**
* Compresses an IPv6 address
*
* RFC 4291 allows you to compress consecutive zero pieces in an address to
* '::'. This method expects a valid IPv6 address and compresses consecutive
* zero pieces to '::'.
*
* Example: FF01:0:0:0:0:0:0:101 -> FF01::101
* 0:0:0:0:0:0:0:1 -> ::1
*
* @see uncompress()
* @param string $ip An IPv6 address
* @return string The compressed IPv6 address
*/
public static function compress( $ip ) {
// Prepare the IP to be compressed
$ip = self::uncompress( $ip );
$ip_parts = self::split_v6_v4( $ip );
// Replace all leading zeros
$ip_parts[0] = preg_replace( '/(^|:)0+([0-9])/', '\1\2', $ip_parts[0] );
// Find bunches of zeros
if ( preg_match_all( '/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE ) ) {
$max = 0;
$pos = null;
foreach ( $matches[0] as $match ) {
if ( strlen( $match[0] ) > $max ) {
$max = strlen( $match[0] );
$pos = $match[1];
}
}
$ip_parts[0] = substr_replace( $ip_parts[0], '::', $pos, $max );
}
if ( '' !== $ip_parts[1] ) {
return implode( ':', $ip_parts );
} else {
return $ip_parts[0];
}
}
/**
* Splits an IPv6 address into the IPv6 and IPv4 representation parts
*
* RFC 4291 allows you to represent the last two parts of an IPv6 address
* using the standard IPv4 representation
*
* Example: 0:0:0:0:0:0:13.1.68.3
* 0:0:0:0:0:FFFF:129.144.52.38
*
* @param string $ip An IPv6 address
* @return string[] [0] contains the IPv6 represented part, and [1] the IPv4 represented part
*/
protected static function split_v6_v4( $ip ) {
if ( strpos( $ip, '.' ) !== false ) {
$pos = strrpos( $ip, ':' );
$ipv6_part = substr( $ip, 0, $pos );
$ipv4_part = substr( $ip, $pos + 1 );
return array( $ipv6_part, $ipv4_part );
} else {
return array( $ip, '' );
}
}
/**
* Checks an IPv6 address
*
* Checks if the given IP is a valid IPv6 address
*
* @param string $ip An IPv6 address
* @return bool true if $ip is a valid IPv6 address
*/
public static function check_ipv6( $ip ) {
$ip = self::uncompress( $ip );
list($ipv6, $ipv4) = self::split_v6_v4( $ip );
$ipv6 = explode( ':', $ipv6 );
$ipv4 = explode( '.', $ipv4 );
if ( count( $ipv6 ) === 8 && count( $ipv4 ) === 1 || count( $ipv6 ) === 6 && count( $ipv4 ) === 4 ) {
foreach ( $ipv6 as $ipv6_part ) {
// The section can't be empty
if ( '' === $ipv6_part ) {
return false;
}
// Nor can it be over four characters
if ( strlen( $ipv6_part ) > 4 ) {
return false;
}
// Remove leading zeros (this is safe because of the above)
$ipv6_part = ltrim( $ipv6_part, '0' );
if ( '' === $ipv6_part ) {
$ipv6_part = '0';
}
// Check the value is valid
$value = hexdec( $ipv6_part );
if ( dechex( $value ) !== strtolower( $ipv6_part ) || $value < 0 || $value > 0xFFFF ) {
return false;
}
}
if ( count( $ipv4 ) === 4 ) {
foreach ( $ipv4 as $ipv4_part ) {
$value = (int) $ipv4_part;
if ( (string) $value !== $ipv4_part || $value < 0 || $value > 0xFF ) {
return false;
}
}
}
return true;
} else {
return false;
}
}
}

View File

@ -773,7 +773,7 @@ function wc_print_js() {
*/
function wc_setcookie( $name, $value, $expire = 0, $secure = false ) {
if ( ! headers_sent() ) {
setcookie( $name, $value, $expire, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN, $secure );
setcookie( $name, $value, $expire, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN, $secure, apply_filters( 'woocommerce_cookie_httponly', false, $name, $value, $expire, $secure ) );
} elseif ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
headers_sent( $file, $line );
trigger_error( "{$name} cookie cannot be set - headers already sent by {$file} on line {$line}", E_USER_NOTICE );

View File

@ -4,10 +4,10 @@
*
* Where functions come to die.
*
* @author WooThemes
* @author Automattic
* @category Core
* @package WooCommerce/Functions
* @version 2.1.0
* @package WooCommerce\Functions
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -18,16 +18,19 @@ if ( ! defined( 'ABSPATH' ) ) {
* Runs a deprecated action with notice only if used.
*
* @since 3.0.0
* @param string $action
* @param array $args
* @param string $deprecated_in
* @param string $replacement
* @param string $tag The name of the action hook.
* @param array $args Array of additional function arguments to be passed to do_action().
* @param string $version The version of WooCommerce that deprecated the hook.
* @param string $replacement The hook that should have been used.
* @param string $message A message regarding the change.
*/
function wc_do_deprecated_action( $action, $args, $deprecated_in, $replacement ) {
if ( has_action( $action ) ) {
wc_deprecated_function( 'Action: ' . $action, $deprecated_in, $replacement );
do_action_ref_array( $action, $args );
function wc_do_deprecated_action( $tag, $args, $version, $replacement = null, $message = null ) {
if ( ! has_action( $tag ) ) {
return;
}
wc_deprecated_hook( $tag, $version, $replacement, $message );
do_action_ref_array( $tag, $args );
}
/**
@ -51,6 +54,31 @@ function wc_deprecated_function( $function, $version, $replacement = null ) {
// @codingStandardsIgnoreEnd
}
/**
* Wrapper for deprecated hook so we can apply some extra logic.
*
* @since 3.3.0
* @param string $hook The hook that was used.
* @param string $version The version of WordPress that deprecated the hook.
* @param string $replacement The hook that should have been used.
* @param string $message A message regarding the change.
*/
function wc_deprecated_hook( $hook, $version, $replacement = null, $message = null ) {
// @codingStandardsIgnoreStart
if ( is_ajax() ) {
do_action( 'deprecated_hook_run', $hook, $replacement, $version, $message );
$message = empty( $message ) ? '' : ' ' . $message;
$log_string = "{$hook} is deprecated since version {$version}";
$log_string .= $replacement ? "! Use {$replacement} instead." : ' with no alternative available.';
error_log( $log_string . $message );
} else {
_deprecated_hook( $hook, $version, $replacement, $message );
}
// @codingStandardsIgnoreEnd
}
/**
* When catching an exception, this allows us to log it if unexpected.
*

View File

@ -587,6 +587,9 @@ function wc_create_refund( $args = array() ) {
do_action( 'woocommerce_order_refunded', $order->get_id(), $refund->get_id() );
} catch ( Exception $e ) {
if ( isset( $refund ) && is_a( $refund, 'WC_Order_Refund' ) ) {
wp_delete_post( $refund->get_id(), true );
}
return new WP_Error( 'error', $e->getMessage() );
}

View File

@ -484,10 +484,14 @@ function wc_track_product_view() {
$viewed_products = (array) explode( '|', $_COOKIE['woocommerce_recently_viewed'] );
}
if ( ! in_array( $post->ID, $viewed_products ) ) {
$viewed_products[] = $post->ID;
// Unset if already in viewed products list.
$keys = array_flip( $viewed_products );
if ( isset( $keys[ $post->ID ] ) ) {
unset( $viewed_products[ $keys[ $post->ID ] ] );
}
$viewed_products[] = $post->ID;
if ( count( $viewed_products ) > 15 ) {
array_shift( $viewed_products );
}

View File

@ -653,33 +653,45 @@ if ( ! function_exists( 'woocommerce_template_loop_category_title' ) ) {
<?php
}
}
/**
if ( ! function_exists( 'woocommerce_template_loop_product_link_open' ) ) {
/**
* Insert the opening anchor tag for products in the loop.
*/
function woocommerce_template_loop_product_link_open() {
function woocommerce_template_loop_product_link_open() {
echo '<a href="' . esc_url( get_the_permalink() ) . '" class="woocommerce-LoopProduct-link woocommerce-loop-product__link">';
}
/**
* Insert the opening anchor tag for products in the loop.
*/
function woocommerce_template_loop_product_link_close() {
echo '</a>';
}
}
/**
if ( ! function_exists( 'woocommerce_template_loop_product_link_close' ) ) {
/**
* Insert the opening anchor tag for products in the loop.
*/
function woocommerce_template_loop_product_link_close() {
echo '</a>';
}
}
if ( ! function_exists( 'woocommerce_template_loop_category_link_open' ) ) {
/**
* Insert the opening anchor tag for categories in the loop.
*
* @param int|object|string $category Category ID, Object or String.
*/
function woocommerce_template_loop_category_link_open( $category ) {
function woocommerce_template_loop_category_link_open( $category ) {
echo '<a href="' . esc_url( get_term_link( $category, 'product_cat' ) ) . '">';
}
}
/**
if ( ! function_exists( 'woocommerce_template_loop_category_link_close' ) ) {
/**
* Insert the closing anchor tag for categories in the loop.
*/
function woocommerce_template_loop_category_link_close() {
function woocommerce_template_loop_category_link_close() {
echo '</a>';
}
}
if ( ! function_exists( 'woocommerce_taxonomy_archive_description' ) ) {
/**
@ -1939,7 +1951,7 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) {
// Custom attribute handling.
$custom_attributes = array();
$args['custom_attributes'] = array_filter( (array) $args['custom_attributes'] );
$args['custom_attributes'] = array_filter( (array) $args['custom_attributes'], 'strlen' );
if ( $args['maxlength'] ) {
$args['custom_attributes']['maxlength'] = absint( $args['maxlength'] );

View File

@ -64,7 +64,8 @@ function wc_update_200_permalinks() {
if ( 'yes' == get_option( 'woocommerce_prepend_shop_page_to_products' ) ) {
$product_base = trailingslashit( $base_slug );
} else {
if ( ( $product_slug = get_option( 'woocommerce_product_slug' ) ) !== false && ! empty( $product_slug ) ) {
$product_slug = get_option( 'woocommerce_product_slug' );
if ( false !== $product_slug && ! empty( $product_slug ) ) {
$product_base = trailingslashit( $product_slug );
} else {
$product_base = trailingslashit( _x( 'product', 'slug', 'woocommerce' ) );
@ -210,7 +211,7 @@ function wc_update_200_taxrates() {
}
/**
* Upadte order item line items for 2.0
* Update order item line items for 2.0
*
* @return void
*/
@ -219,10 +220,9 @@ function wc_update_200_line_items() {
// Now its time for the massive update to line items - move them to the new DB tables.
// Reverse with UPDATE `wpwc_postmeta` SET meta_key = '_order_items' WHERE meta_key = '_order_items_old'.
$order_item_rows = $wpdb->get_results( "
SELECT meta_value, post_id FROM {$wpdb->postmeta}
WHERE meta_key = '_order_items'
" );
$order_item_rows = $wpdb->get_results(
"SELECT meta_value, post_id FROM {$wpdb->postmeta} WHERE meta_key = '_order_items'"
);
foreach ( $order_item_rows as $order_item_row ) {
@ -242,10 +242,13 @@ function wc_update_200_line_items() {
$order_item['line_subtotal_tax'] = isset( $order_item['line_subtotal_tax'] ) ? $order_item['line_subtotal_tax'] : 0;
$order_item['line_subtotal'] = isset( $order_item['line_subtotal'] ) ? $order_item['line_subtotal'] : 0;
$item_id = wc_add_order_item( $order_item_row->post_id, array(
$item_id = wc_add_order_item(
$order_item_row->post_id,
array(
'order_item_name' => $order_item['name'],
'order_item_type' => 'line_item',
) );
)
);
// Add line item meta.
if ( $item_id ) {
@ -274,19 +277,25 @@ function wc_update_200_line_items() {
// Insert meta rows at once.
if ( count( $meta_rows ) > 0 ) {
$wpdb->query( $wpdb->prepare( "
INSERT INTO {$wpdb->prefix}woocommerce_order_itemmeta ( order_item_id, meta_key, meta_value )
VALUES " . implode( ',', $meta_rows ) . ';
', $order_item_row->post_id ) );
$wpdb->query(
$wpdb->prepare(
"INSERT INTO {$wpdb->prefix}woocommerce_order_itemmeta ( order_item_id, meta_key, meta_value )
VALUES " . implode( ',', $meta_rows ) . ';', // @codingStandardsIgnoreLine
$order_item_row->post_id
)
);
}
// Delete from DB (rename).
$wpdb->query( $wpdb->prepare( "
UPDATE {$wpdb->postmeta}
$wpdb->query(
$wpdb->prepare(
"UPDATE {$wpdb->postmeta}
SET meta_key = '_order_items_old'
WHERE meta_key = '_order_items'
AND post_id = %d
", $order_item_row->post_id ) );
AND post_id = %d",
$order_item_row->post_id
)
);
}
unset( $meta_rows, $item_id, $order_item );
@ -295,10 +304,10 @@ function wc_update_200_line_items() {
// Do the same kind of update for order_taxes - move to lines.
// Reverse with UPDATE `wpwc_postmeta` SET meta_key = '_order_taxes' WHERE meta_key = '_order_taxes_old'.
$order_tax_rows = $wpdb->get_results( "
SELECT meta_value, post_id FROM {$wpdb->postmeta}
WHERE meta_key = '_order_taxes'
" );
$order_tax_rows = $wpdb->get_results(
"SELECT meta_value, post_id FROM {$wpdb->postmeta}
WHERE meta_key = '_order_taxes'"
);
foreach ( $order_tax_rows as $order_tax_row ) {
@ -311,10 +320,12 @@ function wc_update_200_line_items() {
continue;
}
$item_id = wc_add_order_item( $order_tax_row->post_id, array(
$item_id = wc_add_order_item(
$order_tax_row->post_id, array(
'order_item_name' => $order_tax['label'],
'order_item_type' => 'tax',
) );
)
);
// Add line item meta.
if ( $item_id ) {
@ -324,12 +335,15 @@ function wc_update_200_line_items() {
}
// Delete from DB (rename).
$wpdb->query( $wpdb->prepare( "
UPDATE {$wpdb->postmeta}
$wpdb->query(
$wpdb->prepare(
"UPDATE {$wpdb->postmeta}
SET meta_key = '_order_taxes_old'
WHERE meta_key = '_order_taxes'
AND post_id = %d
", $order_tax_row->post_id ) );
AND post_id = %d",
$order_tax_row->post_id
)
);
unset( $tax_amount );
}
@ -347,11 +361,13 @@ function wc_update_200_images() {
// cleaning up afterwards like nice people do.
foreach ( array( 'catalog', 'single', 'thumbnail' ) as $value ) {
$old_settings = array_filter( array(
$old_settings = array_filter(
array(
'width' => get_option( 'woocommerce_' . $value . '_image_width' ),
'height' => get_option( 'woocommerce_' . $value . '_image_height' ),
'crop' => get_option( 'woocommerce_' . $value . '_image_crop' ),
) );
)
);
if ( ! empty( $old_settings ) && update_option( 'shop_' . $value . '_image_size', $old_settings ) ) {
@ -521,8 +537,8 @@ function wc_update_220_shipping() {
*/
function wc_update_220_order_status() {
global $wpdb;
$wpdb->query( "
UPDATE {$wpdb->posts} as posts
$wpdb->query(
"UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_id )
@ -530,11 +546,10 @@ function wc_update_220_order_status() {
WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status'
AND term.slug LIKE 'pending%';
"
AND term.slug LIKE 'pending%';"
);
$wpdb->query( "
UPDATE {$wpdb->posts} as posts
$wpdb->query(
"UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_id )
@ -542,11 +557,10 @@ function wc_update_220_order_status() {
WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status'
AND term.slug LIKE 'processing%';
"
AND term.slug LIKE 'processing%';"
);
$wpdb->query( "
UPDATE {$wpdb->posts} as posts
$wpdb->query(
"UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_id )
@ -554,11 +568,10 @@ function wc_update_220_order_status() {
WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status'
AND term.slug LIKE 'on-hold%';
"
AND term.slug LIKE 'on-hold%';"
);
$wpdb->query( "
UPDATE {$wpdb->posts} as posts
$wpdb->query(
"UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_id )
@ -566,11 +579,10 @@ function wc_update_220_order_status() {
WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status'
AND term.slug LIKE 'completed%';
"
AND term.slug LIKE 'completed%';"
);
$wpdb->query( "
UPDATE {$wpdb->posts} as posts
$wpdb->query(
"UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_id )
@ -578,11 +590,10 @@ function wc_update_220_order_status() {
WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status'
AND term.slug LIKE 'cancelled%';
"
AND term.slug LIKE 'cancelled%';"
);
$wpdb->query( "
UPDATE {$wpdb->posts} as posts
$wpdb->query(
"UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_id )
@ -590,11 +601,10 @@ function wc_update_220_order_status() {
WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status'
AND term.slug LIKE 'refunded%';
"
AND term.slug LIKE 'refunded%';"
);
$wpdb->query( "
UPDATE {$wpdb->posts} as posts
$wpdb->query(
"UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id
LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_id )
@ -602,8 +612,7 @@ function wc_update_220_order_status() {
WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status'
AND term.slug LIKE 'failed%';
"
AND term.slug LIKE 'failed%';"
);
}
@ -615,15 +624,15 @@ function wc_update_220_order_status() {
function wc_update_220_variations() {
global $wpdb;
// Update variations which manage stock.
$update_variations = $wpdb->get_results( "
SELECT DISTINCT posts.ID AS variation_id, posts.post_parent AS variation_parent FROM {$wpdb->posts} as posts
$update_variations = $wpdb->get_results(
"SELECT DISTINCT posts.ID AS variation_id, posts.post_parent AS variation_parent FROM {$wpdb->posts} as posts
LEFT OUTER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id AND postmeta.meta_key = '_stock'
LEFT OUTER JOIN {$wpdb->postmeta} as postmeta2 ON posts.ID = postmeta2.post_id AND postmeta2.meta_key = '_manage_stock'
WHERE posts.post_type = 'product_variation'
AND postmeta.meta_value IS NOT NULL
AND postmeta.meta_value != ''
AND postmeta2.meta_value IS NULL
" );
AND postmeta2.meta_value IS NULL"
);
foreach ( $update_variations as $variation ) {
$parent_backorders = get_post_meta( $variation->variation_parent, '_backorders', true );
@ -735,10 +744,15 @@ function wc_update_240_shipping_methods() {
$has_classes = count( WC()->shipping->get_shipping_classes() ) > 0;
$cost_key = $has_classes ? 'no_class_cost' : 'cost';
$min_fee = $shipping_method->get_option( 'minimum_fee' );
$math_cost_strings = array( 'cost' => array(), 'no_class_cost' => array() );
$math_cost_strings[ $cost_key ][] = $shipping_method->get_option( 'cost' );
$math_cost_strings = array(
'cost' => array(),
'no_class_cost' => array(),
);
if ( $fee = $shipping_method->get_option( 'fee' ) ) {
$math_cost_strings[ $cost_key ][] = $shipping_method->get_option( 'cost' );
$fee = $shipping_method->get_option( 'fee' );
if ( $fee ) {
$math_cost_strings[ $cost_key ][] = strstr( $fee, '%' ) ? '[fee percent="' . str_replace( '%', '', $fee ) . '" min="' . esc_attr( $min_fee ) . '"]' : $fee;
}
@ -747,7 +761,9 @@ function wc_update_240_shipping_methods() {
$math_cost_strings[ $rate_key ] = $math_cost_strings['no_class_cost'];
}
if ( $flat_rates = array_filter( (array) get_option( $flat_rate_option_key, array() ) ) ) {
$flat_rates = array_filter( (array) get_option( $flat_rate_option_key, array() ) );
if ( $flat_rates ) {
foreach ( $flat_rates as $shipping_class => $rate ) {
$rate_key = 'class_cost_' . $shipping_class;
if ( $rate['cost'] || $rate['fee'] ) {
@ -844,12 +860,14 @@ function wc_update_240_webhooks() {
* Webhooks.
* Make sure order.update webhooks get the woocommerce_order_edit_status hook.
*/
$order_update_webhooks = get_posts( array(
$order_update_webhooks = get_posts(
array(
'posts_per_page' => -1,
'post_type' => 'shop_webhook',
'meta_key' => '_topic',
'meta_value' => 'order.updated',
) );
)
);
foreach ( $order_update_webhooks as $order_update_webhook ) {
$webhook = new WC_Webhook( $order_update_webhook->ID );
$webhook->set_topic( 'order.updated' );
@ -867,11 +885,13 @@ function wc_update_240_refunds() {
* Refunds for full refunded orders.
* Update fully refunded orders to ensure they have a refund line item so reports add up.
*/
$refunded_orders = get_posts( array(
$refunded_orders = get_posts(
array(
'posts_per_page' => -1,
'post_type' => 'shop_order',
'post_status' => array( 'wc-refunded' ),
) );
)
);
// Ensure emails are disabled during this update routine.
remove_all_actions( 'woocommerce_order_status_refunded_notification' );
@ -881,22 +901,27 @@ function wc_update_240_refunds() {
foreach ( $refunded_orders as $refunded_order ) {
$order_total = get_post_meta( $refunded_order->ID, '_order_total', true );
$refunded_total = $wpdb->get_var( $wpdb->prepare( "
SELECT SUM( postmeta.meta_value )
$refunded_total = $wpdb->get_var(
$wpdb->prepare(
"SELECT SUM( postmeta.meta_value )
FROM $wpdb->postmeta AS postmeta
INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )
WHERE postmeta.meta_key = '_refund_amount'
AND postmeta.post_id = posts.ID
", $refunded_order->ID ) );
AND postmeta.post_id = posts.ID",
$refunded_order->ID
)
);
if ( $order_total > $refunded_total ) {
wc_create_refund( array(
wc_create_refund(
array(
'amount' => $order_total - $refunded_total,
'reason' => __( 'Order fully refunded', 'woocommerce' ),
'order_id' => $refunded_order->ID,
'line_items' => array(),
'date' => $refunded_order->post_modified,
) );
)
);
}
}
@ -921,13 +946,13 @@ function wc_update_241_variations() {
global $wpdb;
// Select variations that don't have any _stock_status implemented on WooCommerce 2.2.
$update_variations = $wpdb->get_results( "
SELECT DISTINCT posts.ID AS variation_id, posts.post_parent AS variation_parent
$update_variations = $wpdb->get_results(
"SELECT DISTINCT posts.ID AS variation_id, posts.post_parent AS variation_parent
FROM {$wpdb->posts} as posts
LEFT OUTER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id AND postmeta.meta_key = '_stock_status'
WHERE posts.post_type = 'product_variation'
AND postmeta.meta_value IS NULL
" );
AND postmeta.meta_value IS NULL"
);
foreach ( $update_variations as $variation ) {
// Get the parent _stock_status.
@ -1065,11 +1090,13 @@ function wc_update_260_zone_methods() {
// Move data.
foreach ( $old_methods as $old_method ) {
$wpdb->insert( $wpdb->prefix . 'woocommerce_shipping_zone_methods', array(
$wpdb->insert(
$wpdb->prefix . 'woocommerce_shipping_zone_methods', array(
'zone_id' => $old_method->zone_id,
'method_id' => $old_method->shipping_method_type,
'method_order' => $old_method->shipping_method_order,
) );
)
);
$new_instance_id = $wpdb->insert_id;
@ -1130,13 +1157,13 @@ function wc_update_260_refunds() {
/**
* Refund item qty should be negative.
*/
$wpdb->query( "
UPDATE {$wpdb->prefix}woocommerce_order_itemmeta as item_meta
$wpdb->query(
"UPDATE {$wpdb->prefix}woocommerce_order_itemmeta as item_meta
LEFT JOIN {$wpdb->prefix}woocommerce_order_items as items ON item_meta.order_item_id = items.order_item_id
LEFT JOIN {$wpdb->posts} as posts ON items.order_id = posts.ID
SET item_meta.meta_value = item_meta.meta_value * -1
WHERE item_meta.meta_value > 0 AND item_meta.meta_key = '_qty' AND posts.post_type = 'shop_order_refund'
" );
WHERE item_meta.meta_value > 0 AND item_meta.meta_key = '_qty' AND posts.post_type = 'shop_order_refund'"
);
}
/**
@ -1158,12 +1185,14 @@ function wc_update_300_webhooks() {
* Make sure product.update webhooks get the woocommerce_product_quick_edit_save
* and woocommerce_product_bulk_edit_save hooks.
*/
$product_update_webhooks = get_posts( array(
$product_update_webhooks = get_posts(
array(
'posts_per_page' => -1,
'post_type' => 'shop_webhook',
'meta_key' => '_topic',
'meta_value' => 'product.updated',
) );
)
);
foreach ( $product_update_webhooks as $product_update_webhook ) {
$webhook = new WC_Webhook( $product_update_webhook->ID );
$webhook->set_topic( 'product.updated' );
@ -1197,12 +1226,14 @@ function wc_update_300_grouped_products() {
foreach ( $parents as $parent_id ) {
$parent = wc_get_product( $parent_id );
if ( $parent && $parent->is_type( 'grouped' ) ) {
$children_ids = get_posts( array(
$children_ids = get_posts(
array(
'post_parent' => $parent_id,
'posts_per_page' => -1,
'post_type' => 'product',
'fields' => 'ids',
) );
)
);
update_post_meta( $parent_id, '_children', $children_ids );
// Update children to remove the parent.
@ -1241,39 +1272,57 @@ function wc_update_300_product_visibility() {
WC_Install::create_terms();
if ( $featured_term = get_term_by( 'name', 'featured', 'product_visibility' ) ) {
$featured_term = get_term_by( 'name', 'featured', 'product_visibility' );
if ( $featured_term ) {
$wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_featured' AND meta_value = 'yes';", $featured_term->term_taxonomy_id ) );
}
if ( $exclude_search_term = get_term_by( 'name', 'exclude-from-search', 'product_visibility' ) ) {
$exclude_search_term = get_term_by( 'name', 'exclude-from-search', 'product_visibility' );
if ( $exclude_search_term ) {
$wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_visibility' AND meta_value IN ('hidden', 'catalog');", $exclude_search_term->term_taxonomy_id ) );
}
if ( $exclude_catalog_term = get_term_by( 'name', 'exclude-from-catalog', 'product_visibility' ) ) {
$exclude_catalog_term = get_term_by( 'name', 'exclude-from-catalog', 'product_visibility' );
if ( $exclude_catalog_term ) {
$wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_visibility' AND meta_value IN ('hidden', 'search');", $exclude_catalog_term->term_taxonomy_id ) );
}
if ( $outofstock_term = get_term_by( 'name', 'outofstock', 'product_visibility' ) ) {
$outofstock_term = get_term_by( 'name', 'outofstock', 'product_visibility' );
if ( $outofstock_term ) {
$wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_stock_status' AND meta_value = 'outofstock';", $outofstock_term->term_taxonomy_id ) );
}
if ( $rating_term = get_term_by( 'name', 'rated-1', 'product_visibility' ) ) {
$rating_term = get_term_by( 'name', 'rated-1', 'product_visibility' );
if ( $rating_term ) {
$wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 1;", $rating_term->term_taxonomy_id ) );
}
if ( $rating_term = get_term_by( 'name', 'rated-2', 'product_visibility' ) ) {
$rating_term = get_term_by( 'name', 'rated-2', 'product_visibility' );
if ( $rating_term ) {
$wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 2;", $rating_term->term_taxonomy_id ) );
}
if ( $rating_term = get_term_by( 'name', 'rated-3', 'product_visibility' ) ) {
$rating_term = get_term_by( 'name', 'rated-3', 'product_visibility' );
if ( $rating_term ) {
$wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 3;", $rating_term->term_taxonomy_id ) );
}
if ( $rating_term = get_term_by( 'name', 'rated-4', 'product_visibility' ) ) {
$rating_term = get_term_by( 'name', 'rated-4', 'product_visibility' );
if ( $rating_term ) {
$wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 4;", $rating_term->term_taxonomy_id ) );
}
if ( $rating_term = get_term_by( 'name', 'rated-5', 'product_visibility' ) ) {
$rating_term = get_term_by( 'name', 'rated-5', 'product_visibility' );
if ( $rating_term ) {
$wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO {$wpdb->term_relationships} SELECT post_id, %d, 0 FROM {$wpdb->postmeta} WHERE meta_key = '_wc_average_rating' AND ROUND( meta_value ) = 5;", $rating_term->term_taxonomy_id ) );
}
}
@ -1373,12 +1422,10 @@ function wc_update_320_mexican_states() {
foreach ( $mx_states as $old => $new ) {
$wpdb->query(
$wpdb->prepare(
"
UPDATE $wpdb->postmeta
"UPDATE $wpdb->postmeta
SET meta_value = %s
WHERE meta_key IN ( '_billing_state', '_shipping_state' )
AND meta_value = %s
",
AND meta_value = %s",
$new, $old
)
);
@ -1432,6 +1479,34 @@ function wc_update_330_image_options() {
}
}
/**
* Assign default cat to all products with no cats.
*/
function wc_update_330_set_default_product_cat() {
global $wpdb;
$default_category = get_option( 'default_product_cat', 0 );
if ( $default_category ) {
$result = $wpdb->query( $wpdb->prepare( "
INSERT INTO {$wpdb->term_relationships} (object_id, term_taxonomy_id)
SELECT DISTINCT posts.ID, %s FROM {$wpdb->posts} posts
LEFT JOIN
(
SELECT object_id FROM {$wpdb->term_relationships} term_relationships
LEFT JOIN {$wpdb->term_taxonomy} term_taxonomy ON term_relationships.term_taxonomy_id = term_taxonomy.term_taxonomy_id
WHERE term_taxonomy.taxonomy = 'product_cat'
) AS tax_query
ON posts.ID = tax_query.object_id
WHERE posts.post_type = 'product'
AND tax_query.object_id IS NULL
", $default_category ) );
wp_cache_flush();
delete_transient( 'wc_term_counts' );
wp_update_term_count_now( array( $default_category ), 'product_cat' );
}
}
/**
* Update DB Version.
*/

View File

@ -449,6 +449,7 @@ function wc_get_customer_available_downloads( $customer_id ) {
'download_id' => $result->download_id,
'product_id' => $_product->get_id(),
'product_name' => $_product->get_name(),
'product_url' => $_product->is_visible() ? $_product->get_permalink() : '', // Since 3.3.0.
'download_name' => $download_name,
'order_id' => $order->get_id(),
'order_key' => $order->get_order_key(),

View File

@ -33,7 +33,7 @@ class WC_Widget_Recently_Viewed extends WC_Widget {
'type' => 'number',
'step' => 1,
'min' => 1,
'max' => '',
'max' => 15,
'std' => 10,
'label' => __( 'Number of products to show', 'woocommerce' ),
),

View File

@ -10,6 +10,8 @@
"license": "GPL-3.0+",
"main": "Gruntfile.js",
"scripts": {
"build": "grunt",
"build-watch": "grunt watch",
"test": "cross-env NODE_CONFIG_DIR='./tests/e2e-tests/config' BABEL_ENV=commonjs mocha \"tests/e2e-tests\" --compilers js:babel-register --recursive",
"test:grep": "cross-env NODE_CONFIG_DIR='./tests/e2e-tests/config' BABEL_ENV=commonjs mocha \"tests/e2e-tests\" --compilers js:babel-register --grep ",
"test:single": "cross-env NODE_CONFIG_DIR='./tests/e2e-tests/config' BABEL_ENV=commonjs mocha --compilers js:babel-register"

View File

@ -15,15 +15,20 @@
<exclude-pattern>*/vendor/*</exclude-pattern>
<!-- Configs -->
<config name="minimum_supported_wp_version" value="4.5" />
<config name="minimum_supported_wp_version" value="4.7" />
<config name="testVersion" value="5.2-"/>
<!-- Rules -->
<rule ref="PHPCompatibility"/>
<rule ref="WordPress">
<exclude name="WordPress.VIP.RestrictedFunctions" />
<exclude name="WordPress.VIP.DirectDatabaseQuery.NoCaching" />
<exclude name="WordPress.VIP.DirectDatabaseQuery.SchemaChange" />
<exclude name="WordPress.VIP.FileSystemWritesDisallow.file_ops_fwrite" />
<exclude name="WordPress.VIP.OrderByRand" />
<exclude name="WordPress.VIP.RestrictedFunctions" />
<exclude name="WordPress.VIP.RestrictedVariables.user_meta__wpdb__usermeta" />
<exclude name="WordPress.VIP.PostsPerPage.posts_per_page_posts_per_page" />
</rule>
<rule ref="WordPress.VIP.ValidatedSanitizedInput">
<properties>
@ -40,4 +45,7 @@
<property name="text_domain" type="array" value="woocommerce" />
</properties>
</rule>
<rule ref="WordPress.Files.FileName.InvalidClassFileName">
<exclude-pattern>includes/**/abstract-*.php</exclude-pattern>
</rule>
</ruleset>

View File

@ -1,8 +1,8 @@
=== WooCommerce ===
Contributors: automattic, mikejolley, jameskoster, claudiosanches, jshreve, coderkevin, claudiulodro, woothemes, iCaleb
Tags: ecommerce, e-commerce, store, sales, sell, shop, cart, checkout, downloadable, downloads, paypal, storefront, woo commerce
Requires at least: 4.5
Tested up to: 4.8
Requires at least: 4.7
Tested up to: 4.9
Stable tag: 3.2.0
License: GPLv3
License URI: https://www.gnu.org/licenses/gpl-3.0.html

View File

@ -11,7 +11,7 @@
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @author Automattic
* @package WooCommerce/Templates
* @version 3.3.0
*/
@ -22,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
<section class="woocommerce-order-downloads">
<?php if ( isset( $show_title ) ) : ?>
<h2 class="woocommerce-order-downloads__title"><?php _e( 'Downloads', 'woocommerce' ); ?></h2>
<h2 class="woocommerce-order-downloads__title"><?php esc_html_e( 'Downloads', 'woocommerce' ); ?></h2>
<?php endif; ?>
<table class="woocommerce-table woocommerce-table--order-downloads shop_table shop_table_responsive order_details">
@ -37,32 +37,36 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php foreach ( $downloads as $download ) : ?>
<tr>
<?php foreach ( wc_get_account_downloads_columns() as $column_id => $column_name ) : ?>
<td class="<?php echo esc_attr( $column_id ); ?>" data-title="<?php echo esc_attr( $column_name ); ?>"><?php
<td class="<?php echo esc_attr( $column_id ); ?>" data-title="<?php echo esc_attr( $column_name ); ?>">
<?php
if ( has_action( 'woocommerce_account_downloads_column_' . $column_id ) ) {
do_action( 'woocommerce_account_downloads_column_' . $column_id, $download );
} else {
switch ( $column_id ) {
case 'download-product' : ?>
<a href="<?php echo esc_url( get_permalink( $download['product_id'] ) ); ?>"><?php echo esc_html( $download['product_name'] ); ?></a>
<?php
case 'download-product':
if ( $download['product_url'] ) {
echo '<a href="' . esc_url( $download['product_url'] ) . '">' . esc_html( $download['product_name'] ) . '</a>';
} else {
echo esc_html( $download['product_name'] );
}
break;
case 'download-file' : ?>
<a href="<?php echo esc_url( $download['download_url'] ); ?>" class="woocommerce-MyAccount-downloads-file button alt"><?php echo esc_html( $download['download_name'] ); ?></a>
<?php
case 'download-file':
echo '<a href="' . esc_url( $download['download_url'] ) . '" class="woocommerce-MyAccount-downloads-file button alt">' . esc_html( $download['download_name'] ) . '</a>';
break;
case 'download-remaining' :
echo is_numeric( $download['downloads_remaining'] ) ? esc_html( $download['downloads_remaining'] ) : __( '&infin;', 'woocommerce' );
case 'download-remaining':
echo is_numeric( $download['downloads_remaining'] ) ? esc_html( $download['downloads_remaining'] ) : esc_html__( '&infin;', 'woocommerce' );
break;
case 'download-expires' : ?>
<?php if ( ! empty( $download['access_expires'] ) ) : ?>
<time datetime="<?php echo date( 'Y-m-d', strtotime( $download['access_expires'] ) ); ?>" title="<?php echo esc_attr( strtotime( $download['access_expires'] ) ); ?>"><?php echo date_i18n( get_option( 'date_format' ), strtotime( $download['access_expires'] ) ); ?></time>
<?php else : ?>
<?php _e( 'Never', 'woocommerce' ); ?>
<?php endif;
case 'download-expires':
if ( ! empty( $download['access_expires'] ) ) {
echo '<time datetime="' . esc_attr( date( 'Y-m-d', strtotime( $download['access_expires'] ) ) ) . '" title="' . esc_attr( strtotime( $download['access_expires'] ) ) . '">' . esc_html( date_i18n( get_option( 'date_format' ), strtotime( $download['access_expires'] ) ) ) . '</time>';
} else {
esc_html_e( 'Never', 'woocommerce' );
}
break;
}
}
?></td>
?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>

View File

@ -15,17 +15,11 @@ if ( ! defined( 'ABSPATH' ) ) {
}
?>
<script type="text/template" id="tmpl-variation-template">
<div class="woocommerce-variation-description">
{{{ data.variation.variation_description }}}
</div>
<div class="woocommerce-variation-description">{{{ data.variation.variation_description }}}</div>
<div class="woocommerce-variation-price">
{{{ data.variation.price_html }}}
</div>
<div class="woocommerce-variation-price">{{{ data.variation.price_html }}}</div>
<div class="woocommerce-variation-availability">
{{{ data.variation.availability_html }}}
</div>
<div class="woocommerce-variation-availability">{{{ data.variation.availability_html }}}</div>
</script>
<script type="text/template" id="tmpl-unavailable-variation-template">
<p><?php _e( 'Sorry, this product is unavailable. Please choose a different combination.', 'woocommerce' ); ?></p>

View File

@ -3,28 +3,16 @@
if [ $1 == 'before' ]; then
# Composer install fails in PHP 5.2
[[ ${TRAVIS_PHP_VERSION} == '5.2' ]] && exit;
# No Xdebug and therefore no coverage in PHP 5.3
[[ ${TRAVIS_PHP_VERSION} == '5.3' ]] && exit;
if [[ ${TRAVIS_PHP_VERSION:0:2} == "5." ]]; then
composer global require "phpunit/phpunit=4.8.*"
else
composer global require "phpunit/phpunit=6.2.*"
fi
if [[ ${RUN_PHPCS} == 1 ]]; then
composer install
fi
# Remove Xdebug from PHP runtime for all PHP version except 7.1 to speed up builds.
# We need Xdebug enabled in the PHP 7.1 build job as it is used to generate code coverage.
if [[ ${RUN_CODE_COVERAGE} != 1 ]]; then
phpenv config-rm xdebug.ini
fi
if [[ ${RUN_PHPCS} == 1 ]]; then
composer install
fi
fi
if [ $1 == 'after' ]; then

View File

@ -81,6 +81,21 @@ class WC_Unit_Test_Case extends WP_UnitTestCase {
$this->assertInstanceOf( 'WP_Error', $actual, $message );
}
/**
* Throws an exception with an optional message and code.
*
* Note: can't use `throwException` as that's reserved.
*
* @since 3.3-dev
* @param string $message
* @param int $code
* @throws \Exception
*/
public function throwAnException( $message = null, $code = null ) {
$message = $message ? $message : "We're all doomed!";
throw new Exception( $message, $code );
}
/**
* Backport assertNotFalse to PHPUnit 3.6.12 which only runs in PHP 5.2.
*

View File

@ -1,7 +1,13 @@
<?php
/**
* Class WC_Tests_Order_Functions file.
*
* @package WooCommerce/Tests
*/
/**
* Class Functions.
*
* @package WooCommerce\Tests\Order
* @since 2.3
*/
@ -14,7 +20,8 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
*/
public function test_wc_get_order_statuses() {
$order_statuses = apply_filters( 'wc_order_statuses', array(
$order_statuses = apply_filters(
'wc_order_statuses', array(
'wc-pending' => _x( 'Pending payment', 'Order status', 'woocommerce' ),
'wc-processing' => _x( 'Processing', 'Order status', 'woocommerce' ),
'wc-on-hold' => _x( 'On hold', 'Order status', 'woocommerce' ),
@ -22,7 +29,8 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
'wc-cancelled' => _x( 'Cancelled', 'Order status', 'woocommerce' ),
'wc-refunded' => _x( 'Refunded', 'Order status', 'woocommerce' ),
'wc-failed' => _x( 'Failed', 'Order status', 'woocommerce' ),
) );
)
);
$this->assertEquals( $order_statuses, wc_get_order_statuses() );
}
@ -50,6 +58,7 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
/**
* Test wc_processing_order_count().
*
* @since 2.4
*/
public function test_wc_processing_order_count() {
@ -58,6 +67,7 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
/**
* Test wc_orders_count().
*
* @since 2.4
*/
public function test_wc_orders_count() {
@ -65,7 +75,7 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$this->assertEquals( 0, wc_orders_count( $status ) );
}
// Invalid status returns 0
// Invalid status returns 0.
$this->assertEquals( 0, wc_orders_count( 'unkown-status' ) );
}
@ -97,20 +107,20 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order = WC_Helper_Order::create_order();
// Assert that $order is a WC_Order object
// Assert that $order is a WC_Order object.
$this->assertInstanceOf( 'WC_Order', $order );
// Assert that wc_get_order() accepts a WC_Order object
// Assert that wc_get_order() accepts a WC_Order object.
$this->assertInstanceOf( 'WC_Order', wc_get_order( $order ) );
// Assert that wc_get_order() accepts a order post id.
$this->assertInstanceOf( 'WC_Order', wc_get_order( $order->get_id() ) );
// Assert that a non-shop_order post returns false
// Assert that a non-shop_order post returns false.
$post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) );
$this->assertFalse( wc_get_order( $post->ID ) );
// Assert the return when $the_order args is false
// Assert the return when $the_order args is false.
$this->assertFalse( wc_get_order( false ) );
// Assert the return when $the_order args is a random (incorrect) id.
@ -163,19 +173,34 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order_3 = $order3->get_id();
$order_4 = $order4->get_id();
$orders = wc_get_orders( array( 'customer' => 0, 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'customer' => 0,
'return' => 'ids',
)
);
$expected = array( $order_1, $order_2 );
sort( $expected );
sort( $orders );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'customer' => 1, 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'customer' => 1,
'return' => 'ids',
)
);
$expected = array( $order_3, $order_4 );
sort( $expected );
sort( $orders );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'customer' => '', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'customer' => '',
'return' => 'ids',
)
);
$expected = array( $order_1, $order_2, $order_3, $order_4 );
sort( $expected );
sort( $orders );
@ -206,37 +231,68 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order3->save();
$order_3 = $order3->get_id();
$orders = wc_get_orders( array( 'date_before' => '2017-01-15', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'date_before' => '2017-01-15',
'return' => 'ids',
)
);
$expected = array( $order_1, $order_2, $order_3 );
sort( $expected );
sort( $orders );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'date_before' => '2017-01-01', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'date_before' => '2017-01-01',
'return' => 'ids',
)
);
$expected = array( $order_1 );
sort( $expected );
sort( $orders );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'date_before' => '2016-12-31', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'date_before' => '2016-12-31',
'return' => 'ids',
)
);
$expected = array( $order_1 );
sort( $expected );
sort( $orders );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'date_after' => '2015-01-01 00:00:00', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'date_after' => '2015-01-01 00:00:00',
'return' => 'ids',
)
);
$expected = array( $order_1, $order_2, $order_3 );
sort( $expected );
sort( $orders );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'date_after' => '2016-01-01', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'date_after' => '2016-01-01',
'return' => 'ids',
)
);
$expected = array( $order_2, $order_3 );
sort( $expected );
sort( $orders );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'date_before' => '2017-01-15', 'date_after' => '2015-01-01 00:00:00', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'date_before' => '2017-01-15',
'date_after' => '2015-01-01 00:00:00',
'return' => 'ids',
)
);
$expected = array( $order_1, $order_2, $order_3 );
sort( $expected );
sort( $orders );
@ -260,11 +316,21 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2->set_status( 'completed' );
$order2->save();
$orders = wc_get_orders( array( 'status' => 'pending', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'status' => 'pending',
'return' => 'ids',
)
);
$expected = array( $order1->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'status' => 'completed', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'status' => 'completed',
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -280,11 +346,21 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$refund = new WC_Order_Refund();
$refund->save();
$orders = wc_get_orders( array( 'type' => 'shop_order_refund', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'type' => 'shop_order_refund',
'return' => 'ids',
)
);
$expected = array( $refund->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'type' => 'shop_order', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'type' => 'shop_order',
'return' => 'ids',
)
);
$expected = array( $order->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -298,11 +374,21 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order = WC_Helper_Order::create_order();
$order->save();
$orders = wc_get_orders( array( 'version' => WC_VERSION, 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'version' => WC_VERSION,
'return' => 'ids',
)
);
$expected = array( $order->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'version' => '2.1.0', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'version' => '2.1.0',
'return' => 'ids',
)
);
$expected = array();
$this->assertEquals( $expected, $orders );
}
@ -320,11 +406,21 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2->set_created_via( 'checkout' );
$order2->save();
$orders = wc_get_orders( array( 'created_via' => 'rest-api', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'created_via' => 'rest-api',
'return' => 'ids',
)
);
$expected = array( $order1->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'created_via' => 'checkout', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'created_via' => 'checkout',
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -344,7 +440,12 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2 = WC_Helper_Order::create_order();
$order2->save();
$orders = wc_get_orders( array( 'parent' => $parent->get_id(), 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'parent' => $parent->get_id(),
'return' => 'ids',
)
);
$expected = array( $order1->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -364,7 +465,12 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2 = WC_Helper_Order::create_order();
$order2->save();
$orders = wc_get_orders( array( 'parent_exclude' => array( $parent->get_id() ), 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'parent_exclude' => array( $parent->get_id() ),
'return' => 'ids',
)
);
sort( $orders );
$expected = array( $parent->get_id(), $order2->get_id() );
$this->assertEquals( $expected, $orders );
@ -381,7 +487,12 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2 = WC_Helper_Order::create_order();
$order2->save();
$orders = wc_get_orders( array( 'exclude' => array( $order1->get_id() ), 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'exclude' => array( $order1->get_id() ),
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -412,11 +523,27 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2 = WC_Helper_Order::create_order();
$order2->save();
$orders = wc_get_orders( array( 'paged' => 1, 'orderby' => 'ID', 'order' => 'ASC', 'limit' => 1, 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'paged' => 1,
'orderby' => 'ID',
'order' => 'ASC',
'limit' => 1,
'return' => 'ids',
)
);
$expected = array( $order1->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'paged' => 2, 'orderby' => 'ID', 'order' => 'ASC', 'limit' => 1, 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'paged' => 2,
'orderby' => 'ID',
'order' => 'ASC',
'limit' => 1,
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -432,7 +559,14 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2 = WC_Helper_Order::create_order();
$order2->save();
$orders = wc_get_orders( array( 'offset' => 1, 'orderby' => 'ID', 'order' => 'ASC', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'offset' => 1,
'orderby' => 'ID',
'order' => 'ASC',
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -464,7 +598,12 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order = WC_Helper_order::create_order();
$order->save();
$orders = wc_get_orders( array( 'paginate' => true, 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'paginate' => true,
'return' => 'ids',
)
);
$this->assertEquals( 1, $orders->total );
$this->assertEquals( 1, $orders->max_num_pages );
$this->assertEquals( $order->get_id(), $orders->orders[0] );
@ -481,11 +620,23 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2 = WC_Helper_Order::create_order();
$order2->save();
$orders = wc_get_orders( array( 'orderby' => 'ID', 'order' => 'DESC', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'orderby' => 'ID',
'order' => 'DESC',
'return' => 'ids',
)
);
$expected = array( $order2->get_id(), $order1->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'orderby' => 'ID', 'order' => 'ASC', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'orderby' => 'ID',
'order' => 'ASC',
'return' => 'ids',
)
);
$expected = array( $order1->get_id(), $order2->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -503,11 +654,21 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2->set_currency( 'USD' );
$order2->save();
$orders = wc_get_orders( array( 'currency' => 'BRL', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'currency' => 'BRL',
'return' => 'ids',
)
);
$expected = array( $order1->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'currency' => 'USD', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'currency' => 'USD',
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -525,11 +686,21 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2->set_prices_include_tax( false );
$order2->save();
$orders = wc_get_orders( array( 'prices_include_tax' => 'yes', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'prices_include_tax' => 'yes',
'return' => 'ids',
)
);
$expected = array( $order1->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'prices_include_tax' => 'no', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'prices_include_tax' => 'no',
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -547,11 +718,21 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2->set_payment_method( 'cod' );
$order2->save();
$orders = wc_get_orders( array( 'payment_method' => 'cheque', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'payment_method' => 'cheque',
'return' => 'ids',
)
);
$expected = array( $order1->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'payment_method' => 'cod', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'payment_method' => 'cod',
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -569,11 +750,21 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2->set_payment_method_title( 'PayPal' );
$order2->save();
$orders = wc_get_orders( array( 'payment_method_title' => 'Check payments', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'payment_method_title' => 'Check payments',
'return' => 'ids',
)
);
$expected = array( $order1->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'payment_method_title' => 'PayPal', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'payment_method_title' => 'PayPal',
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -601,27 +792,57 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2->set_total( 5.89 );
$order2->save();
$orders = wc_get_orders( array( 'discount_total' => 5.50, 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'discount_total' => 5.50,
'return' => 'ids',
)
);
$expected = array( $order1->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'discount_tax' => 0.20, 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'discount_tax' => 0.20,
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'shipping_total' => 3.99, 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'shipping_total' => 3.99,
'return' => 'ids',
)
);
$expected = array( $order1->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'shipping_tax' => 0.15, 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'shipping_tax' => 0.15,
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'cart_tax' => 0.10, 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'cart_tax' => 0.10,
'return' => 'ids',
)
);
$expected = array( $order1->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'total' => 5.89, 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'total' => 5.89,
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -649,11 +870,21 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2->set_billing_email( $customer2->get_billing_email() );
$order2->save();
$orders = wc_get_orders( array( 'customer' => $customer1->get_billing_email(), 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'customer' => $customer1->get_billing_email(),
'return' => 'ids',
)
);
$expected = array( $order1->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'customer' => $customer2->get_id(), 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'customer' => $customer2->get_id(),
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
@ -691,11 +922,21 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$order2->set_customer_id( $customer2->get_id() );
$order2->save();
$orders = wc_get_orders( array( 'customer_id' => $customer1->get_id(), 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'customer_id' => $customer1->get_id(),
'return' => 'ids',
)
);
$expected = array( $order1->get_id() );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'customer_id' => $customer2->get_id(), 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'customer_id' => $customer2->get_id(),
'return' => 'ids',
)
);
$expected = array( $order2->get_id() );
$this->assertEquals( $expected, $orders );
}
@ -707,7 +948,8 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
*/
public function test_wc_get_order_address_params() {
$order1 = WC_Helper_Order::create_order();
$order1->set_props( array(
$order1->set_props(
array(
'billing_email' => 'test1@test.com',
'billing_first_name' => 'Bill',
'billing_last_name' => 'Powers',
@ -728,12 +970,14 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
'shipping_state' => 'OR',
'shipping_postcode' => '97222',
'shipping_country' => 'USA',
) );
)
);
$order1->save();
$order1_id = $order1->get_id();
$order2 = WC_Helper_Order::create_order();
$order2->set_props( array(
$order2->set_props(
array(
'billing_email' => 'test2@test.com',
'billing_first_name' => 'Joe',
'billing_last_name' => 'Thunder',
@ -754,91 +998,202 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
'shipping_state' => 'WA',
'shipping_postcode' => '97233',
'shipping_country' => 'USA',
) );
)
);
$order2->save();
$order2_id = $order2->get_id();
$orders = wc_get_orders( array( 'billing_email' => 'test1@test.com', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'billing_email' => 'test1@test.com',
'return' => 'ids',
)
);
$expected = array( $order1_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'billing_first_name' => 'Joe', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'billing_first_name' => 'Joe',
'return' => 'ids',
)
);
$expected = array( $order2_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'billing_last_name' => 'Powers', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'billing_last_name' => 'Powers',
'return' => 'ids',
)
);
$expected = array( $order1_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'billing_company' => 'ThunderCo.', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'billing_company' => 'ThunderCo.',
'return' => 'ids',
)
);
$expected = array( $order2_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'billing_address_1' => '1234 Cool St.', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'billing_address_1' => '1234 Cool St.',
'return' => 'ids',
)
);
$expected = array( $order1_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'billing_address_2' => 'Apt 2', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'billing_address_2' => 'Apt 2',
'return' => 'ids',
)
);
$expected = array( $order1_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'billing_city' => 'Vancouver', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'billing_city' => 'Vancouver',
'return' => 'ids',
)
);
$expected = array( $order2_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'billing_state' => 'OR', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'billing_state' => 'OR',
'return' => 'ids',
)
);
$expected = array( $order1_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'billing_postcode' => '97267', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'billing_postcode' => '97267',
'return' => 'ids',
)
);
$expected = array( $order2_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'billing_country' => 'USA', 'orderby' => 'ID', 'order' => 'ASC', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'billing_country' => 'USA',
'orderby' => 'ID',
'order' => 'ASC',
'return' => 'ids',
)
);
$expected = array( $order1_id, $order2_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'billing_phone' => '503-333-3333', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'billing_phone' => '503-333-3333',
'return' => 'ids',
)
);
$expected = array( $order2_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'shipping_first_name' => 'Jane', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'shipping_first_name' => 'Jane',
'return' => 'ids',
)
);
$expected = array( $order1_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'shipping_last_name' => 'Thunder', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'shipping_last_name' => 'Thunder',
'return' => 'ids',
)
);
$expected = array( $order2_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'shipping_company' => 'Thunder Inc', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'shipping_company' => 'Thunder Inc',
'return' => 'ids',
)
);
$expected = array( $order2_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'shipping_address_1' => '1 Thunder Blvd', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'shipping_address_1' => '1 Thunder Blvd',
'return' => 'ids',
)
);
$expected = array( $order2_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'shipping_address_2' => 'Apt 1', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'shipping_address_2' => 'Apt 1',
'return' => 'ids',
)
);
$expected = array( $order1_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'shipping_city' => 'Vancouver', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'shipping_city' => 'Vancouver',
'return' => 'ids',
)
);
$expected = array( $order2_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'shipping_state' => 'OR', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'shipping_state' => 'OR',
'return' => 'ids',
)
);
$expected = array( $order1_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'shipping_postcode' => '97233', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'shipping_postcode' => '97233',
'return' => 'ids',
)
);
$expected = array( $order2_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'shipping_country' => 'USA', 'orderby' => 'ID', 'order' => 'ASC', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'shipping_country' => 'USA',
'orderby' => 'ID',
'order' => 'ASC',
'return' => 'ids',
)
);
$expected = array( $order1_id, $order2_id );
$this->assertEquals( $expected, $orders );
$orders = wc_get_orders( array( 'billing_first_name' => 'Joe', 'billing_last_name' => 'Thunder', 'return' => 'ids' ) );
$orders = wc_get_orders(
array(
'billing_first_name' => 'Joe',
'billing_last_name' => 'Thunder',
'return' => 'ids',
)
);
$expected = array( $order2_id );
$this->assertEquals( $expected, $orders );
}
@ -857,29 +1212,37 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
// Populate orders.
$us_now = WC_Helper_Order::create_order();
$us_now->set_props( array(
$us_now->set_props(
array(
'shipping_country' => 'US',
) );
)
);
$us_now->save();
$us_old = WC_Helper_Order::create_order();
$us_old->set_props( array(
$us_old->set_props(
array(
'date_created' => $yesterday,
'shipping_country' => 'US',
) );
)
);
$us_old->save();
$mx_now = WC_Helper_Order::create_order();
$mx_now->set_props( array(
$mx_now->set_props(
array(
'shipping_country' => 'MX',
) );
)
);
$mx_now->save();
$mx_old = WC_Helper_Order::create_order();
$mx_old->set_props( array(
$mx_old->set_props(
array(
'date_created' => $yesterday,
'shipping_country' => 'MX',
) );
)
);
$mx_old->save();
// Test just date range.
@ -952,10 +1315,20 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$notes = wc_get_order_notes( array( 'order_id' => $order->get_id() ) );
$this->assertEquals( 3, count( $notes ) );
$notes = wc_get_order_notes( array( 'order_id' => $order->get_id(), 'type' => 'customer' ) );
$notes = wc_get_order_notes(
array(
'order_id' => $order->get_id(),
'type' => 'customer',
)
);
$this->assertEquals( 1, count( $notes ) );
$notes = wc_get_order_notes( array( 'order_id' => $order->get_id(), 'type' => 'internal' ) );
$notes = wc_get_order_notes(
array(
'order_id' => $order->get_id(),
'type' => 'internal',
)
);
$this->assertEquals( 2, count( $notes ) );
}
@ -982,4 +1355,22 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case {
$this->assertTrue( wc_delete_order_note( $note_id ) );
}
/**
* Test wc_order_search()
*
* @since 3.3.0
*/
public function test_wc_order_search() {
$order = WC_Helper_Order::create_order();
// Should find order searching by billing address name.
$this->assertEquals( array( $order->get_id() ), wc_order_search( 'Jeroen' ) );
// Should find order searching by order item name.
$this->assertEquals( array( $order->get_id() ), wc_order_search( 'Dummy Product' ) );
// Should return nothing when searching for nonexistent term.
$this->assertEmpty( wc_order_search( 'Nonexistent term' ) );
}
}

View File

@ -1318,7 +1318,7 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case {
$object->set_shipping_state( 'Boulder' );
$object->set_shipping_postcode( '00001' );
$object->set_shipping_country( 'US' );
$this->assertEquals( 'https://maps.google.com/maps?&q=34+Stonepants+avenue%2C+Rockville%2C+Bedrock%2C+Boulder%2C+00001%2C+US&z=16', $object->get_shipping_address_map_url() );
$this->assertEquals( 'https://maps.google.com/maps?&q=34%20Stonepants%20avenue%2C%20Rockville%2C%20Bedrock%2C%20Boulder%2C%2000001%2C%20US&z=16', $object->get_shipping_address_map_url() );
}
/**
@ -1656,6 +1656,21 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case {
$this->assertEquals( 4, $object->get_remaining_refund_items() );
}
/**
* Test that if an exception is thrown when creating a refund, the refund is deleted from database.
*/
function test_refund_exception() {
$order = WC_Helper_Order::create_order();
add_action( 'woocommerce_create_refund', array( $this, 'throwAnException' ) );
$refund = wc_create_refund( array(
'order_id' => $order->get_id(),
'amount' => $order->get_total(),
'line_items' => array(),
) );
remove_action( 'woocommerce_create_refund', array( $this, 'throwAnException' ) );
$this->assertEmpty( $order->get_refunds() );
}
/**
* Test apply_coupon and remove_coupon with a fixed discount coupon.
* @since 3.2.0

View File

@ -40,6 +40,7 @@ class WC_Tests_Deprecated_Hooks extends WC_Unit_Test_Case {
function setUp() {
add_filter( 'deprecated_function_trigger_error', '__return_false' );
add_filter( 'deprecated_hook_trigger_error', '__return_false' );
$this->handlers = WC()->deprecated_hook_handlers;
}

View File

@ -6,8 +6,6 @@
* Version: 3.3-dev
* Author: Automattic
* Author URI: https://woocommerce.com
* Requires at least: 4.5
* Tested up to: 4.7
*
* Text Domain: woocommerce
* Domain Path: /i18n/languages/