Merge branch 'master' into feature/webhook-crud

This commit is contained in:
Claudio Sanches 2017-11-28 15:09:10 -02:00
commit c6f8e95b97
92 changed files with 2493 additions and 1726 deletions

View File

@ -6,7 +6,6 @@ sudo: false
php: php:
- 5.6 - 5.6
- 7.0 - 7.0
- 7.1
env: env:
- WP_VERSION=latest WP_MULTISITE=0 - WP_VERSION=latest WP_MULTISITE=0
@ -20,6 +19,8 @@ matrix:
dist: precise dist: precise
- php: 5.2 - php: 5.2
dist: precise dist: precise
- php: 7.1
env: WP_VERSION=latest WP_MULTISITE=0 RUN_PHPCS=1
- php: 7.1 - php: 7.1
env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1 env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1
allow_failures: allow_failures:
@ -27,7 +28,6 @@ matrix:
before_script: before_script:
- export PATH="$HOME/.composer/vendor/bin:$PATH" - export PATH="$HOME/.composer/vendor/bin:$PATH"
- if [[ $TRAVIS_PHP_VERSION == '7.1' ]]; then composer install; fi
- bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION - bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION
- bash tests/bin/travis.sh before - bash tests/bin/travis.sh before
@ -37,3 +37,10 @@ script:
after_script: after_script:
- bash tests/bin/travis.sh after - bash tests/bin/travis.sh after
# Specifies that Travis should create builds for master and release branches and also tags.
branches:
only:
- master
- /^\d+\.\d+(\.\d+)?(-\S*)?$/
- /^release\//

View File

@ -334,9 +334,9 @@ module.exports = function( grunt ) {
// Register tasks // Register tasks
grunt.registerTask( 'default', [ grunt.registerTask( 'default', [
'jshint', 'js',
'uglify', 'css',
'css' 'i18n'
]); ]);
grunt.registerTask( 'js', [ grunt.registerTask( 'js', [
@ -358,8 +358,13 @@ module.exports = function( grunt ) {
'shell:apigen' 'shell:apigen'
]); ]);
// Only an alias to 'default' task.
grunt.registerTask( 'dev', [ grunt.registerTask( 'dev', [
'default', 'default'
]);
grunt.registerTask( 'i18n', [
'checktextdomain',
'makepot' 'makepot'
]); ]);

View File

@ -145,7 +145,7 @@
classes = _.indexBy( model.get( 'classes' ), 'term_id' ), classes = _.indexBy( model.get( 'classes' ), 'term_id' ),
changes = {}, changes = {},
size = _.size( classes ), size = _.size( classes ),
newRow = _.extend( {}, data.default_class, { newRow = _.extend( {}, data.default_shipping_class, {
term_id: 'new-' + size + '-' + Date.now(), term_id: 'new-' + size + '-' + Date.now(),
editing: true, editing: true,
newRow : true newRow : true

View File

@ -9,7 +9,7 @@
}, },
"require-dev": { "require-dev": {
"squizlabs/php_codesniffer": "*", "squizlabs/php_codesniffer": "*",
"wp-coding-standards/wpcs": "0.13.1", "wp-coding-standards/wpcs": "^0.14",
"phpunit/phpunit": "6.2.3", "phpunit/phpunit": "6.2.3",
"woocommerce/woocommerce-git-hooks": "1.0.3", "woocommerce/woocommerce-git-hooks": "1.0.3",
"wimg/php-compatibility": "^8.0", "wimg/php-compatibility": "^8.0",

14
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "9a9c7e81cc3a30935c03b1b2d64c201c", "content-hash": "f8dbe5807f695e87ad3453a8b629b6bf",
"packages": [ "packages": [
{ {
"name": "composer/installers", "name": "composer/installers",
@ -1783,16 +1783,16 @@
}, },
{ {
"name": "wp-coding-standards/wpcs", "name": "wp-coding-standards/wpcs",
"version": "0.13.1", "version": "0.14.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git", "url": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git",
"reference": "1f64b1a0b5b789822d0303436ee4e30e0135e4dc" "reference": "8cadf48fa1c70b2381988e0a79e029e011a8f41c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/WordPress-Coding-Standards/WordPress-Coding-Standards/zipball/1f64b1a0b5b789822d0303436ee4e30e0135e4dc", "url": "https://api.github.com/repos/WordPress-Coding-Standards/WordPress-Coding-Standards/zipball/8cadf48fa1c70b2381988e0a79e029e011a8f41c",
"reference": "1f64b1a0b5b789822d0303436ee4e30e0135e4dc", "reference": "8cadf48fa1c70b2381988e0a79e029e011a8f41c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1800,7 +1800,7 @@
"squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2" "squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2"
}, },
"suggest": { "suggest": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.1" "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3"
}, },
"type": "phpcodesniffer-standard", "type": "phpcodesniffer-standard",
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
@ -1819,7 +1819,7 @@
"standards", "standards",
"wordpress" "wordpress"
], ],
"time": "2017-08-05T16:08:58+00:00" "time": "2017-11-01T15:10:46+00:00"
} }
], ],
"aliases": [], "aliases": [],

View File

@ -285,7 +285,7 @@ abstract class WC_Data {
if ( ! $has_setter_or_getter ) { if ( ! $has_setter_or_getter ) {
return false; return false;
} }
/* translators: %s: $key Key to check */
wc_doing_it_wrong( __FUNCTION__, sprintf( __( 'Generic add/update/get meta methods should not be used for internal meta data, including "%s". Use getters and setters.', 'woocommerce' ), $key ), '3.2.0' ); wc_doing_it_wrong( __FUNCTION__, sprintf( __( 'Generic add/update/get meta methods should not be used for internal meta data, including "%s". Use getters and setters.', 'woocommerce' ), $key ), '3.2.0' );
return true; return true;
@ -400,7 +400,7 @@ abstract class WC_Data {
* @param string $value * @param string $value
* @param int $meta_id * @param int $meta_id
*/ */
public function update_meta_data( $key, $value, $meta_id = '' ) { public function update_meta_data( $key, $value, $meta_id = 0 ) {
if ( $this->is_internal_meta_key( $key ) ) { if ( $this->is_internal_meta_key( $key ) ) {
$function = 'set_' . $key; $function = 'set_' . $key;

View File

@ -1,4 +1,12 @@
<?php <?php
/**
* Abstract deprecated hooks
*
* @package WooCommerce\Abstracts
* @since 3.0.0
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; 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. * 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. * Based on the WCS_Hook_Deprecator class by Prospress.
*
* @since 3.0.0
*/ */
abstract class WC_Deprecated_Hooks { abstract class WC_Deprecated_Hooks {
@ -19,6 +25,13 @@ abstract class WC_Deprecated_Hooks {
*/ */
protected $deprecated_hooks = array(); protected $deprecated_hooks = array();
/**
* Array of versions on each hook has been deprecated.
*
* @var array
*/
protected $deprecated_version = array();
/** /**
* Constructor. * Constructor.
*/ */
@ -30,14 +43,14 @@ abstract class WC_Deprecated_Hooks {
/** /**
* Hook into the new hook so we can handle deprecated hooks once fired. * 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. * Get old hooks to map to new hook.
* *
* @param string $new_hook * @param string $new_hook New hook name.
* @return array * @return array
*/ */
public function get_old_hooks( $new_hook ) { 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. * If the old hook is in-use, trigger it.
* *
* @param string $new_hook * @param string $new_hook New hook name.
* @param string $old_hook * @param string $old_hook Old hook name.
* @param array $new_callback_args * @param array $new_callback_args New callback args.
* @param mixed $return_value * @param mixed $return_value Returned value.
* @return mixed * @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. * Display a deprecated notice for old hooks.
* *
* @param string $old_hook * @param string $old_hook Old hook.
* @param string $new_hook * @param string $new_hook New hook.
*/ */
protected function display_notice( $old_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. * Fire off a legacy hook with it's args.
* *
* @param string $old_hook * @param string $old_hook Old hook name.
* @param array $new_callback_args * @param array $new_callback_args New callback args.
* @return mixed * @return mixed
*/ */
abstract protected function trigger_hook( $old_hook, $new_callback_args ); 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 );
} }
/** /**
@ -1599,7 +1599,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
public function get_subtotal_to_display( $compound = false, $tax_display = '' ) { public function get_subtotal_to_display( $compound = false, $tax_display = '' ) {
$tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' ); $tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' );
$subtotal = 0; $subtotal = 0;
if ( ! $compound ) { if ( ! $compound ) {
foreach ( $this->get_items() as $item ) { foreach ( $this->get_items() as $item ) {
$subtotal += $item->get_subtotal(); $subtotal += $item->get_subtotal();

View File

@ -1520,7 +1520,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
* @return bool * @return bool
*/ */
public function is_shipping_taxable() { public function is_shipping_taxable() {
return $this->get_tax_status() === 'taxable' || $this->get_tax_status() === 'shipping'; return $this->needs_shipping() && ( $this->get_tax_status() === 'taxable' || $this->get_tax_status() === 'shipping' );
} }
/** /**

View File

@ -1664,7 +1664,7 @@ class WC_Admin_Setup_Wizard {
$docs_url = 'https://docs.woocommerce.com/documentation/plugins/woocommerce/getting-started/?utm_source=setupwizard&utm_medium=product&utm_content=docs&utm_campaign=woocommerceplugin'; $docs_url = 'https://docs.woocommerce.com/documentation/plugins/woocommerce/getting-started/?utm_source=setupwizard&utm_medium=product&utm_content=docs&utm_campaign=woocommerceplugin';
$help_text = sprintf( $help_text = sprintf(
/* translators: %1$s: link to videos, %2$s: link to docs */ /* translators: %1$s: link to videos, %2$s: link to docs */
__( 'Watch our <a href="%1$s" target="_blank">guided tour videos</a> to learn more about WooCommerce, and visit WooCommerce.com to learn more about <a href="%2$s" target="_blank">getting started</a>.' ), __( 'Watch our <a href="%1$s" target="_blank">guided tour videos</a> to learn more about WooCommerce, and visit WooCommerce.com to learn more about <a href="%2$s" target="_blank">getting started</a>.', 'woocommerce' ),
$videos_url, $videos_url,
$docs_url $docs_url
); );

View File

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

View File

@ -299,22 +299,29 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
* Render any custom filters and search inputs for the list table. * Render any custom filters and search inputs for the list table.
*/ */
protected function render_filters() { 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. // Category Filtering.
$current_product_type = isset( $_REQUEST['product_type'] ) ? wc_clean( wp_unslash( $_REQUEST['product_type'] ) ) : false; // WPCS: input var ok, sanitization ok. $categories_count = (int) wp_count_terms( 'product_cat' );
// @codingStandardsIgnoreStart
$current_category = $current_category_slug ? get_term_by( 'slug', $current_category_slug, 'product_cat' ): false;
// @codingStandardsIgnoreEnd
?>
<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 ) : ?>
<option value="<?php echo esc_attr( $current_category_slug ); ?>" selected="selected"><?php echo esc_html( $current_category->name ); ?><option>
<?php endif; ?>
</select>
<?php
$terms = get_terms( 'product_type' ); if ( $categories_count <= apply_filters( 'woocommerce_product_category_filter_threshold', 100 ) ) {
$output = '<select name="product_type" id="dropdown_product_type">'; wc_product_dropdown_categories( array(
$output .= '<option value="">' . __( 'Filter by product type', 'woocommerce' ) . '</option>'; '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 ) : ?>
<option value="<?php echo esc_attr( $current_category_slug ); ?>" selected="selected"><?php echo esc_html( $current_category->name ); ?><option>
<?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"><option value="">' . __( 'Filter by product type', 'woocommerce' ) . '</option>';
foreach ( $terms as $term ) { foreach ( $terms as $term ) {
$output .= '<option value="' . sanitize_title( $term->name ) . '" '; $output .= '<option value="' . sanitize_title( $term->name ) . '" ';

View File

@ -284,12 +284,18 @@ class WC_Meta_Box_Product_Data {
$attribute_key = sanitize_title( $attribute->get_name() ); $attribute_key = sanitize_title( $attribute->get_name() );
if ( ! is_null( $index ) ) { if ( ! is_null( $index ) ) {
$value = isset( $_POST[ $key_prefix . $attribute_key ][ $index ] ) ? stripslashes( $_POST[ $key_prefix . $attribute_key ][ $index ] ) : ''; $value = isset( $_POST[ $key_prefix . $attribute_key ][ $index ] ) ? wp_unslash( $_POST[ $key_prefix . $attribute_key ][ $index ] ) : '';
} else { } else {
$value = isset( $_POST[ $key_prefix . $attribute_key ] ) ? stripslashes( $_POST[ $key_prefix . $attribute_key ] ) : ''; $value = isset( $_POST[ $key_prefix . $attribute_key ] ) ? wp_unslash( $_POST[ $key_prefix . $attribute_key ] ) : '';
}
if ( $attribute->is_taxonomy() ) {
// Don't use wc_clean as it destroys sanitized characters.
$value = sanitize_title( $value );
} else {
$value = html_entity_decode( wc_clean( $value ), ENT_QUOTES, get_bloginfo( 'charset' ) ); // WPCS: sanitization ok.
} }
$value = $attribute->is_taxonomy() ? sanitize_title( $value ) : wc_clean( $value ); // Don't use wc_clean as it destroys sanitized characters in terms.
$attributes[ $attribute_key ] = $value; $attributes[ $attribute_key ] = $value;
} }
} }

View File

@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) {
?> ?>
<div class="wc-metabox closed"> <div class="wc-metabox closed">
<h3 class="fixed"> <h3 class="fixed">
<button type="button" data-permission_id="<?php echo esc_attr( $download->get_id() ); ?>" rel="<?php echo esc_attr( $download->get_product_id() ) . ',' . esc_attr( $download->get_download_id() ); ?>" class="revoke_access button"><?php _e( 'Revoke access', 'woocommerce' ); ?></button> <button type="button" data-permission_id="<?php echo esc_attr( $download->get_id() ); ?>" rel="<?php echo esc_attr( $download->get_product_id() ) . ',' . esc_attr( $download->get_download_id() ); ?>" class="revoke_access button"><?php esc_html_e( 'Revoke access', 'woocommerce' ); ?></button>
<div class="handlediv" aria-label="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div> <div class="handlediv" aria-label="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div>
<strong><?php <strong><?php
printf( printf(
@ -16,19 +16,19 @@ if ( ! defined( 'ABSPATH' ) ) {
esc_html( wc_get_filename_from_url( $product->get_file_download_path( $download->get_download_id() ) ) ) esc_html( wc_get_filename_from_url( $product->get_file_download_path( $download->get_download_id() ) ) )
); );
printf( _n( 'Downloaded %s time', 'Downloaded %s times', $download->get_download_count(), 'woocommerce' ), esc_html( $download->get_download_count() ) ) printf( _n( 'Downloaded %s time', 'Downloaded %s times', $download->get_download_count(), 'woocommerce' ), esc_html( $download->get_download_count() ) )
?></strong> ?></strong>
</h3> </h3>
<table cellpadding="0" cellspacing="0" class="wc-metabox-content"> <table cellpadding="0" cellspacing="0" class="wc-metabox-content">
<tbody> <tbody>
<tr> <tr>
<td> <td>
<label><?php esc_html_e( 'Downloads remaining', 'woocommerce' ); ?></label> <label><?php esc_html_e( 'Downloads remaining', 'woocommerce' ); ?></label>
<input type="hidden" name="permission_id[<?php echo $loop; ?>]" value="<?php echo esc_attr( $download->get_id() ); ?>" /> <input type="hidden" name="permission_id[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( $download->get_id() ); ?>" />
<input type="number" step="1" min="0" class="short" name="downloads_remaining[<?php echo $loop; ?>]" value="<?php echo esc_attr( $download->get_downloads_remaining() ); ?>" placeholder="<?php esc_attr_e( 'Unlimited', 'woocommerce' ); ?>" /> <input type="number" step="1" min="0" class="short" name="downloads_remaining[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( $download->get_downloads_remaining() ); ?>" placeholder="<?php esc_attr_e( 'Unlimited', 'woocommerce' ); ?>" />
</td> </td>
<td> <td>
<label><?php esc_html_e( 'Access expires', 'woocommerce' ); ?></label> <label><?php esc_html_e( 'Access expires', 'woocommerce' ); ?></label>
<input type="text" class="short date-picker" name="access_expires[<?php echo $loop; ?>]" value="<?php echo ! is_null( $download->get_access_expires() ) ? date_i18n( 'Y-m-d', $download->get_access_expires()->getTimestamp() ) : ''; ?>" maxlength="10" placeholder="<?php esc_attr_e( 'Never', 'woocommerce' ); ?>" pattern="<?php echo esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ); ?>" /> <input type="text" class="short date-picker" name="access_expires[<?php echo esc_attr( $loop ); ?>]" value="<?php echo ! is_null( $download->get_access_expires() ) ? esc_attr( date_i18n( 'Y-m-d', $download->get_access_expires()->getTimestamp() ) ) : ''; ?>" maxlength="10" placeholder="<?php esc_attr_e( 'Never', 'woocommerce' ); ?>" pattern="<?php echo esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ); ?>" />
</td> </td>
<td> <td>
<label><?php esc_html_e( 'Customer download link', 'woocommerce' ); ?></label> <label><?php esc_html_e( 'Customer download link', 'woocommerce' ); ?></label>

View File

@ -10,7 +10,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
?> ?>
<tr class="fee <?php echo ( ! empty( $class ) ) ? $class : ''; ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>"> <tr class="fee <?php echo ( ! empty( $class ) ) ? esc_attr( $class ) : ''; ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>">
<td class="thumb"><div></div></td> <td class="thumb"><div></div></td>
<td class="name"> <td class="name">
@ -22,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<input type="hidden" class="order_item_id" name="order_item_id[]" value="<?php echo esc_attr( $item_id ); ?>" /> <input type="hidden" class="order_item_id" name="order_item_id[]" value="<?php echo esc_attr( $item_id ); ?>" />
<input type="hidden" name="order_item_tax_class[<?php echo absint( $item_id ); ?>]" value="<?php echo esc_attr( $item->get_tax_class() ); ?>" /> <input type="hidden" name="order_item_tax_class[<?php echo absint( $item_id ); ?>]" value="<?php echo esc_attr( $item->get_tax_class() ); ?>" />
</div> </div>
<?php do_action( 'woocommerce_after_order_fee_item_name', $item_id, $item, null ) ?> <?php do_action( 'woocommerce_after_order_fee_item_name', $item_id, $item, null ); ?>
</td> </td>
<?php do_action( 'woocommerce_admin_order_item_values', null, $item, absint( $item_id ) ); ?> <?php do_action( 'woocommerce_admin_order_item_values', null, $item, absint( $item_id ) ); ?>
@ -41,10 +41,10 @@ if ( ! defined( 'ABSPATH' ) ) {
?> ?>
</div> </div>
<div class="edit" style="display: none;"> <div class="edit" style="display: none;">
<input type="text" name="line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" /> <input type="text" name="line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" />
</div> </div>
<div class="refund" style="display: none;"> <div class="refund" style="display: none;">
<input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_total wc_input_price" /> <input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_total wc_input_price" />
</div> </div>
</td> </td>
@ -65,10 +65,10 @@ if ( ! defined( 'ABSPATH' ) ) {
?> ?>
</div> </div>
<div class="edit" style="display: none;"> <div class="edit" style="display: none;">
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" /> <input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" />
</div> </div>
<div class="refund" style="display: none;"> <div class="refund" style="display: none;">
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" /> <input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
</div> </div>
</td> </td>

View File

@ -18,8 +18,9 @@ $hidden_order_itemmeta = apply_filters( 'woocommerce_hidden_order_itemmeta', arr
?><div class="view"> ?><div class="view">
<?php if ( $meta_data = $item->get_formatted_meta_data( '' ) ) : ?> <?php if ( $meta_data = $item->get_formatted_meta_data( '' ) ) : ?>
<table cellspacing="0" class="display_meta"> <table cellspacing="0" class="display_meta">
<?php foreach ( $meta_data as $meta_id => $meta ) : <?php
if ( in_array( $meta->key, $hidden_order_itemmeta ) ) { foreach ( $meta_data as $meta_id => $meta ) :
if ( in_array( $meta->key, $hidden_order_itemmeta, true ) ) {
continue; continue;
} }
?> ?>
@ -35,8 +36,9 @@ $hidden_order_itemmeta = apply_filters( 'woocommerce_hidden_order_itemmeta', arr
<table class="meta" cellspacing="0"> <table class="meta" cellspacing="0">
<tbody class="meta_items"> <tbody class="meta_items">
<?php if ( $meta_data = $item->get_formatted_meta_data( '' ) ) : ?> <?php if ( $meta_data = $item->get_formatted_meta_data( '' ) ) : ?>
<?php foreach ( $meta_data as $meta_id => $meta ) : <?php
if ( in_array( $meta->key, $hidden_order_itemmeta ) ) { foreach ( $meta_data as $meta_id => $meta ) :
if ( in_array( $meta->key, $hidden_order_itemmeta, true ) ) {
continue; continue;
} }
?> ?>
@ -52,7 +54,7 @@ $hidden_order_itemmeta = apply_filters( 'woocommerce_hidden_order_itemmeta', arr
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<td colspan="4"><button class="add_order_item_meta button"><?php _e( 'Add&nbsp;meta', 'woocommerce' ); ?></button></td> <td colspan="4"><button class="add_order_item_meta button"><?php esc_html_e( 'Add&nbsp;meta', 'woocommerce' ); ?></button></td>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>

View File

@ -12,7 +12,7 @@ $product = $item->get_product();
$product_link = $product ? admin_url( 'post.php?post=' . $item->get_product_id() . '&action=edit' ) : ''; $product_link = $product ? admin_url( 'post.php?post=' . $item->get_product_id() . '&action=edit' ) : '';
$thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnail', $product->get_image( 'thumbnail', array( 'title' => '' ), false ), $item_id, $item ) : ''; $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnail', $product->get_image( 'thumbnail', array( 'title' => '' ), false ), $item_id, $item ) : '';
?> ?>
<tr class="item <?php echo apply_filters( 'woocommerce_admin_html_order_item_class', ( ! empty( $class ) ? $class : '' ), $item, $order ); ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>"> <tr class="item <?php echo esc_attr( apply_filters( 'woocommerce_admin_html_order_item_class', ( ! empty( $class ) ? $class : '' ), $item, $order ) ); ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>">
<td class="thumb"> <td class="thumb">
<?php echo '<div class="wc-order-item-thumbnail">' . wp_kses_post( $thumbnail ) . '</div>'; ?> <?php echo '<div class="wc-order-item-thumbnail">' . wp_kses_post( $thumbnail ) . '</div>'; ?>
</td> </td>
@ -21,11 +21,11 @@ $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnai
echo $product_link ? '<a href="' . esc_url( $product_link ) . '" class="wc-order-item-name">' . esc_html( $item->get_name() ) . '</a>' : '<div class="wc-order-item-name">' . esc_html( $item->get_name() ) . '</div>'; echo $product_link ? '<a href="' . esc_url( $product_link ) . '" class="wc-order-item-name">' . esc_html( $item->get_name() ) . '</a>' : '<div class="wc-order-item-name">' . esc_html( $item->get_name() ) . '</div>';
if ( $product && $product->get_sku() ) { if ( $product && $product->get_sku() ) {
echo '<div class="wc-order-item-sku"><strong>' . __( 'SKU:', 'woocommerce' ) . '</strong> ' . esc_html( $product->get_sku() ) . '</div>'; echo '<div class="wc-order-item-sku"><strong>' . esc_html__( 'SKU:', 'woocommerce' ) . '</strong> ' . esc_html( $product->get_sku() ) . '</div>';
} }
if ( $item->get_variation_id() ) { if ( $item->get_variation_id() ) {
echo '<div class="wc-order-item-variation"><strong>' . __( 'Variation ID:', 'woocommerce' ) . '</strong> '; echo '<div class="wc-order-item-variation"><strong>' . esc_html__( 'Variation ID:', 'woocommerce' ) . '</strong> ';
if ( 'product_variation' === get_post_type( $item->get_variation_id() ) ) { if ( 'product_variation' === get_post_type( $item->get_variation_id() ) ) {
echo esc_html( $item->get_variation_id() ); echo esc_html( $item->get_variation_id() );
} else { } else {
@ -38,9 +38,9 @@ $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnai
<input type="hidden" class="order_item_id" name="order_item_id[]" value="<?php echo esc_attr( $item_id ); ?>" /> <input type="hidden" class="order_item_id" name="order_item_id[]" value="<?php echo esc_attr( $item_id ); ?>" />
<input type="hidden" name="order_item_tax_class[<?php echo absint( $item_id ); ?>]" value="<?php echo esc_attr( $item->get_tax_class() ); ?>" /> <input type="hidden" name="order_item_tax_class[<?php echo absint( $item_id ); ?>]" value="<?php echo esc_attr( $item->get_tax_class() ); ?>" />
<?php do_action( 'woocommerce_before_order_itemmeta', $item_id, $item, $product ) ?> <?php do_action( 'woocommerce_before_order_itemmeta', $item_id, $item, $product ); ?>
<?php include( 'html-order-item-meta.php' ); ?> <?php include( 'html-order-item-meta.php' ); ?>
<?php do_action( 'woocommerce_after_order_itemmeta', $item_id, $item, $product ) ?> <?php do_action( 'woocommerce_after_order_itemmeta', $item_id, $item, $product ); ?>
</td> </td>
<?php do_action( 'woocommerce_admin_order_item_values', $product, $item, absint( $item_id ) ); ?> <?php do_action( 'woocommerce_admin_order_item_values', $product, $item, absint( $item_id ) ); ?>
@ -67,10 +67,10 @@ $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnai
?> ?>
</div> </div>
<div class="edit" style="display: none;"> <div class="edit" style="display: none;">
<input type="number" step="<?php echo apply_filters( 'woocommerce_quantity_input_step', '1', $product ); ?>" min="0" autocomplete="off" name="order_item_qty[<?php echo absint( $item_id ); ?>]" placeholder="0" value="<?php echo esc_attr( $item->get_quantity() ); ?>" data-qty="<?php echo esc_attr( $item->get_quantity() ); ?>" size="4" class="quantity" /> <input type="number" step="<?php echo esc_attr( apply_filters( 'woocommerce_quantity_input_step', '1', $product ) ); ?>" min="0" autocomplete="off" name="order_item_qty[<?php echo absint( $item_id ); ?>]" placeholder="0" value="<?php echo esc_attr( $item->get_quantity() ); ?>" data-qty="<?php echo esc_attr( $item->get_quantity() ); ?>" size="4" class="quantity" />
</div> </div>
<div class="refund" style="display: none;"> <div class="refund" style="display: none;">
<input type="number" step="<?php echo apply_filters( 'woocommerce_quantity_input_step', '1', $product ); ?>" min="0" max="<?php echo $item->get_quantity(); ?>" autocomplete="off" name="refund_order_item_qty[<?php echo absint( $item_id ); ?>]" placeholder="0" size="4" class="refund_order_item_qty" /> <input type="number" step="<?php echo esc_attr( apply_filters( 'woocommerce_quantity_input_step', '1', $product ) ); ?>" min="0" max="<?php echo absint( $item->get_quantity() ); ?>" autocomplete="off" name="refund_order_item_qty[<?php echo absint( $item_id ); ?>]" placeholder="0" size="4" class="refund_order_item_qty" />
</div> </div>
</td> </td>
<td class="line_cost" width="1%" data-sort-value="<?php echo esc_attr( $item->get_total() ); ?>"> <td class="line_cost" width="1%" data-sort-value="<?php echo esc_attr( $item->get_total() ); ?>">
@ -91,16 +91,16 @@ $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnai
<div class="split-input"> <div class="split-input">
<div class="input"> <div class="input">
<label><?php esc_attr_e( 'Pre-discount:', 'woocommerce' ); ?></label> <label><?php esc_attr_e( 'Pre-discount:', 'woocommerce' ); ?></label>
<input type="text" name="line_subtotal[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_subtotal() ) ); ?>" class="line_subtotal wc_input_price" data-subtotal="<?php echo esc_attr( wc_format_localized_price( $item->get_subtotal() ) ); ?>" /> <input type="text" name="line_subtotal[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_subtotal() ) ); ?>" class="line_subtotal wc_input_price" data-subtotal="<?php echo esc_attr( wc_format_localized_price( $item->get_subtotal() ) ); ?>" />
</div> </div>
<div class="input"> <div class="input">
<label><?php esc_attr_e( 'Total:', 'woocommerce' ); ?></label> <label><?php esc_attr_e( 'Total:', 'woocommerce' ); ?></label>
<input type="text" name="line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" data-tip="<?php esc_attr_e( 'After pre-tax discounts.', 'woocommerce' ); ?>" data-total="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" /> <input type="text" name="line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" data-tip="<?php esc_attr_e( 'After pre-tax discounts.', 'woocommerce' ); ?>" data-total="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" />
</div> </div>
</div> </div>
</div> </div>
<div class="refund" style="display: none;"> <div class="refund" style="display: none;">
<input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_total wc_input_price" /> <input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_total wc_input_price" />
</div> </div>
</td> </td>
@ -114,7 +114,7 @@ $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnai
<td class="line_tax" width="1%"> <td class="line_tax" width="1%">
<div class="view"> <div class="view">
<?php <?php
if ( '' != $tax_item_total ) { if ( '' !== $tax_item_total ) {
echo wc_price( wc_round_tax_total( $tax_item_total ), array( 'currency' => $order->get_currency() ) ); echo wc_price( wc_round_tax_total( $tax_item_total ), array( 'currency' => $order->get_currency() ) );
} else { } else {
echo '&ndash;'; echo '&ndash;';
@ -137,16 +137,16 @@ $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnai
<div class="split-input"> <div class="split-input">
<div class="input"> <div class="input">
<label><?php esc_attr_e( 'Pre-discount:', 'woocommerce' ); ?></label> <label><?php esc_attr_e( 'Pre-discount:', 'woocommerce' ); ?></label>
<input type="text" name="line_subtotal_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $tax_item_subtotal ) ); ?>" class="line_subtotal_tax wc_input_price" data-subtotal_tax="<?php echo esc_attr( wc_format_localized_price( $tax_item_subtotal ) ); ?>" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" /> <input type="text" name="line_subtotal_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $tax_item_subtotal ) ); ?>" class="line_subtotal_tax wc_input_price" data-subtotal_tax="<?php echo esc_attr( wc_format_localized_price( $tax_item_subtotal ) ); ?>" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
</div> </div>
<div class="input"> <div class="input">
<label><?php esc_attr_e( 'Total:', 'woocommerce' ); ?></label> <label><?php esc_attr_e( 'Total:', 'woocommerce' ); ?></label>
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $tax_item_total ) ); ?>" class="line_tax wc_input_price" data-total_tax="<?php echo esc_attr( wc_format_localized_price( $tax_item_total ) ); ?>" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" /> <input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $tax_item_total ) ); ?>" class="line_tax wc_input_price" data-total_tax="<?php echo esc_attr( wc_format_localized_price( $tax_item_total ) ); ?>" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
</div> </div>
</div> </div>
</div> </div>
<div class="refund" style="display: none;"> <div class="refund" style="display: none;">
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" /> <input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
</div> </div>
</td> </td>
<?php <?php

View File

@ -26,23 +26,24 @@ if ( wc_tax_enabled() ) {
<table cellpadding="0" cellspacing="0" class="woocommerce_order_items"> <table cellpadding="0" cellspacing="0" class="woocommerce_order_items">
<thead> <thead>
<tr> <tr>
<th class="item sortable" colspan="2" data-sort="string-ins"><?php _e( 'Item', 'woocommerce' ); ?></th> <th class="item sortable" colspan="2" data-sort="string-ins"><?php esc_html_e( 'Item', 'woocommerce' ); ?></th>
<?php do_action( 'woocommerce_admin_order_item_headers', $order ); ?> <?php do_action( 'woocommerce_admin_order_item_headers', $order ); ?>
<th class="item_cost sortable" data-sort="float"><?php _e( 'Cost', 'woocommerce' ); ?></th> <th class="item_cost sortable" data-sort="float"><?php esc_html_e( 'Cost', 'woocommerce' ); ?></th>
<th class="quantity sortable" data-sort="int"><?php _e( 'Qty', 'woocommerce' ); ?></th> <th class="quantity sortable" data-sort="int"><?php esc_html_e( 'Qty', 'woocommerce' ); ?></th>
<th class="line_cost sortable" data-sort="float"><?php _e( 'Total', 'woocommerce' ); ?></th> <th class="line_cost sortable" data-sort="float"><?php esc_html_e( 'Total', 'woocommerce' ); ?></th>
<?php <?php
if ( ! empty( $order_taxes ) ) : if ( ! empty( $order_taxes ) ) :
foreach ( $order_taxes as $tax_id => $tax_item ) : foreach ( $order_taxes as $tax_id => $tax_item ) :
$tax_class = wc_get_tax_class_by_tax_id( $tax_item['rate_id'] ); $tax_class = wc_get_tax_class_by_tax_id( $tax_item['rate_id'] );
$tax_class_name = isset( $classes_options[ $tax_class ] ) ? $classes_options[ $tax_class ] : __( 'Tax', 'woocommerce' ); $tax_class_name = isset( $classes_options[ $tax_class ] ) ? $classes_options[ $tax_class ] : __( 'Tax', 'woocommerce' );
$column_label = ! empty( $tax_item['label'] ) ? $tax_item['label'] : __( 'Tax', 'woocommerce' ); $column_label = ! empty( $tax_item['label'] ) ? $tax_item['label'] : __( 'Tax', 'woocommerce' );
/* translators: %1$s: tax item name %2$s: tax class name */
$column_tip = sprintf( esc_html__( '%1$s (%2$s)', 'woocommerce' ), $tax_item['name'], $tax_class_name ); $column_tip = sprintf( esc_html__( '%1$s (%2$s)', 'woocommerce' ), $tax_item['name'], $tax_class_name );
?> ?>
<th class="line_tax tips" data-tip="<?php echo esc_attr( $column_tip ); ?>"> <th class="line_tax tips" data-tip="<?php echo esc_attr( $column_tip ); ?>">
<?php echo esc_attr( $column_label ); ?> <?php echo esc_attr( $column_label ); ?>
<input type="hidden" class="order-tax-id" name="order_taxes[<?php echo $tax_id; ?>]" value="<?php echo esc_attr( $tax_item['rate_id'] ); ?>"> <input type="hidden" class="order-tax-id" name="order_taxes[<?php echo esc_attr( $tax_id ); ?>]" value="<?php echo esc_attr( $tax_item['rate_id'] ); ?>">
<a class="delete-order-tax" href="#" data-rate_id="<?php echo $tax_id; ?>"></a> <a class="delete-order-tax" href="#" data-rate_id="<?php echo esc_attr( $tax_id ); ?>"></a>
</th> </th>
<?php <?php
endforeach; endforeach;
@ -94,11 +95,11 @@ if ( wc_tax_enabled() ) {
</div> </div>
<div class="wc-order-data-row wc-order-item-bulk-edit" style="display:none;"> <div class="wc-order-data-row wc-order-item-bulk-edit" style="display:none;">
<?php if ( $order->is_editable() ) : ?> <?php if ( $order->is_editable() ) : ?>
<button type="button" class="button bulk-delete-items"><?php _e( 'Delete selected row(s)', 'woocommerce' ); ?></button> <button type="button" class="button bulk-delete-items"><?php esc_html_e( 'Delete selected row(s)', 'woocommerce' ); ?></button>
<?php endif; ?> <?php endif; ?>
<button type="button" class="button bulk-decrease-stock"><?php _e( 'Reduce stock', 'woocommerce' ); ?></button> <button type="button" class="button bulk-decrease-stock"><?php esc_html_e( 'Reduce stock', 'woocommerce' ); ?></button>
<button type="button" class="button bulk-increase-stock"><?php _e( 'Increase stock', 'woocommerce' ); ?></button> <button type="button" class="button bulk-increase-stock"><?php esc_html_e( 'Increase stock', 'woocommerce' ); ?></button>
<?php do_action( 'woocommerce_admin_order_item_bulk_actions', $order ); ?> <?php do_action( 'woocommerce_admin_order_item_bulk_actions', $order ); ?>
</div> </div>
<div class="wc-order-data-row wc-order-totals-items wc-order-items-editable"> <div class="wc-order-data-row wc-order-totals-items wc-order-items-editable">
@ -108,7 +109,7 @@ if ( wc_tax_enabled() ) {
?> ?>
<div class="wc-used-coupons"> <div class="wc-used-coupons">
<ul class="wc_coupon_list"><?php <ul class="wc_coupon_list"><?php
echo '<li><strong>' . __( 'Coupon(s)', 'woocommerce' ) . '</strong></li>'; echo '<li><strong>' . esc_html__( 'Coupon(s)', 'woocommerce' ) . '</strong></li>';
foreach ( $coupons as $item_id => $item ) { foreach ( $coupons as $item_id => $item ) {
$post_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' LIMIT 1;", $item->get_code() ) ); $post_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' LIMIT 1;", $item->get_code() ) );
@ -126,7 +127,7 @@ if ( wc_tax_enabled() ) {
<table class="wc-order-totals"> <table class="wc-order-totals">
<?php if ( 0 < $order->get_total_discount() ) : ?> <?php if ( 0 < $order->get_total_discount() ) : ?>
<tr> <tr>
<td class="label"><?php _e( 'Discount:', 'woocommerce' ); ?></td> <td class="label"><?php esc_html_e( 'Discount:', 'woocommerce' ); ?></td>
<td width="1%"></td> <td width="1%"></td>
<td class="total"> <td class="total">
<?php echo wc_price( $order->get_total_discount(), array( 'currency' => $order->get_currency() ) ); ?> <?php echo wc_price( $order->get_total_discount(), array( 'currency' => $order->get_currency() ) ); ?>
@ -138,10 +139,12 @@ if ( wc_tax_enabled() ) {
<?php if ( $order->get_shipping_methods() ) : ?> <?php if ( $order->get_shipping_methods() ) : ?>
<tr> <tr>
<td class="label"><?php _e( 'Shipping:', 'woocommerce' ); ?></td> <td class="label"><?php esc_html_e( 'Shipping:', 'woocommerce' ); ?></td>
<td width="1%"></td> <td width="1%"></td>
<td class="total"><?php <td class="total">
if ( ( $refunded = $order->get_total_shipping_refunded() ) > 0 ) { <?php
$refunded = $order->get_total_shipping_refunded();
if ( $refunded > 0 ) {
echo '<del>' . strip_tags( wc_price( $order->get_shipping_total(), array( 'currency' => $order->get_currency() ) ) ) . '</del> <ins>' . wc_price( $order->get_shipping_total() - $refunded, array( 'currency' => $order->get_currency() ) ) . '</ins>'; echo '<del>' . strip_tags( wc_price( $order->get_shipping_total(), array( 'currency' => $order->get_currency() ) ) ) . '</del> <ins>' . wc_price( $order->get_shipping_total() - $refunded, array( 'currency' => $order->get_currency() ) ) . '</ins>';
} else { } else {
echo wc_price( $order->get_shipping_total(), array( 'currency' => $order->get_currency() ) ); echo wc_price( $order->get_shipping_total(), array( 'currency' => $order->get_currency() ) );
@ -155,15 +158,18 @@ if ( wc_tax_enabled() ) {
<?php if ( wc_tax_enabled() ) : ?> <?php if ( wc_tax_enabled() ) : ?>
<?php foreach ( $order->get_tax_totals() as $code => $tax ) : ?> <?php foreach ( $order->get_tax_totals() as $code => $tax ) : ?>
<tr> <tr>
<td class="label"><?php echo $tax->label; ?>:</td> <td class="label"><?php echo esc_html( $tax->label ); ?>:</td>
<td width="1%"></td> <td width="1%"></td>
<td class="total"><?php <td class="total">
if ( ( $refunded = $order->get_total_tax_refunded_by_rate_id( $tax->rate_id ) ) > 0 ) { <?php
$refunded = $order->get_total_tax_refunded_by_rate_id( $tax->rate_id );
if ( $refunded > 0 ) {
echo '<del>' . strip_tags( $tax->formatted_amount ) . '</del> <ins>' . wc_price( WC_Tax::round( $tax->amount, wc_get_price_decimals() ) - WC_Tax::round( $refunded, wc_get_price_decimals() ), array( 'currency' => $order->get_currency() ) ) . '</ins>'; echo '<del>' . strip_tags( $tax->formatted_amount ) . '</del> <ins>' . wc_price( WC_Tax::round( $tax->amount, wc_get_price_decimals() ) - WC_Tax::round( $refunded, wc_get_price_decimals() ), array( 'currency' => $order->get_currency() ) ) . '</ins>';
} else { } else {
echo $tax->formatted_amount; echo $tax->formatted_amount;
} }
?></td> ?>
</td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?> <?php endif; ?>
@ -171,7 +177,7 @@ if ( wc_tax_enabled() ) {
<?php do_action( 'woocommerce_admin_order_totals_after_tax', $order->get_id() ); ?> <?php do_action( 'woocommerce_admin_order_totals_after_tax', $order->get_id() ); ?>
<tr> <tr>
<td class="label"><?php _e( 'Total', 'woocommerce' ); ?>:</td> <td class="label"><?php esc_html_e( 'Total', 'woocommerce' ); ?>:</td>
<td width="1%"></td> <td width="1%"></td>
<td class="total"> <td class="total">
<?php echo $order->get_formatted_order_total(); ?> <?php echo $order->get_formatted_order_total(); ?>
@ -182,7 +188,7 @@ if ( wc_tax_enabled() ) {
<?php if ( $order->get_total_refunded() ) : ?> <?php if ( $order->get_total_refunded() ) : ?>
<tr> <tr>
<td class="label refunded-total"><?php _e( 'Refunded', 'woocommerce' ); ?>:</td> <td class="label refunded-total"><?php esc_html_e( 'Refunded', 'woocommerce' ); ?>:</td>
<td width="1%"></td> <td width="1%"></td>
<td class="total refunded-total">-<?php echo wc_price( $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); ?></td> <td class="total refunded-total">-<?php echo wc_price( $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); ?></td>
</tr> </tr>
@ -196,63 +202,63 @@ if ( wc_tax_enabled() ) {
<div class="wc-order-data-row wc-order-bulk-actions wc-order-data-row-toggle"> <div class="wc-order-data-row wc-order-bulk-actions wc-order-data-row-toggle">
<p class="add-items"> <p class="add-items">
<?php if ( $order->is_editable() ) : ?> <?php if ( $order->is_editable() ) : ?>
<button type="button" class="button add-line-item"><?php _e( 'Add item(s)', 'woocommerce' ); ?></button> <button type="button" class="button add-line-item"><?php esc_html_e( 'Add item(s)', 'woocommerce' ); ?></button>
<button type="button" class="button add-coupon"><?php _e( 'Apply coupon', 'woocommerce' ); ?></button> <button type="button" class="button add-coupon"><?php esc_html_e( 'Apply coupon', 'woocommerce' ); ?></button>
<?php else : ?> <?php else : ?>
<span class="description"><?php echo wc_help_tip( __( 'To edit this order change the status back to "Pending"', 'woocommerce' ) ); ?> <?php _e( 'This order is no longer editable.', 'woocommerce' ); ?></span> <span class="description"><?php echo wc_help_tip( __( 'To edit this order change the status back to "Pending"', 'woocommerce' ) ); ?> <?php esc_html_e( 'This order is no longer editable.', 'woocommerce' ); ?></span>
<?php endif; ?> <?php endif; ?>
<?php if ( 0 < $order->get_total() - $order->get_total_refunded() || 0 < absint( $order->get_item_count() - $order->get_item_count_refunded() ) ) : ?> <?php if ( 0 < $order->get_total() - $order->get_total_refunded() || 0 < absint( $order->get_item_count() - $order->get_item_count_refunded() ) ) : ?>
<button type="button" class="button refund-items"><?php _e( 'Refund', 'woocommerce' ); ?></button> <button type="button" class="button refund-items"><?php esc_html_e( 'Refund', 'woocommerce' ); ?></button>
<?php endif; ?> <?php endif; ?>
<?php <?php
// allow adding custom buttons // allow adding custom buttons
do_action( 'woocommerce_order_item_add_action_buttons', $order ); do_action( 'woocommerce_order_item_add_action_buttons', $order );
?> ?>
<?php if ( $order->is_editable() ) : ?> <?php if ( $order->is_editable() ) : ?>
<button type="button" class="button button-primary calculate-action"><?php _e( 'Recalculate', 'woocommerce' ); ?></button> <button type="button" class="button button-primary calculate-action"><?php esc_html_e( 'Recalculate', 'woocommerce' ); ?></button>
<?php endif; ?> <?php endif; ?>
</p> </p>
</div> </div>
<div class="wc-order-data-row wc-order-add-item wc-order-data-row-toggle" style="display:none;"> <div class="wc-order-data-row wc-order-add-item wc-order-data-row-toggle" style="display:none;">
<button type="button" class="button add-order-item"><?php _e( 'Add product(s)', 'woocommerce' ); ?></button> <button type="button" class="button add-order-item"><?php esc_html_e( 'Add product(s)', 'woocommerce' ); ?></button>
<button type="button" class="button add-order-fee"><?php _e( 'Add fee', 'woocommerce' ); ?></button> <button type="button" class="button add-order-fee"><?php esc_html_e( 'Add fee', 'woocommerce' ); ?></button>
<button type="button" class="button add-order-shipping"><?php _e( 'Add shipping', 'woocommerce' ); ?></button> <button type="button" class="button add-order-shipping"><?php esc_html_e( 'Add shipping', 'woocommerce' ); ?></button>
<?php if ( wc_tax_enabled() ) : ?> <?php if ( wc_tax_enabled() ) : ?>
<button type="button" class="button add-order-tax"><?php _e( 'Add tax', 'woocommerce' ); ?></button> <button type="button" class="button add-order-tax"><?php esc_html_e( 'Add tax', 'woocommerce' ); ?></button>
<?php endif; ?> <?php endif; ?>
<?php <?php
// allow adding custom buttons // allow adding custom buttons
do_action( 'woocommerce_order_item_add_line_buttons', $order ); do_action( 'woocommerce_order_item_add_line_buttons', $order );
?> ?>
<button type="button" class="button cancel-action"><?php _e( 'Cancel', 'woocommerce' ); ?></button> <button type="button" class="button cancel-action"><?php esc_html_e( 'Cancel', 'woocommerce' ); ?></button>
<button type="button" class="button button-primary save-action"><?php _e( 'Save', 'woocommerce' ); ?></button> <button type="button" class="button button-primary save-action"><?php esc_html_e( 'Save', 'woocommerce' ); ?></button>
</div> </div>
<?php if ( 0 < $order->get_total() - $order->get_total_refunded() || 0 < absint( $order->get_item_count() - $order->get_item_count_refunded() ) ) : ?> <?php if ( 0 < $order->get_total() - $order->get_total_refunded() || 0 < absint( $order->get_item_count() - $order->get_item_count_refunded() ) ) : ?>
<div class="wc-order-data-row wc-order-refund-items wc-order-data-row-toggle" style="display: none;"> <div class="wc-order-data-row wc-order-refund-items wc-order-data-row-toggle" style="display: none;">
<table class="wc-order-totals"> <table class="wc-order-totals">
<?php if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) : ?> <?php if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) : ?>
<tr> <tr>
<td class="label"><label for="restock_refunded_items"><?php _e( 'Restock refunded items', 'woocommerce' ); ?>:</label></td> <td class="label"><label for="restock_refunded_items"><?php esc_html_e( 'Restock refunded items', 'woocommerce' ); ?>:</label></td>
<td class="total"><input type="checkbox" id="restock_refunded_items" name="restock_refunded_items" checked="checked" /></td> <td class="total"><input type="checkbox" id="restock_refunded_items" name="restock_refunded_items" checked="checked" /></td>
</tr> </tr>
<?php endif; ?> <?php endif; ?>
<tr> <tr>
<td class="label"><?php _e( 'Amount already refunded', 'woocommerce' ); ?>:</td> <td class="label"><?php esc_html_e( 'Amount already refunded', 'woocommerce' ); ?>:</td>
<td class="total">-<?php echo wc_price( $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); ?></td> <td class="total">-<?php echo wc_price( $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); ?></td>
</tr> </tr>
<tr> <tr>
<td class="label"><?php _e( 'Total available to refund', 'woocommerce' ); ?>:</td> <td class="label"><?php esc_html_e( 'Total available to refund', 'woocommerce' ); ?>:</td>
<td class="total"><?php echo wc_price( $order->get_total() - $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); ?></td> <td class="total"><?php echo wc_price( $order->get_total() - $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); ?></td>
</tr> </tr>
<tr> <tr>
<td class="label"><label for="refund_amount"><?php _e( 'Refund amount', 'woocommerce' ); ?>:</label></td> <td class="label"><label for="refund_amount"><?php esc_html_e( 'Refund amount', 'woocommerce' ); ?>:</label></td>
<td class="total"> <td class="total">
<input type="text" id="refund_amount" name="refund_amount" class="wc_input_price" /> <input type="text" id="refund_amount" name="refund_amount" class="wc_input_price" />
<div class="clear"></div> <div class="clear"></div>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="label"><label for="refund_reason"><?php echo wc_help_tip( __( 'Note: the refund reason will be visible by the customer.', 'woocommerce' ) ); ?> <?php _e( 'Reason for refund (optional):', 'woocommerce' ); ?></label></td> <td class="label"><label for="refund_reason"><?php echo wc_help_tip( __( 'Note: the refund reason will be visible by the customer.', 'woocommerce' ) ); ?> <?php esc_html_e( 'Reason for refund (optional):', 'woocommerce' ); ?></label></td>
<td class="total"> <td class="total">
<input type="text" id="refund_reason" name="refund_reason" /> <input type="text" id="refund_reason" name="refund_reason" />
<div class="clear"></div> <div class="clear"></div>
@ -266,9 +272,11 @@ if ( wc_tax_enabled() ) {
$gateway_supports_refunds = false !== $payment_gateway && $payment_gateway->supports( 'refunds' ); $gateway_supports_refunds = false !== $payment_gateway && $payment_gateway->supports( 'refunds' );
$gateway_name = false !== $payment_gateway ? ( ! empty( $payment_gateway->method_title ) ? $payment_gateway->method_title : $payment_gateway->get_title() ) : __( 'Payment gateway', 'woocommerce' ); $gateway_name = false !== $payment_gateway ? ( ! empty( $payment_gateway->method_title ) ? $payment_gateway->method_title : $payment_gateway->get_title() ) : __( 'Payment gateway', 'woocommerce' );
?> ?>
<button type="button" class="button <?php echo $gateway_supports_refunds ? 'button-primary do-api-refund' : 'tips disabled'; ?>" <?php echo $gateway_supports_refunds ? '' : 'data-tip="' . esc_attr__( 'The payment gateway used to place this order does not support automatic refunds.', 'woocommerce' ) . '"'; ?>><?php printf( __( 'Refund %1$s via %2$s', 'woocommerce' ), $refund_amount, $gateway_name ); ?></button> <?php /* translators: refund amount, gateway name */ ?>
<button type="button" class="button button-primary do-manual-refund tips" data-tip="<?php esc_attr_e( 'You will need to manually issue a refund through your payment gateway after using this.', 'woocommerce' ); ?>"><?php printf( __( 'Refund %s manually', 'woocommerce' ), $refund_amount ); ?></button> <button type="button" class="button <?php echo $gateway_supports_refunds ? 'button-primary do-api-refund' : 'tips disabled'; ?>" <?php echo $gateway_supports_refunds ? '' : 'data-tip="' . esc_attr__( 'The payment gateway used to place this order does not support automatic refunds.', 'woocommerce' ) . '"'; ?>><?php printf( esc_html__( 'Refund %1$s via %2$s', 'woocommerce' ), $refund_amount, $gateway_name ); ?></button>
<button type="button" class="button cancel-action"><?php _e( 'Cancel', 'woocommerce' ); ?></button> <?php /* translators: refund amount */ ?>
<button type="button" class="button button-primary do-manual-refund tips" data-tip="<?php esc_attr_e( 'You will need to manually issue a refund through your payment gateway after using this.', 'woocommerce' ); ?>"><?php printf( esc_html__( 'Refund %s manually', 'woocommerce' ), $refund_amount ); ?></button>
<button type="button" class="button cancel-action"><?php esc_html_e( 'Cancel', 'woocommerce' ); ?></button>
<input type="hidden" id="refunded_amount" name="refunded_amount" value="<?php echo esc_attr( $order->get_total_refunded() ); ?>" /> <input type="hidden" id="refunded_amount" name="refunded_amount" value="<?php echo esc_attr( $order->get_total_refunded() ); ?>" />
<div class="clear"></div> <div class="clear"></div>
</div> </div>
@ -280,7 +288,7 @@ if ( wc_tax_enabled() ) {
<div class="wc-backbone-modal-content"> <div class="wc-backbone-modal-content">
<section class="wc-backbone-modal-main" role="main"> <section class="wc-backbone-modal-main" role="main">
<header class="wc-backbone-modal-header"> <header class="wc-backbone-modal-header">
<h1><?php _e( 'Add products', 'woocommerce' ); ?></h1> <h1><?php esc_html_e( 'Add products', 'woocommerce' ); ?></h1>
<button class="modal-close modal-close-link dashicons dashicons-no-alt"> <button class="modal-close modal-close-link dashicons dashicons-no-alt">
<span class="screen-reader-text">Close modal panel</span> <span class="screen-reader-text">Close modal panel</span>
</button> </button>
@ -292,7 +300,7 @@ if ( wc_tax_enabled() ) {
</article> </article>
<footer> <footer>
<div class="inner"> <div class="inner">
<button id="btn-ok" class="button button-primary button-large"><?php _e( 'Add', 'woocommerce' ); ?></button> <button id="btn-ok" class="button button-primary button-large"><?php esc_html_e( 'Add', 'woocommerce' ); ?></button>
</div> </div>
</footer> </footer>
</section> </section>
@ -306,7 +314,7 @@ if ( wc_tax_enabled() ) {
<div class="wc-backbone-modal-content"> <div class="wc-backbone-modal-content">
<section class="wc-backbone-modal-main" role="main"> <section class="wc-backbone-modal-main" role="main">
<header class="wc-backbone-modal-header"> <header class="wc-backbone-modal-header">
<h1><?php _e( 'Add tax', 'woocommerce' ); ?></h1> <h1><?php esc_html_e( 'Add tax', 'woocommerce' ); ?></h1>
<button class="modal-close modal-close-link dashicons dashicons-no-alt"> <button class="modal-close modal-close-link dashicons dashicons-no-alt">
<span class="screen-reader-text">Close modal panel</span> <span class="screen-reader-text">Close modal panel</span>
</button> </button>
@ -317,10 +325,10 @@ if ( wc_tax_enabled() ) {
<thead> <thead>
<tr> <tr>
<th>&nbsp;</th> <th>&nbsp;</th>
<th><?php _e( 'Rate name', 'woocommerce' ); ?></th> <th><?php esc_html_e( 'Rate name', 'woocommerce' ); ?></th>
<th><?php _e( 'Tax class', 'woocommerce' ); ?></th> <th><?php esc_html_e( 'Tax class', 'woocommerce' ); ?></th>
<th><?php _e( 'Rate code', 'woocommerce' ); ?></th> <th><?php esc_html_e( 'Rate code', 'woocommerce' ); ?></th>
<th><?php _e( 'Rate %', 'woocommerce' ); ?></th> <th><?php esc_html_e( 'Rate %', 'woocommerce' ); ?></th>
</tr> </tr>
</thead> </thead>
<?php <?php
@ -341,7 +349,7 @@ if ( wc_tax_enabled() ) {
</table> </table>
<?php if ( absint( $wpdb->get_var( "SELECT COUNT(tax_rate_id) FROM {$wpdb->prefix}woocommerce_tax_rates;" ) ) > 100 ) : ?> <?php if ( absint( $wpdb->get_var( "SELECT COUNT(tax_rate_id) FROM {$wpdb->prefix}woocommerce_tax_rates;" ) ) > 100 ) : ?>
<p> <p>
<label for="manual_tax_rate_id"><?php _e( 'Or, enter tax rate ID:', 'woocommerce' ); ?></label><br/> <label for="manual_tax_rate_id"><?php esc_html_e( 'Or, enter tax rate ID:', 'woocommerce' ); ?></label><br/>
<input type="number" name="manual_tax_rate_id" id="manual_tax_rate_id" step="1" placeholder="<?php esc_attr_e( 'Optional', 'woocommerce' ); ?>" /> <input type="number" name="manual_tax_rate_id" id="manual_tax_rate_id" step="1" placeholder="<?php esc_attr_e( 'Optional', 'woocommerce' ); ?>" />
</p> </p>
<?php endif; ?> <?php endif; ?>
@ -349,7 +357,7 @@ if ( wc_tax_enabled() ) {
</article> </article>
<footer> <footer>
<div class="inner"> <div class="inner">
<button id="btn-ok" class="button button-primary button-large"><?php _e( 'Add', 'woocommerce' ); ?></button> <button id="btn-ok" class="button button-primary button-large"><?php esc_html_e( 'Add', 'woocommerce' ); ?></button>
</div> </div>
</footer> </footer>
</section> </section>

View File

@ -8,7 +8,7 @@ if ( ! defined( 'ABSPATH' ) ) {
*/ */
$who_refunded = new WP_User( $refund->get_refunded_by() ); $who_refunded = new WP_User( $refund->get_refunded_by() );
?> ?>
<tr class="refund <?php echo ( ! empty( $class ) ) ? $class : ''; ?>" data-order_refund_id="<?php echo $refund->get_id(); ?>"> <tr class="refund <?php echo ( ! empty( $class ) ) ? esc_attr( $class ) : ''; ?>" data-order_refund_id="<?php echo esc_attr( $refund->get_id() ); ?>">
<td class="thumb"><div></div></td> <td class="thumb"><div></div></td>
<td class="name"> <td class="name">
@ -16,11 +16,12 @@ $who_refunded = new WP_User( $refund->get_refunded_by() );
if ( $who_refunded->exists() ) { if ( $who_refunded->exists() ) {
printf( printf(
/* translators: 1: refund id 2: refund date 3: username */ /* translators: 1: refund id 2: refund date 3: username */
__( 'Refund #%1$s - %2$s by %3$s', 'woocommerce' ), esc_html__( 'Refund #%1$s - %2$s by %3$s', 'woocommerce' ),
$refund->get_id(), $refund->get_id(),
wc_format_datetime( $refund->get_date_created(), get_option( 'date_format' ) . ', ' . get_option( 'time_format' ) ), wc_format_datetime( $refund->get_date_created(), get_option( 'date_format' ) . ', ' . get_option( 'time_format' ) ),
sprintf( sprintf(
'<abbr class="refund_by" title="%1$s">%2$s</abbr>', '<abbr class="refund_by" title="%1$s">%2$s</abbr>',
/* translators: 1: ID who refunded */
sprintf( esc_attr__( 'ID: %d', 'woocommerce' ), absint( $who_refunded->ID ) ), sprintf( esc_attr__( 'ID: %d', 'woocommerce' ), absint( $who_refunded->ID ) ),
esc_html( $who_refunded->display_name ) esc_html( $who_refunded->display_name )
) )
@ -28,7 +29,7 @@ $who_refunded = new WP_User( $refund->get_refunded_by() );
} else { } else {
printf( printf(
/* translators: 1: refund id 2: refund date */ /* translators: 1: refund id 2: refund date */
__( 'Refund #%1$s - %2$s', 'woocommerce' ), esc_html__( 'Refund #%1$s - %2$s', 'woocommerce' ),
$refund->get_id(), $refund->get_id(),
wc_format_datetime( $refund->get_date_created(), get_option( 'date_format' ) . ', ' . get_option( 'time_format' ) ) wc_format_datetime( $refund->get_date_created(), get_option( 'date_format' ) . ', ' . get_option( 'time_format' ) )
); );

View File

@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
?> ?>
<tr class="shipping <?php echo ( ! empty( $class ) ) ? $class : ''; ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>"> <tr class="shipping <?php echo ( ! empty( $class ) ) ? esc_attr( $class ) : ''; ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>">
<td class="thumb"><div></div></td> <td class="thumb"><div></div></td>
<td class="name"> <td class="name">
@ -21,7 +21,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<input type="text" class="shipping_method_name" placeholder="<?php esc_attr_e( 'Shipping name', 'woocommerce' ); ?>" name="shipping_method_title[<?php echo esc_attr( $item_id ); ?>]" value="<?php echo esc_attr( $item->get_name() ); ?>" /> <input type="text" class="shipping_method_name" placeholder="<?php esc_attr_e( 'Shipping name', 'woocommerce' ); ?>" name="shipping_method_title[<?php echo esc_attr( $item_id ); ?>]" value="<?php echo esc_attr( $item->get_name() ); ?>" />
<select class="shipping_method" name="shipping_method[<?php echo esc_attr( $item_id ); ?>]"> <select class="shipping_method" name="shipping_method[<?php echo esc_attr( $item_id ); ?>]">
<optgroup label="<?php esc_attr_e( 'Shipping method', 'woocommerce' ); ?>"> <optgroup label="<?php esc_attr_e( 'Shipping method', 'woocommerce' ); ?>">
<option value=""><?php _e( 'N/A', 'woocommerce' ); ?></option> <option value=""><?php esc_html_e( 'N/A', 'woocommerce' ); ?></option>
<?php <?php
$found_method = false; $found_method = false;
@ -36,18 +36,18 @@ if ( ! defined( 'ABSPATH' ) ) {
} }
if ( ! $found_method && $item->get_method_id() ) { if ( ! $found_method && $item->get_method_id() ) {
echo '<option value="' . esc_attr( $item->get_method_id() ) . '" selected="selected">' . __( 'Other', 'woocommerce' ) . '</option>'; echo '<option value="' . esc_attr( $item->get_method_id() ) . '" selected="selected">' . esc_html__( 'Other', 'woocommerce' ) . '</option>';
} else { } else {
echo '<option value="other">' . __( 'Other', 'woocommerce' ) . '</option>'; echo '<option value="other">' . esc_html__( 'Other', 'woocommerce' ) . '</option>';
} }
?> ?>
</optgroup> </optgroup>
</select> </select>
</div> </div>
<?php do_action( 'woocommerce_before_order_itemmeta', $item_id, $item, null ) ?> <?php do_action( 'woocommerce_before_order_itemmeta', $item_id, $item, null ); ?>
<?php include( 'html-order-item-meta.php' ); ?> <?php include( 'html-order-item-meta.php' ); ?>
<?php do_action( 'woocommerce_after_order_itemmeta', $item_id, $item, null ) ?> <?php do_action( 'woocommerce_after_order_itemmeta', $item_id, $item, null ); ?>
</td> </td>
<?php do_action( 'woocommerce_admin_order_item_values', null, $item, absint( $item_id ) ); ?> <?php do_action( 'woocommerce_admin_order_item_values', null, $item, absint( $item_id ) ); ?>
@ -59,17 +59,17 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="view"> <div class="view">
<?php <?php
echo wc_price( $item->get_total(), array( 'currency' => $order->get_currency() ) ); echo wc_price( $item->get_total(), array( 'currency' => $order->get_currency() ) );
$refunded = $order->get_total_refunded_for_item( $item_id, 'shipping' );
if ( $refunded = $order->get_total_refunded_for_item( $item_id, 'shipping' ) ) { if ( $refunded ) {
echo '<small class="refunded">-' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>'; echo '<small class="refunded">-' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>';
} }
?> ?>
</div> </div>
<div class="edit" style="display: none;"> <div class="edit" style="display: none;">
<input type="text" name="shipping_cost[<?php echo esc_attr( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" /> <input type="text" name="shipping_cost[<?php echo esc_attr( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" />
</div> </div>
<div class="refund" style="display: none;"> <div class="refund" style="display: none;">
<input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_total wc_input_price" /> <input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_total wc_input_price" />
</div> </div>
</td> </td>
@ -83,17 +83,17 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="view"> <div class="view">
<?php <?php
echo ( '' !== $tax_item_total ) ? wc_price( wc_round_tax_total( $tax_item_total ), array( 'currency' => $order->get_currency() ) ) : '&ndash;'; echo ( '' !== $tax_item_total ) ? wc_price( wc_round_tax_total( $tax_item_total ), array( 'currency' => $order->get_currency() ) ) : '&ndash;';
$refunded = $order->get_tax_refunded_for_item( $item_id, $tax_item_id, 'shipping' );
if ( $refunded = $order->get_tax_refunded_for_item( $item_id, $tax_item_id, 'shipping' ) ) { if ( $refunded ) {
echo '<small class="refunded">-' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>'; echo '<small class="refunded">-' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>';
} }
?> ?>
</div> </div>
<div class="edit" style="display: none;"> <div class="edit" style="display: none;">
<input type="text" name="shipping_taxes[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" /> <input type="text" name="shipping_taxes[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" />
</div> </div>
<div class="refund" style="display: none;"> <div class="refund" style="display: none;">
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" /> <input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
</div> </div>
</td> </td>
<?php <?php

View File

@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) {
?> ?>
<div data-taxonomy="<?php echo esc_attr( $attribute->get_taxonomy() ); ?>" class="woocommerce_attribute wc-metabox closed <?php echo esc_attr( implode( ' ', $metabox_class ) ); ?>" rel="<?php echo esc_attr( $attribute->get_position() ); ?>"> <div data-taxonomy="<?php echo esc_attr( $attribute->get_taxonomy() ); ?>" class="woocommerce_attribute wc-metabox closed <?php echo esc_attr( implode( ' ', $metabox_class ) ); ?>" rel="<?php echo esc_attr( $attribute->get_position() ); ?>">
<h3> <h3>
<a href="#" class="remove_row delete"><?php _e( 'Remove', 'woocommerce' ); ?></a> <a href="#" class="remove_row delete"><?php esc_html_e( 'Remove', 'woocommerce' ); ?></a>
<div class="handlediv" title="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div> <div class="handlediv" title="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div>
<strong class="attribute_name"><?php echo esc_html( wc_attribute_label( $attribute->get_name() ) ); ?></strong> <strong class="attribute_name"><?php echo esc_html( wc_attribute_label( $attribute->get_name() ) ); ?></strong>
</h3> </h3>
@ -14,24 +14,26 @@ if ( ! defined( 'ABSPATH' ) ) {
<tbody> <tbody>
<tr> <tr>
<td class="attribute_name"> <td class="attribute_name">
<label><?php _e( 'Name', 'woocommerce' ); ?>:</label> <label><?php esc_html_e( 'Name', 'woocommerce' ); ?>:</label>
<?php if ( $attribute->is_taxonomy() ) : ?> <?php if ( $attribute->is_taxonomy() ) : ?>
<strong><?php echo esc_html( wc_attribute_label( $attribute->get_name() ) ); ?></strong> <strong><?php echo esc_html( wc_attribute_label( $attribute->get_name() ) ); ?></strong>
<input type="hidden" name="attribute_names[<?php echo $i; ?>]" value="<?php echo esc_attr( $attribute->get_name() ); ?>" /> <input type="hidden" name="attribute_names[<?php echo esc_attr( $i ); ?>]" value="<?php echo esc_attr( $attribute->get_name() ); ?>" />
<?php else : ?> <?php else : ?>
<input type="text" class="attribute_name" name="attribute_names[<?php echo $i; ?>]" value="<?php echo esc_attr( $attribute->get_name() ); ?>" /> <input type="text" class="attribute_name" name="attribute_names[<?php echo esc_attr( $i ); ?>]" value="<?php echo esc_attr( $attribute->get_name() ); ?>" />
<?php endif; ?> <?php endif; ?>
<input type="hidden" name="attribute_position[<?php echo $i; ?>]" class="attribute_position" value="<?php echo esc_attr( $attribute->get_position() ); ?>" /> <input type="hidden" name="attribute_position[<?php echo esc_attr( $i ); ?>]" class="attribute_position" value="<?php echo esc_attr( $attribute->get_position() ); ?>" />
</td> </td>
<td rowspan="3"> <td rowspan="3">
<label><?php _e( 'Value(s)', 'woocommerce' ); ?>:</label> <label><?php esc_html_e( 'Value(s)', 'woocommerce' ); ?>:</label>
<?php if ( $attribute->is_taxonomy() && ( $attribute_taxonomy = $attribute->get_taxonomy_object() ) ) : ?> <?php
if ( $attribute->is_taxonomy() && $attribute_taxonomy = $attribute->get_taxonomy_object() ) :
?>
<?php if ( 'select' === $attribute_taxonomy->attribute_type ) : ?> <?php if ( 'select' === $attribute_taxonomy->attribute_type ) : ?>
<select multiple="multiple" data-placeholder="<?php esc_attr_e( 'Select terms', 'woocommerce' ); ?>" class="multiselect attribute_values wc-enhanced-select" name="attribute_values[<?php echo $i; ?>][]"> <select multiple="multiple" data-placeholder="<?php esc_attr_e( 'Select terms', 'woocommerce' ); ?>" class="multiselect attribute_values wc-enhanced-select" name="attribute_values[<?php echo esc_attr( $i ); ?>][]">
<?php <?php
$args = array( $args = array(
'orderby' => 'name', 'orderby' => 'name',
@ -42,18 +44,18 @@ if ( ! defined( 'ABSPATH' ) ) {
foreach ( $all_terms as $term ) { foreach ( $all_terms as $term ) {
$options = $attribute->get_options(); $options = $attribute->get_options();
$options = ! empty( $options ) ? $options : array(); $options = ! empty( $options ) ? $options : array();
echo '<option value="' . esc_attr( $term->term_id ) . '" ' . selected( in_array( $term->term_id, $options ), true, false ) . '>' . esc_attr( apply_filters( 'woocommerce_product_attribute_term_name', $term->name, $term ) ) . '</option>'; echo '<option value="' . esc_attr( $term->term_id ) . '" ' . selected( in_array( $term->term_id, $options, true ), true, false ) . '>' . esc_attr( apply_filters( 'woocommerce_product_attribute_term_name', $term->name, $term ) ) . '</option>';
} }
} }
?> ?>
</select> </select>
<button class="button plus select_all_attributes"><?php _e( 'Select all', 'woocommerce' ); ?></button> <button class="button plus select_all_attributes"><?php esc_html_e( 'Select all', 'woocommerce' ); ?></button>
<button class="button minus select_no_attributes"><?php _e( 'Select none', 'woocommerce' ); ?></button> <button class="button minus select_no_attributes"><?php esc_html_e( 'Select none', 'woocommerce' ); ?></button>
<button class="button fr plus add_new_attribute"><?php _e( 'Add new', 'woocommerce' ); ?></button> <button class="button fr plus add_new_attribute"><?php esc_html_e( 'Add new', 'woocommerce' ); ?></button>
<?php elseif ( 'text' == $attribute_taxonomy->attribute_type ) : ?> <?php elseif ( 'text' === $attribute_taxonomy->attribute_type ) : ?>
<input type="text" name="attribute_values[<?php echo $i; ?>]" value="<?php <input type="text" name="attribute_values[<?php echo esc_attr( $i ); ?>]" value="<?php
// Text attributes should list terms pipe separated // Text attributes should list terms pipe separated
echo esc_attr( wc_implode_text_attributes( wp_list_pluck( $attribute->get_terms(), 'name' ) ) ); echo esc_attr( wc_implode_text_attributes( wp_list_pluck( $attribute->get_terms(), 'name' ) ) );
@ -70,21 +72,21 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php do_action( 'woocommerce_product_option_terms', $attribute_taxonomy, $i ); ?> <?php do_action( 'woocommerce_product_option_terms', $attribute_taxonomy, $i ); ?>
<?php else : ?> <?php else : ?>
<?php /* translators: %s: WC_DELIMITER */ ?>
<textarea name="attribute_values[<?php echo $i; ?>]" cols="5" rows="5" placeholder="<?php printf( esc_attr__( 'Enter some text, or some attributes by "%s" separating values.', 'woocommerce' ), WC_DELIMITER ); ?>"><?php echo esc_textarea( wc_implode_text_attributes( $attribute->get_options() ) ); ?></textarea> <textarea name="attribute_values[<?php echo esc_attr( $i ); ?>]" cols="5" rows="5" placeholder="<?php printf( esc_attr__( 'Enter some text, or some attributes by "%s" separating values.', 'woocommerce' ), WC_DELIMITER ); ?>"><?php echo esc_textarea( wc_implode_text_attributes( $attribute->get_options() ) ); ?></textarea>
<?php endif; ?> <?php endif; ?>
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<label><input type="checkbox" class="checkbox" <?php checked( $attribute->get_visible(), true ); ?> name="attribute_visibility[<?php echo $i; ?>]" value="1" /> <?php _e( 'Visible on the product page', 'woocommerce' ); ?></label> <label><input type="checkbox" class="checkbox" <?php checked( $attribute->get_visible(), true ); ?> name="attribute_visibility[<?php echo esc_attr( $i ); ?>]" value="1" /> <?php esc_html_e( 'Visible on the product page', 'woocommerce' ); ?></label>
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<div class="enable_variation show_if_variable"> <div class="enable_variation show_if_variable">
<label><input type="checkbox" class="checkbox" <?php checked( $attribute->get_variation(), true ); ?> name="attribute_variation[<?php echo $i; ?>]" value="1" /> <?php _e( 'Used for variations', 'woocommerce' ); ?></label> <label><input type="checkbox" class="checkbox" <?php checked( $attribute->get_variation(), true ); ?> name="attribute_variation[<?php echo esc_attr( $i ); ?>]" value="1" /> <?php esc_html_e( 'Used for variations', 'woocommerce' ); ?></label>
</div> </div>
</td> </td>
</tr> </tr>

View File

@ -6,10 +6,10 @@ if ( ! defined( 'ABSPATH' ) ) {
<div id="product_attributes" class="panel wc-metaboxes-wrapper hidden"> <div id="product_attributes" class="panel wc-metaboxes-wrapper hidden">
<div class="toolbar toolbar-top"> <div class="toolbar toolbar-top">
<span class="expand-close"> <span class="expand-close">
<a href="#" class="expand_all"><?php _e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php _e( 'Close', 'woocommerce' ); ?></a> <a href="#" class="expand_all"><?php esc_html_e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php esc_html_e( 'Close', 'woocommerce' ); ?></a>
</span> </span>
<select name="attribute_taxonomy" class="attribute_taxonomy"> <select name="attribute_taxonomy" class="attribute_taxonomy">
<option value=""><?php _e( 'Custom product attribute', 'woocommerce' ); ?></option> <option value=""><?php esc_html_e( 'Custom product attribute', 'woocommerce' ); ?></option>
<?php <?php
global $wc_product_attributes; global $wc_product_attributes;
@ -25,7 +25,7 @@ if ( ! defined( 'ABSPATH' ) ) {
} }
?> ?>
</select> </select>
<button type="button" class="button add_attribute"><?php _e( 'Add', 'woocommerce' ); ?></button> <button type="button" class="button add_attribute"><?php esc_html_e( 'Add', 'woocommerce' ); ?></button>
</div> </div>
<div class="product_attributes wc-metaboxes"> <div class="product_attributes wc-metaboxes">
<?php <?php
@ -48,9 +48,9 @@ if ( ! defined( 'ABSPATH' ) ) {
</div> </div>
<div class="toolbar"> <div class="toolbar">
<span class="expand-close"> <span class="expand-close">
<a href="#" class="expand_all"><?php _e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php _e( 'Close', 'woocommerce' ); ?></a> <a href="#" class="expand_all"><?php esc_html_e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php esc_html_e( 'Close', 'woocommerce' ); ?></a>
</span> </span>
<button type="button" class="button save_attributes button-primary"><?php _e( 'Save attributes', 'woocommerce' ); ?></button> <button type="button" class="button save_attributes button-primary"><?php esc_html_e( 'Save attributes', 'woocommerce' ); ?></button>
</div> </div>
<?php do_action( 'woocommerce_product_options_attributes' ); ?> <?php do_action( 'woocommerce_product_options_attributes' ); ?>
</div> </div>

View File

@ -46,10 +46,10 @@ if ( ! defined( 'ABSPATH' ) ) {
$sale_price_dates_to = $product_object->get_date_on_sale_to( 'edit' ) && ( $date = $product_object->get_date_on_sale_to( 'edit' )->getOffsetTimestamp() ) ? date_i18n( 'Y-m-d', $date ) : ''; $sale_price_dates_to = $product_object->get_date_on_sale_to( 'edit' ) && ( $date = $product_object->get_date_on_sale_to( 'edit' )->getOffsetTimestamp() ) ? date_i18n( 'Y-m-d', $date ) : '';
echo '<p class="form-field sale_price_dates_fields"> echo '<p class="form-field sale_price_dates_fields">
<label for="_sale_price_dates_from">' . __( 'Sale price dates', 'woocommerce' ) . '</label> <label for="_sale_price_dates_from">' . esc_html__( 'Sale price dates', 'woocommerce' ) . '</label>
<input type="text" class="short" name="_sale_price_dates_from" id="_sale_price_dates_from" value="' . esc_attr( $sale_price_dates_from ) . '" placeholder="' . _x( 'From&hellip;', 'placeholder', 'woocommerce' ) . ' YYYY-MM-DD" maxlength="10" pattern="' . esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ) . '" /> <input type="text" class="short" name="_sale_price_dates_from" id="_sale_price_dates_from" value="' . esc_attr( $sale_price_dates_from ) . '" placeholder="' . esc_html( _x( 'From&hellip;', 'placeholder', 'woocommerce' ) ) . ' YYYY-MM-DD" maxlength="10" pattern="' . esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ) . '" />
<input type="text" class="short" name="_sale_price_dates_to" id="_sale_price_dates_to" value="' . esc_attr( $sale_price_dates_to ) . '" placeholder="' . _x( 'To&hellip;', 'placeholder', 'woocommerce' ) . ' YYYY-MM-DD" maxlength="10" pattern="' . esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ) . '" /> <input type="text" class="short" name="_sale_price_dates_to" id="_sale_price_dates_to" value="' . esc_attr( $sale_price_dates_to ) . '" placeholder="' . esc_html( _x( 'To&hellip;', 'placeholder', 'woocommerce' ) ) . ' YYYY-MM-DD" maxlength="10" pattern="' . esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ) . '" />
<a href="#" class="description cancel_sale_schedule">' . __( 'Cancel', 'woocommerce' ) . '</a>' . wc_help_tip( __( 'The sale will end at the beginning of the set date.', 'woocommerce' ) ) . ' <a href="#" class="description cancel_sale_schedule">' . esc_html__( 'Cancel', 'woocommerce' ) . '</a>' . wc_help_tip( __( 'The sale will end at the beginning of the set date.', 'woocommerce' ) ) . '
</p>'; </p>';
do_action( 'woocommerce_product_options_pricing' ); do_action( 'woocommerce_product_options_pricing' );
@ -58,19 +58,20 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="options_group show_if_downloadable hidden"> <div class="options_group show_if_downloadable hidden">
<div class="form-field downloadable_files"> <div class="form-field downloadable_files">
<label><?php _e( 'Downloadable files', 'woocommerce' ); ?></label> <label><?php esc_html_e( 'Downloadable files', 'woocommerce' ); ?></label>
<table class="widefat"> <table class="widefat">
<thead> <thead>
<tr> <tr>
<th class="sort">&nbsp;</th> <th class="sort">&nbsp;</th>
<th><?php _e( 'Name', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the name of the download shown to the customer.', 'woocommerce' ) ); ?></th> <th><?php esc_html_e( 'Name', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the name of the download shown to the customer.', 'woocommerce' ) ); ?></th>
<th colspan="2"><?php _e( 'File URL', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the URL or absolute path to the file which customers will get access to. URLs entered here should already be encoded.', 'woocommerce' ) ); ?></th> <th colspan="2"><?php esc_html_e( 'File URL', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the URL or absolute path to the file which customers will get access to. URLs entered here should already be encoded.', 'woocommerce' ) ); ?></th>
<th>&nbsp;</th> <th>&nbsp;</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php <?php
if ( $downloadable_files = $product_object->get_downloads( 'edit' ) ) { $downloadable_files = $product_object->get_downloads( 'edit' );
if ( $downloadable_files ) {
foreach ( $downloadable_files as $key => $file ) { foreach ( $downloadable_files as $key => $file ) {
include( 'html-product-download.php' ); include( 'html-product-download.php' );
} }
@ -89,7 +90,7 @@ if ( ! defined( 'ABSPATH' ) ) {
ob_start(); ob_start();
include( 'html-product-download.php' ); include( 'html-product-download.php' );
echo esc_attr( ob_get_clean() ); echo esc_attr( ob_get_clean() );
?>"><?php _e( 'Add File', 'woocommerce' ); ?></a> ?>"><?php esc_html_e( 'Add File', 'woocommerce' ); ?></a>
</th> </th>
</tr> </tr>
</tfoot> </tfoot>

View File

@ -11,7 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) {
woocommerce_wp_text_input( array( woocommerce_wp_text_input( array(
'id' => '_sku', 'id' => '_sku',
'value' => $product_object->get_sku( 'edit' ), 'value' => $product_object->get_sku( 'edit' ),
'label' => '<abbr title="' . __( 'Stock Keeping Unit', 'woocommerce' ) . '">' . __( 'SKU', 'woocommerce' ) . '</abbr>', 'label' => '<abbr title="' . esc_attr__( 'Stock Keeping Unit', 'woocommerce' ) . '">' . esc_html__( 'SKU', 'woocommerce' ) . '</abbr>',
'desc_tip' => true, 'desc_tip' => true,
'description' => __( 'SKU refers to a Stock-keeping unit, a unique identifier for each distinct product and service that can be purchased.', 'woocommerce' ), 'description' => __( 'SKU refers to a Stock-keeping unit, a unique identifier for each distinct product and service that can be purchased.', 'woocommerce' ),
) ); ) );

View File

@ -7,7 +7,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="options_group show_if_grouped"> <div class="options_group show_if_grouped">
<p class="form-field"> <p class="form-field">
<label for="grouped_products"><?php _e( 'Grouped products', 'woocommerce' ); ?></label> <label for="grouped_products"><?php esc_html_e( 'Grouped products', 'woocommerce' ); ?></label>
<select class="wc-product-search" multiple="multiple" style="width: 50%;" id="grouped_products" name="grouped_products[]" data-sortable="true" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products" data-exclude="<?php echo intval( $post->ID ); ?>"> <select class="wc-product-search" multiple="multiple" style="width: 50%;" id="grouped_products" name="grouped_products[]" data-sortable="true" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products" data-exclude="<?php echo intval( $post->ID ); ?>">
<?php <?php
$product_ids = $product_object->get_children( 'edit' ); $product_ids = $product_object->get_children( 'edit' );
@ -25,7 +25,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="options_group"> <div class="options_group">
<p class="form-field"> <p class="form-field">
<label for="upsell_ids"><?php _e( 'Upsells', 'woocommerce' ); ?></label> <label for="upsell_ids"><?php esc_html_e( 'Upsells', 'woocommerce' ); ?></label>
<select class="wc-product-search" multiple="multiple" style="width: 50%;" id="upsell_ids" name="upsell_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations" data-exclude="<?php echo intval( $post->ID ); ?>"> <select class="wc-product-search" multiple="multiple" style="width: 50%;" id="upsell_ids" name="upsell_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations" data-exclude="<?php echo intval( $post->ID ); ?>">
<?php <?php
$product_ids = $product_object->get_upsell_ids( 'edit' ); $product_ids = $product_object->get_upsell_ids( 'edit' );
@ -41,7 +41,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</p> </p>
<p class="form-field hide_if_grouped hide_if_external"> <p class="form-field hide_if_grouped hide_if_external">
<label for="crosssell_ids"><?php _e( 'Cross-sells', 'woocommerce' ); ?></label> <label for="crosssell_ids"><?php esc_html_e( 'Cross-sells', 'woocommerce' ); ?></label>
<select class="wc-product-search" multiple="multiple" style="width: 50%;" id="crosssell_ids" name="crosssell_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations" data-exclude="<?php echo intval( $post->ID ); ?>"> <select class="wc-product-search" multiple="multiple" style="width: 50%;" id="crosssell_ids" name="crosssell_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations" data-exclude="<?php echo intval( $post->ID ); ?>">
<?php <?php
$product_ids = $product_object->get_cross_sell_ids( 'edit' ); $product_ids = $product_object->get_cross_sell_ids( 'edit' );

View File

@ -32,8 +32,8 @@ if ( ! defined( 'ABSPATH' ) ) {
<ul class="product_data_tabs wc-tabs"> <ul class="product_data_tabs wc-tabs">
<?php foreach ( self::get_product_data_tabs() as $key => $tab ) : ?> <?php foreach ( self::get_product_data_tabs() as $key => $tab ) : ?>
<li class="<?php echo $key; ?>_options <?php echo $key; ?>_tab <?php echo esc_attr( isset( $tab['class'] ) ? implode( ' ' , (array) $tab['class'] ) : '' ); ?>"> <li class="<?php echo esc_attr( $key ); ?>_options <?php echo esc_attr( $key ); ?>_tab <?php echo esc_attr( isset( $tab['class'] ) ? implode( ' ' , (array) $tab['class'] ) : '' ); ?>">
<a href="#<?php echo $tab['target']; ?>"><span><?php echo esc_html( $tab['label'] ); ?></span></a> <a href="#<?php echo esc_attr( $tab['target'] ); ?>"><span><?php echo esc_html( $tab['label'] ); ?></span></a>
</li> </li>
<?php endforeach; ?> <?php endforeach; ?>
<?php do_action( 'woocommerce_product_write_panel_tabs' ); ?> <?php do_action( 'woocommerce_product_write_panel_tabs' ); ?>

View File

@ -21,6 +21,7 @@ if ( ! defined( 'ABSPATH' ) ) {
if ( wc_product_dimensions_enabled() ) { if ( wc_product_dimensions_enabled() ) {
?><p class="form-field dimensions_field"> ?><p class="form-field dimensions_field">
<?php /* translators: WooCommerce dimension unit*/ ?>
<label for="product_length"><?php printf( __( 'Dimensions (%s)', 'woocommerce' ), get_option( 'woocommerce_dimension_unit' ) ); ?></label> <label for="product_length"><?php printf( __( 'Dimensions (%s)', 'woocommerce' ), get_option( 'woocommerce_dimension_unit' ) ); ?></label>
<span class="wrap"> <span class="wrap">
<input id="product_length" placeholder="<?php esc_attr_e( 'Length', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="_length" value="<?php echo esc_attr( wc_format_localized_decimal( $product_object->get_length( 'edit' ) ) ); ?>" /> <input id="product_length" placeholder="<?php esc_attr_e( 'Length', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="_length" value="<?php echo esc_attr( wc_format_localized_decimal( $product_object->get_length( 'edit' ) ) ); ?>" />
@ -47,7 +48,7 @@ if ( ! defined( 'ABSPATH' ) ) {
'class' => 'select short', 'class' => 'select short',
); );
?><p class="form-field dimensions_field"> ?><p class="form-field dimensions_field">
<label for="product_shipping_class"><?php _e( 'Shipping class', 'woocommerce' ); ?></label> <label for="product_shipping_class"><?php esc_html_e( 'Shipping class', 'woocommerce' ); ?></label>
<?php wp_dropdown_categories( $args ); ?> <?php wp_dropdown_categories( $args ); ?>
<?php echo wc_help_tip( __( 'Shipping classes are used by certain shipping methods to group similar products.', 'woocommerce' ) ); ?> <?php echo wc_help_tip( __( 'Shipping classes are used by certain shipping methods to group similar products.', 'woocommerce' ) ); ?>
</p><?php </p><?php

View File

@ -9,20 +9,21 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( ! count( $variation_attributes ) ) : ?> <?php if ( ! count( $variation_attributes ) ) : ?>
<div id="message" class="inline notice woocommerce-message"> <div id="message" class="inline notice woocommerce-message">
<p><?php _e( 'Before you can add a variation you need to add some variation attributes on the <strong>Attributes</strong> tab.', 'woocommerce' ); ?></p> <p><?php esc_html_e( 'Before you can add a variation you need to add some variation attributes on the <strong>Attributes</strong> tab.', 'woocommerce' ); ?></p>
<p><a class="button-primary" href="<?php echo esc_url( apply_filters( 'woocommerce_docs_url', 'https://docs.woocommerce.com/document/variable-product/', 'product-variations' ) ); ?>" target="_blank"><?php _e( 'Learn more', 'woocommerce' ); ?></a></p> <p><a class="button-primary" href="<?php echo esc_url( apply_filters( 'woocommerce_docs_url', 'https://docs.woocommerce.com/document/variable-product/', 'product-variations' ) ); ?>" target="_blank"><?php esc_html_e( 'Learn more', 'woocommerce' ); ?></a></p>
</div> </div>
<?php else : ?> <?php else : ?>
<div class="toolbar toolbar-variations-defaults"> <div class="toolbar toolbar-variations-defaults">
<div class="variations-defaults"> <div class="variations-defaults">
<strong><?php _e( 'Default Form Values', 'woocommerce' ); ?>: <?php echo wc_help_tip( __( 'These are the attributes that will be pre-selected on the frontend.', 'woocommerce' ) ); ?></strong> <strong><?php esc_html_e( 'Default Form Values', 'woocommerce' ); ?>: <?php echo wc_help_tip( __( 'These are the attributes that will be pre-selected on the frontend.', 'woocommerce' ) ); ?></strong>
<?php <?php
foreach ( $variation_attributes as $attribute ) { foreach ( $variation_attributes as $attribute ) {
$selected_value = isset( $default_attributes[ sanitize_title( $attribute->get_name() ) ] ) ? $default_attributes[ sanitize_title( $attribute->get_name() ) ] : ''; $selected_value = isset( $default_attributes[ sanitize_title( $attribute->get_name() ) ] ) ? $default_attributes[ sanitize_title( $attribute->get_name() ) ] : '';
?> ?>
<select name="default_attribute_<?php echo sanitize_title( $attribute->get_name() ); ?>" data-current="<?php echo esc_attr( $selected_value ); ?>"> <select name="default_attribute_<?php echo sanitize_title( $attribute->get_name() ); ?>" data-current="<?php echo esc_attr( $selected_value ); ?>">
<?php /* translators: WooCommerce attribute label */ ?>
<option value=""><?php printf( esc_html__( 'No default %s&hellip;', 'woocommerce' ), wc_attribute_label( $attribute->get_name() ) ); ?></option> <option value=""><?php printf( esc_html__( 'No default %s&hellip;', 'woocommerce' ), wc_attribute_label( $attribute->get_name() ) ); ?></option>
<?php if ( $attribute->is_taxonomy() ) : ?> <?php if ( $attribute->is_taxonomy() ) : ?>
<?php foreach ( $attribute->get_terms() as $option ) : ?> <?php foreach ( $attribute->get_terms() as $option ) : ?>
@ -43,59 +44,60 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="toolbar toolbar-top"> <div class="toolbar toolbar-top">
<select id="field_to_edit" class="variation_actions"> <select id="field_to_edit" class="variation_actions">
<option data-global="true" value="add_variation"><?php _e( 'Add variation', 'woocommerce' ); ?></option> <option data-global="true" value="add_variation"><?php esc_html_e( 'Add variation', 'woocommerce' ); ?></option>
<option data-global="true" value="link_all_variations"><?php _e( 'Create variations from all attributes', 'woocommerce' ); ?></option> <option data-global="true" value="link_all_variations"><?php esc_html_e( 'Create variations from all attributes', 'woocommerce' ); ?></option>
<option value="delete_all"><?php _e( 'Delete all variations', 'woocommerce' ); ?></option> <option value="delete_all"><?php esc_html_e( 'Delete all variations', 'woocommerce' ); ?></option>
<optgroup label="<?php esc_attr_e( 'Status', 'woocommerce' ); ?>"> <optgroup label="<?php esc_attr_e( 'Status', 'woocommerce' ); ?>">
<option value="toggle_enabled"><?php _e( 'Toggle &quot;Enabled&quot;', 'woocommerce' ); ?></option> <option value="toggle_enabled"><?php esc_html_e( 'Toggle &quot;Enabled&quot;', 'woocommerce' ); ?></option>
<option value="toggle_downloadable"><?php _e( 'Toggle &quot;Downloadable&quot;', 'woocommerce' ); ?></option> <option value="toggle_downloadable"><?php esc_html_e( 'Toggle &quot;Downloadable&quot;', 'woocommerce' ); ?></option>
<option value="toggle_virtual"><?php _e( 'Toggle &quot;Virtual&quot;', 'woocommerce' ); ?></option> <option value="toggle_virtual"><?php esc_html_e( 'Toggle &quot;Virtual&quot;', 'woocommerce' ); ?></option>
</optgroup> </optgroup>
<optgroup label="<?php esc_attr_e( 'Pricing', 'woocommerce' ); ?>"> <optgroup label="<?php esc_attr_e( 'Pricing', 'woocommerce' ); ?>">
<option value="variable_regular_price"><?php _e( 'Set regular prices', 'woocommerce' ); ?></option> <option value="variable_regular_price"><?php esc_html_e( 'Set regular prices', 'woocommerce' ); ?></option>
<option value="variable_regular_price_increase"><?php _e( 'Increase regular prices (fixed amount or percentage)', 'woocommerce' ); ?></option> <option value="variable_regular_price_increase"><?php esc_html_e( 'Increase regular prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
<option value="variable_regular_price_decrease"><?php _e( 'Decrease regular prices (fixed amount or percentage)', 'woocommerce' ); ?></option> <option value="variable_regular_price_decrease"><?php esc_html_e( 'Decrease regular prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
<option value="variable_sale_price"><?php _e( 'Set sale prices', 'woocommerce' ); ?></option> <option value="variable_sale_price"><?php esc_html_e( 'Set sale prices', 'woocommerce' ); ?></option>
<option value="variable_sale_price_increase"><?php _e( 'Increase sale prices (fixed amount or percentage)', 'woocommerce' ); ?></option> <option value="variable_sale_price_increase"><?php esc_html_e( 'Increase sale prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
<option value="variable_sale_price_decrease"><?php _e( 'Decrease sale prices (fixed amount or percentage)', 'woocommerce' ); ?></option> <option value="variable_sale_price_decrease"><?php esc_html_e( 'Decrease sale prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
<option value="variable_sale_schedule"><?php _e( 'Set scheduled sale dates', 'woocommerce' ); ?></option> <option value="variable_sale_schedule"><?php esc_html_e( 'Set scheduled sale dates', 'woocommerce' ); ?></option>
</optgroup> </optgroup>
<optgroup label="<?php esc_attr_e( 'Inventory', 'woocommerce' ); ?>"> <optgroup label="<?php esc_attr_e( 'Inventory', 'woocommerce' ); ?>">
<option value="toggle_manage_stock"><?php _e( 'Toggle &quot;Manage stock&quot;', 'woocommerce' ); ?></option> <option value="toggle_manage_stock"><?php esc_html_e( 'Toggle &quot;Manage stock&quot;', 'woocommerce' ); ?></option>
<option value="variable_stock"><?php _e( 'Stock', 'woocommerce' ); ?></option> <option value="variable_stock"><?php esc_html_e( 'Stock', 'woocommerce' ); ?></option>
<option value="variable_stock_status_instock"><?php _e( 'Set Status - In stock', 'woocommerce' ); ?></option> <option value="variable_stock_status_instock"><?php esc_html_e( 'Set Status - In stock', 'woocommerce' ); ?></option>
<option value="variable_stock_status_outofstock"><?php _e( 'Set Status - Out of stock', 'woocommerce' ); ?></option> <option value="variable_stock_status_outofstock"><?php esc_html_e( 'Set Status - Out of stock', 'woocommerce' ); ?></option>
</optgroup> </optgroup>
<optgroup label="<?php esc_attr_e( 'Shipping', 'woocommerce' ); ?>"> <optgroup label="<?php esc_attr_e( 'Shipping', 'woocommerce' ); ?>">
<option value="variable_length"><?php _e( 'Length', 'woocommerce' ); ?></option> <option value="variable_length"><?php esc_html_e( 'Length', 'woocommerce' ); ?></option>
<option value="variable_width"><?php _e( 'Width', 'woocommerce' ); ?></option> <option value="variable_width"><?php esc_html_e( 'Width', 'woocommerce' ); ?></option>
<option value="variable_height"><?php _e( 'Height', 'woocommerce' ); ?></option> <option value="variable_height"><?php esc_html_e( 'Height', 'woocommerce' ); ?></option>
<option value="variable_weight"><?php _e( 'Weight', 'woocommerce' ); ?></option> <option value="variable_weight"><?php esc_html_e( 'Weight', 'woocommerce' ); ?></option>
</optgroup> </optgroup>
<optgroup label="<?php esc_attr_e( 'Downloadable products', 'woocommerce' ); ?>"> <optgroup label="<?php esc_attr_e( 'Downloadable products', 'woocommerce' ); ?>">
<option value="variable_download_limit"><?php _e( 'Download limit', 'woocommerce' ); ?></option> <option value="variable_download_limit"><?php esc_html_e( 'Download limit', 'woocommerce' ); ?></option>
<option value="variable_download_expiry"><?php _e( 'Download expiry', 'woocommerce' ); ?></option> <option value="variable_download_expiry"><?php esc_html_e( 'Download expiry', 'woocommerce' ); ?></option>
</optgroup> </optgroup>
<?php do_action( 'woocommerce_variable_product_bulk_edit_actions' ); ?> <?php do_action( 'woocommerce_variable_product_bulk_edit_actions' ); ?>
</select> </select>
<a class="button bulk_edit do_variation_action"><?php _e( 'Go', 'woocommerce' ); ?></a> <a class="button bulk_edit do_variation_action"><?php esc_html_e( 'Go', 'woocommerce' ); ?></a>
<div class="variations-pagenav"> <div class="variations-pagenav">
<span class="displaying-num"><?php printf( _n( '%s item', '%s items', $variations_count, 'woocommerce' ), $variations_count ); ?></span> <?php /* translators: variations count */ ?>
<span class="displaying-num"><?php printf( esc_html( _n( '%s item', '%s items', $variations_count, 'woocommerce' ), $variations_count ) ); ?></span>
<span class="expand-close"> <span class="expand-close">
(<a href="#" class="expand_all"><?php _e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php _e( 'Close', 'woocommerce' ); ?></a>) (<a href="#" class="expand_all"><?php esc_html_e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php esc_html_e( 'Close', 'woocommerce' ); ?></a>)
</span> </span>
<span class="pagination-links"> <span class="pagination-links">
<a class="first-page disabled" title="<?php esc_attr_e( 'Go to the first page', 'woocommerce' ); ?>" href="#">&laquo;</a> <a class="first-page disabled" title="<?php esc_attr_e( 'Go to the first page', 'woocommerce' ); ?>" href="#">&laquo;</a>
<a class="prev-page disabled" title="<?php esc_attr_e( 'Go to the previous page', 'woocommerce' ); ?>" href="#">&lsaquo;</a> <a class="prev-page disabled" title="<?php esc_attr_e( 'Go to the previous page', 'woocommerce' ); ?>" href="#">&lsaquo;</a>
<span class="paging-select"> <span class="paging-select">
<label for="current-page-selector-1" class="screen-reader-text"><?php _e( 'Select Page', 'woocommerce' ); ?></label> <label for="current-page-selector-1" class="screen-reader-text"><?php esc_html_e( 'Select Page', 'woocommerce' ); ?></label>
<select class="page-selector" id="current-page-selector-1" title="<?php esc_attr_e( 'Current page', 'woocommerce' ); ?>"> <select class="page-selector" id="current-page-selector-1" title="<?php esc_attr_e( 'Current page', 'woocommerce' ); ?>">
<?php for ( $i = 1; $i <= $variations_total_pages; $i++ ) : ?> <?php for ( $i = 1; $i <= $variations_total_pages; $i++ ) : ?>
<option value="<?php echo $i; ?>"><?php echo $i; ?></option> <option value="<?php echo $i; ?>"><?php echo $i; ?></option>
<?php endfor; ?> <?php endfor; ?>
</select> </select>
<?php _ex( 'of', 'number of pages', 'woocommerce' ); ?> <span class="total-pages"><?php echo $variations_total_pages; ?></span> <?php _ex( 'of', 'number of pages', 'woocommerce' ); ?> <span class="total-pages"><?php echo esc_html( $variations_total_pages ); ?></span>
</span> </span>
<a class="next-page" title="<?php esc_attr_e( 'Go to the next page', 'woocommerce' ); ?>" href="#">&rsaquo;</a> <a class="next-page" title="<?php esc_attr_e( 'Go to the next page', 'woocommerce' ); ?>" href="#">&rsaquo;</a>
<a class="last-page" title="<?php esc_attr_e( 'Go to the last page', 'woocommerce' ); ?>" href="#">&raquo;</a> <a class="last-page" title="<?php esc_attr_e( 'Go to the last page', 'woocommerce' ); ?>" href="#">&raquo;</a>
@ -106,24 +108,25 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="woocommerce_variations wc-metaboxes" data-attributes="<?php <div class="woocommerce_variations wc-metaboxes" data-attributes="<?php
// esc_attr does not double encode - htmlspecialchars does // esc_attr does not double encode - htmlspecialchars does
echo htmlspecialchars( json_encode( wc_list_pluck( $variation_attributes, 'get_data' ) ) ); echo htmlspecialchars( wp_json_encode( wc_list_pluck( $variation_attributes, 'get_data' ) ) );
?>" data-total="<?php echo $variations_count; ?>" data-total_pages="<?php echo $variations_total_pages; ?>" data-page="1" data-edited="false"> ?>" data-total="<?php echo esc_attr( $variations_count ); ?>" data-total_pages="<?php echo esc_attr( $variations_total_pages ); ?>" data-page="1" data-edited="false">
</div> </div>
<div class="toolbar"> <div class="toolbar">
<button type="button" class="button-primary save-variation-changes" disabled="disabled"><?php _e( 'Save changes', 'woocommerce' ); ?></button> <button type="button" class="button-primary save-variation-changes" disabled="disabled"><?php esc_html_e( 'Save changes', 'woocommerce' ); ?></button>
<button type="button" class="button cancel-variation-changes" disabled="disabled"><?php _e( 'Cancel', 'woocommerce' ); ?></button> <button type="button" class="button cancel-variation-changes" disabled="disabled"><?php esc_html_e( 'Cancel', 'woocommerce' ); ?></button>
<div class="variations-pagenav"> <div class="variations-pagenav">
<?php /* translators: variations count*/ ?>
<span class="displaying-num"><?php printf( _n( '%s item', '%s items', $variations_count, 'woocommerce' ), $variations_count ); ?></span> <span class="displaying-num"><?php printf( _n( '%s item', '%s items', $variations_count, 'woocommerce' ), $variations_count ); ?></span>
<span class="expand-close"> <span class="expand-close">
(<a href="#" class="expand_all"><?php _e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php _e( 'Close', 'woocommerce' ); ?></a>) (<a href="#" class="expand_all"><?php esc_html_e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php esc_html_e( 'Close', 'woocommerce' ); ?></a>)
</span> </span>
<span class="pagination-links"> <span class="pagination-links">
<a class="first-page disabled" title="<?php esc_attr_e( 'Go to the first page', 'woocommerce' ); ?>" href="#">&laquo;</a> <a class="first-page disabled" title="<?php esc_attr_e( 'Go to the first page', 'woocommerce' ); ?>" href="#">&laquo;</a>
<a class="prev-page disabled" title="<?php esc_attr_e( 'Go to the previous page', 'woocommerce' ); ?>" href="#">&lsaquo;</a> <a class="prev-page disabled" title="<?php esc_attr_e( 'Go to the previous page', 'woocommerce' ); ?>" href="#">&lsaquo;</a>
<span class="paging-select"> <span class="paging-select">
<label for="current-page-selector-1" class="screen-reader-text"><?php _e( 'Select Page', 'woocommerce' ); ?></label> <label for="current-page-selector-1" class="screen-reader-text"><?php esc_html_e( 'Select Page', 'woocommerce' ); ?></label>
<select class="page-selector" id="current-page-selector-1" title="<?php esc_attr_e( 'Current page', 'woocommerce' ); ?>"> <select class="page-selector" id="current-page-selector-1" title="<?php esc_attr_e( 'Current page', 'woocommerce' ); ?>">
<?php for ( $i = 1; $i <= $variations_total_pages; $i++ ) : ?> <?php for ( $i = 1; $i <= $variations_total_pages; $i++ ) : ?>
<option value="<?php echo $i; ?>"><?php echo $i; ?></option> <option value="<?php echo $i; ?>"><?php echo $i; ?></option>

View File

@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<input type="text" class="input_text" placeholder="<?php esc_attr_e( 'File name', 'woocommerce' ); ?>" name="_wc_file_names[]" value="<?php echo esc_attr( $file['name'] ); ?>" /> <input type="text" class="input_text" placeholder="<?php esc_attr_e( 'File name', 'woocommerce' ); ?>" name="_wc_file_names[]" value="<?php echo esc_attr( $file['name'] ); ?>" />
<input type="hidden" name="_wc_file_hashes[]" value="<?php echo esc_attr( $key ); ?>" /> <input type="hidden" name="_wc_file_hashes[]" value="<?php echo esc_attr( $key ); ?>" />
</td> </td>
<td class="file_url"><input type="text" class="input_text" placeholder="<?php esc_attr_e( "http://", 'woocommerce' ); ?>" name="_wc_file_urls[]" value="<?php echo esc_attr( $file['file'] ); ?>" /></td> <td class="file_url"><input type="text" class="input_text" placeholder="<?php esc_attr_e( 'http://', 'woocommerce' ); ?>" name="_wc_file_urls[]" value="<?php echo esc_attr( $file['file'] ); ?>" /></td>
<td class="file_url_choose" width="1%"><a href="#" class="button upload_file_button" data-choose="<?php esc_attr_e( 'Choose file', 'woocommerce' ); ?>" data-update="<?php esc_attr_e( 'Insert file URL', 'woocommerce' ); ?>"><?php echo str_replace( ' ', '&nbsp;', __( 'Choose file', 'woocommerce' ) ); ?></a></td> <td class="file_url_choose" width="1%"><a href="#" class="button upload_file_button" data-choose="<?php esc_attr_e( 'Choose file', 'woocommerce' ); ?>" data-update="<?php esc_attr_e( 'Insert file URL', 'woocommerce' ); ?>"><?php echo esc_html__( 'Choose file', 'woocommerce' ); ?></a></td>
<td width="1%"><a href="#" class="delete"><?php _e( 'Delete', 'woocommerce' ); ?></a></td> <td width="1%"><a href="#" class="delete"><?php esc_html_e( 'Delete', 'woocommerce' ); ?></a></td>
</tr> </tr>

View File

@ -5,10 +5,10 @@ if ( ! defined( 'ABSPATH' ) ) {
?> ?>
<tr> <tr>
<td class="file_name"> <td class="file_name">
<input type="text" class="input_text" placeholder="<?php esc_attr_e( 'File name', 'woocommerce' ); ?>" name="_wc_variation_file_names[<?php echo $variation_id; ?>][]" value="<?php echo esc_attr( $file['name'] ); ?>" /> <input type="text" class="input_text" placeholder="<?php esc_attr_e( 'File name', 'woocommerce' ); ?>" name="_wc_variation_file_names[<?php echo esc_attr( $variation_id ); ?>][]" value="<?php echo esc_attr( $file['name'] ); ?>" />
<input type="hidden" name="_wc_variation_file_hashes[<?php echo $variation_id; ?>][]" value="<?php echo esc_attr( $key ); ?>" /> <input type="hidden" name="_wc_variation_file_hashes[<?php echo esc_attr( $variation_id ); ?>][]" value="<?php echo esc_attr( $key ); ?>" />
</td> </td>
<td class="file_url"><input type="text" class="input_text" placeholder="<?php esc_attr_e( "http://", 'woocommerce' ); ?>" name="_wc_variation_file_urls[<?php echo $variation_id; ?>][]" value="<?php echo esc_attr( $file['file'] ); ?>" /></td> <td class="file_url"><input type="text" class="input_text" placeholder="<?php esc_attr_e( 'http://', 'woocommerce' ); ?>" name="_wc_variation_file_urls[<?php echo esc_attr( $variation_id ); ?>][]" value="<?php echo esc_attr( $file['file'] ); ?>" /></td>
<td class="file_url_choose" width="1%"><a href="#" class="button upload_file_button" data-choose="<?php esc_attr_e( 'Choose file', 'woocommerce' ); ?>" data-update="<?php esc_attr_e( 'Insert file URL', 'woocommerce' ); ?>"><?php echo str_replace( ' ', '&nbsp;', __( 'Choose file', 'woocommerce' ) ); ?></a></td> <td class="file_url_choose" width="1%"><a href="#" class="button upload_file_button" data-choose="<?php esc_attr_e( 'Choose file', 'woocommerce' ); ?>" data-update="<?php esc_attr_e( 'Insert file URL', 'woocommerce' ); ?>"><?php esc_html_e( 'Choose file', 'woocommerce' ); ?></a></td>
<td width="1%"><a href="#" class="delete"><?php _e( 'Delete', 'woocommerce' ); ?></a></td> <td width="1%"><a href="#" class="delete"><?php esc_html_e( 'Delete', 'woocommerce' ); ?></a></td>
</tr> </tr>

View File

@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) {
?> ?>
<div class="woocommerce_variation wc-metabox closed"> <div class="woocommerce_variation wc-metabox closed">
<h3> <h3>
<a href="#" class="remove_variation delete" rel="<?php echo esc_attr( $variation_id ); ?>"><?php _e( 'Remove', 'woocommerce' ); ?></a> <a href="#" class="remove_variation delete" rel="<?php echo esc_attr( $variation_id ); ?>"><?php esc_html_e( 'Remove', 'woocommerce' ); ?></a>
<div class="handlediv" aria-label="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div> <div class="handlediv" aria-label="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div>
<div class="tips sort" data-tip="<?php esc_attr_e( 'Drag and drop, or click to set admin variation order', 'woocommerce' ); ?>"></div> <div class="tips sort" data-tip="<?php esc_attr_e( 'Drag and drop, or click to set admin variation order', 'woocommerce' ); ?>"></div>
<strong>#<?php echo esc_html( $variation_id ); ?> </strong> <strong>#<?php echo esc_html( $variation_id ); ?> </strong>
@ -44,14 +44,14 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php <?php
} }
?> ?>
<input type="hidden" name="variable_post_id[<?php echo $loop; ?>]" value="<?php echo esc_attr( $variation_id ); ?>" /> <input type="hidden" name="variable_post_id[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( $variation_id ); ?>" />
<input type="hidden" class="variation_menu_order" name="variation_menu_order[<?php echo $loop; ?>]" value="<?php echo esc_attr( $variation_object->get_menu_order( 'edit' ) ); ?>" /> <input type="hidden" class="variation_menu_order" name="variation_menu_order[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( $variation_object->get_menu_order( 'edit' ) ); ?>" />
</h3> </h3>
<div class="woocommerce_variable_attributes wc-metabox-content" style="display: none;"> <div class="woocommerce_variable_attributes wc-metabox-content" style="display: none;">
<div class="data"> <div class="data">
<p class="form-row form-row-first upload_image"> <p class="form-row form-row-first upload_image">
<a href="#" class="upload_image_button tips <?php echo $variation_object->get_image_id( 'edit' ) ? 'remove' : ''; ?>" data-tip="<?php echo $variation_object->get_image_id( 'edit' ) ? esc_attr__( 'Remove this image', 'woocommerce' ) : esc_attr__( 'Upload an image', 'woocommerce' ); ?>" rel="<?php echo esc_attr( $variation_id ); ?>"> <a href="#" class="upload_image_button tips <?php echo $variation_object->get_image_id( 'edit' ) ? 'remove' : ''; ?>" data-tip="<?php echo $variation_object->get_image_id( 'edit' ) ? esc_attr__( 'Remove this image', 'woocommerce' ) : esc_attr__( 'Upload an image', 'woocommerce' ); ?>" rel="<?php echo esc_attr( $variation_id ); ?>">
<img src="<?php echo $variation_object->get_image_id( 'edit' ) ? esc_url( wp_get_attachment_thumb_url( $variation_object->get_image_id( 'edit' ) ) ) : esc_url( wc_placeholder_img_src() ); ?>" /><input type="hidden" name="upload_image_id[<?php echo $loop; ?>]" class="upload_image_id" value="<?php echo esc_attr( $variation_object->get_image_id( 'edit' ) ); ?>" /> <img src="<?php echo $variation_object->get_image_id( 'edit' ) ? esc_url( wp_get_attachment_thumb_url( $variation_object->get_image_id( 'edit' ) ) ) : esc_url( wc_placeholder_img_src() ); ?>" /><input type="hidden" name="upload_image_id[<?php echo esc_attr( $loop ); ?>]" class="upload_image_id" value="<?php echo esc_attr( $variation_object->get_image_id( 'edit' ) ); ?>" />
</a> </a>
</p> </p>
<?php <?php
@ -70,22 +70,22 @@ if ( ! defined( 'ABSPATH' ) ) {
?> ?>
<p class="form-row form-row-full options"> <p class="form-row form-row-full options">
<label> <label>
<?php _e( 'Enabled', 'woocommerce' ); ?>: <?php esc_html_e( 'Enabled', 'woocommerce' ); ?>:
<input type="checkbox" class="checkbox" name="variable_enabled[<?php echo $loop; ?>]" <?php checked( in_array( $variation_object->get_status( 'edit' ), array( 'publish', false ) ), true ); ?> /> <input type="checkbox" class="checkbox" name="variable_enabled[<?php echo $loop; ?>]" <?php checked( in_array( $variation_object->get_status( 'edit' ), array( 'publish', false ), true ), true ); ?> />
</label> </label>
<label class="tips" data-tip="<?php _e( 'Enable this option if access is given to a downloadable file upon purchase of a product', 'woocommerce' ); ?>"> <label class="tips" data-tip="<?php esc_html_e( 'Enable this option if access is given to a downloadable file upon purchase of a product', 'woocommerce' ); ?>">
<?php _e( 'Downloadable', 'woocommerce' ); ?>: <?php esc_html_e( 'Downloadable', 'woocommerce' ); ?>:
<input type="checkbox" class="checkbox variable_is_downloadable" name="variable_is_downloadable[<?php echo $loop; ?>]" <?php checked( $variation_object->get_downloadable( 'edit' ), true ); ?> /> <input type="checkbox" class="checkbox variable_is_downloadable" name="variable_is_downloadable[<?php echo esc_attr( $loop ); ?>]" <?php checked( $variation_object->get_downloadable( 'edit' ), true ); ?> />
</label> </label>
<label class="tips" data-tip="<?php _e( 'Enable this option if a product is not shipped or there is no shipping cost', 'woocommerce' ); ?>"> <label class="tips" data-tip="<?php esc_html_e( 'Enable this option if a product is not shipped or there is no shipping cost', 'woocommerce' ); ?>">
<?php _e( 'Virtual', 'woocommerce' ); ?>: <?php esc_html_e( 'Virtual', 'woocommerce' ); ?>:
<input type="checkbox" class="checkbox variable_is_virtual" name="variable_is_virtual[<?php echo $loop; ?>]" <?php checked( $variation_object->get_virtual( 'edit' ), true ); ?> /> <input type="checkbox" class="checkbox variable_is_virtual" name="variable_is_virtual[<?php echo esc_attr( $loop ); ?>]" <?php checked( $variation_object->get_virtual( 'edit' ), true ); ?> />
</label> </label>
<?php if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) : ?> <?php if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) : ?>
<label class="tips" data-tip="<?php _e( 'Enable this option to enable stock management at variation level', 'woocommerce' ); ?>"> <label class="tips" data-tip="<?php esc_html_e( 'Enable this option to enable stock management at variation level', 'woocommerce' ); ?>">
<?php _e( 'Manage stock?', 'woocommerce' ); ?> <?php esc_html_e( 'Manage stock?', 'woocommerce' ); ?>
<input type="checkbox" class="checkbox variable_manage_stock" name="variable_manage_stock[<?php echo $loop; ?>]" <?php checked( $variation_object->get_manage_stock( 'edit' ), true ); ?> /> <input type="checkbox" class="checkbox variable_manage_stock" name="variable_manage_stock[<?php echo esc_attr( $loop ); ?>]" <?php checked( $variation_object->get_manage_stock( 'edit' ), true ); ?> />
</label> </label>
<?php endif; ?> <?php endif; ?>
@ -94,8 +94,8 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="variable_pricing"> <div class="variable_pricing">
<?php <?php
/* translators: %s: currency symbol */
$label = sprintf( $label = sprintf(
/* translators: %s: currency symbol */
__( 'Regular price (%s)', 'woocommerce' ), __( 'Regular price (%s)', 'woocommerce' ),
get_woocommerce_currency_symbol() get_woocommerce_currency_symbol()
); );
@ -109,9 +109,9 @@ if ( ! defined( 'ABSPATH' ) ) {
'wrapper_class' => 'form-row form-row-first', 'wrapper_class' => 'form-row form-row-first',
'placeholder' => __( 'Variation price (required)', 'woocommerce' ), 'placeholder' => __( 'Variation price (required)', 'woocommerce' ),
) ); ) );
/* translators: %s: currency symbol */
$label = sprintf( $label = sprintf(
/* translators: %s: currency symbol */
__( 'Sale price (%s)', 'woocommerce' ), __( 'Sale price (%s)', 'woocommerce' ),
get_woocommerce_currency_symbol() get_woocommerce_currency_symbol()
); );
@ -121,7 +121,7 @@ if ( ! defined( 'ABSPATH' ) ) {
'name' => "variable_sale_price[{$loop}]", 'name' => "variable_sale_price[{$loop}]",
'value' => wc_format_localized_price( $variation_object->get_sale_price( 'edit' ) ), 'value' => wc_format_localized_price( $variation_object->get_sale_price( 'edit' ) ),
'data_type' => 'price', 'data_type' => 'price',
'label' => $label . ' <a href="#" class="sale_schedule">' . __( 'Schedule', 'woocommerce' ) . '</a><a href="#" class="cancel_sale_schedule hidden">' . __( 'Cancel schedule', 'woocommerce' ) . '</a>', 'label' => $label . ' <a href="#" class="sale_schedule">' . esc_html__( 'Schedule', 'woocommerce' ) . '</a><a href="#" class="cancel_sale_schedule hidden">' . esc_html__( 'Cancel schedule', 'woocommerce' ) . '</a>',
'wrapper_class' => 'form-row form-row-last', 'wrapper_class' => 'form-row form-row-last',
) ); ) );
@ -135,7 +135,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</p> </p>
<p class="form-row form-row-last"> <p class="form-row form-row-last">
<label>' . __( 'Sale end date', 'woocommerce' ) . '</label> <label>' . __( 'Sale end date', 'woocommerce' ) . '</label>
<input type="text" class="sale_price_dates_to" name="variable_sale_price_dates_to[' . $loop . ']" value="' . esc_attr( $sale_price_dates_to ) . '" placeholder="' . _x( 'To&hellip;', 'placeholder', 'woocommerce' ) . ' YYYY-MM-DD" maxlength="10" pattern="' . esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ) . '" /> <input type="text" class="sale_price_dates_to" name="variable_sale_price_dates_to[' . esc_attr( $loop ) . ']" value="' . esc_attr( $sale_price_dates_to ) . '" placeholder="' . esc_html_x( 'To&hellip;', 'placeholder', 'woocommerce' ) . ' YYYY-MM-DD" maxlength="10" pattern="' . esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ) . '" />
</p> </p>
</div>'; </div>';
@ -170,7 +170,7 @@ if ( ! defined( 'ABSPATH' ) ) {
'wrapper_class' => 'form-row form-row-first', 'wrapper_class' => 'form-row form-row-first',
) ); ) );
echo '<input type="hidden" name="variable_original_stock[' . $loop . ']" value="' . esc_attr( wc_stock_amount( $variation_object->get_stock_quantity( 'edit' ) ) ) . '" />'; echo '<input type="hidden" name="variable_original_stock[' . esc_attr( $loop ) . ']" value="' . esc_attr( wc_stock_amount( $variation_object->get_stock_quantity( 'edit' ) ) ) . '" />';
woocommerce_wp_select( array( woocommerce_wp_select( array(
'id' => "variable_backorders{$loop}", 'id' => "variable_backorders{$loop}",
@ -211,8 +211,8 @@ if ( ! defined( 'ABSPATH' ) ) {
) ); ) );
if ( wc_product_weight_enabled() ) { if ( wc_product_weight_enabled() ) {
/* translators: %s: weight unit */
$label = sprintf( $label = sprintf(
/* translators: %s: weight unit */
__( 'Weight (%s)', 'woocommerce' ), __( 'Weight (%s)', 'woocommerce' ),
esc_html( get_option( 'woocommerce_weight_unit' ) ) esc_html( get_option( 'woocommerce_weight_unit' ) )
); );
@ -238,17 +238,17 @@ if ( ! defined( 'ABSPATH' ) ) {
?><p class="form-field form-row dimensions_field hide_if_variation_virtual form-row-last"> ?><p class="form-field form-row dimensions_field hide_if_variation_virtual form-row-last">
<label for="product_length"><?php <label for="product_length"><?php
/* translators: %s: dimension unit */
printf( printf(
__( 'Dimensions (L&times;W&times;H) (%s)', 'woocommerce' ), /* translators: %s: dimension unit */
esc_html__( 'Dimensions (L&times;W&times;H) (%s)', 'woocommerce' ),
get_option( 'woocommerce_dimension_unit' ) get_option( 'woocommerce_dimension_unit' )
); );
?></label> ?></label>
<?php echo wc_help_tip( __( 'Length x width x height in decimal form', 'woocommerce' ) ); ?> <?php echo wc_help_tip( __( 'Length x width x height in decimal form', 'woocommerce' ) ); ?>
<span class="wrap"> <span class="wrap">
<input id="product_length" placeholder="<?php echo $parent_length ? esc_attr( $parent_length ) : esc_attr__( 'Length', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="variable_length[<?php echo $loop; ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_length( 'edit' ) ) ); ?>" /> <input id="product_length" placeholder="<?php echo $parent_length ? esc_attr( $parent_length ) : esc_attr__( 'Length', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="variable_length[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_length( 'edit' ) ) ); ?>" />
<input placeholder="<?php echo $parent_width ? esc_attr( $parent_width ) : esc_attr__( 'Width', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="variable_width[<?php echo $loop; ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_width( 'edit' ) ) ); ?>" /> <input placeholder="<?php echo $parent_width ? esc_attr( $parent_width ) : esc_attr__( 'Width', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="variable_width[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_width( 'edit' ) ) ); ?>" />
<input placeholder="<?php echo $parent_height ? esc_attr( $parent_height ) : esc_attr__( 'Height', 'woocommerce' ); ?>" class="input-text wc_input_decimal last" size="6" type="text" name="variable_height[<?php echo $loop; ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_height( 'edit' ) ) ); ?>" /> <input placeholder="<?php echo $parent_height ? esc_attr( $parent_height ) : esc_attr__( 'Height', 'woocommerce' ); ?>" class="input-text wc_input_decimal last" size="6" type="text" name="variable_height[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_height( 'edit' ) ) ); ?>" />
</span> </span>
</p><?php </p><?php
} }
@ -267,7 +267,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</div> </div>
<div> <div>
<p class="form-row hide_if_variation_virtual form-row-full"><label><?php _e( 'Shipping class', 'woocommerce' ); ?></label> <?php <p class="form-row hide_if_variation_virtual form-row-full"><label><?php esc_html_e( 'Shipping class', 'woocommerce' ); ?></label> <?php
wp_dropdown_categories( array( wp_dropdown_categories( array(
'taxonomy' => 'product_shipping_class', 'taxonomy' => 'product_shipping_class',
'hide_empty' => 0, 'hide_empty' => 0,
@ -319,12 +319,12 @@ if ( ! defined( 'ABSPATH' ) ) {
</div> </div>
<div class="show_if_variation_downloadable" style="display: none;"> <div class="show_if_variation_downloadable" style="display: none;">
<div class="form-row form-row-full downloadable_files"> <div class="form-row form-row-full downloadable_files">
<label><?php _e( 'Downloadable files', 'woocommerce' ); ?></label> <label><?php esc_html_e( 'Downloadable files', 'woocommerce' ); ?></label>
<table class="widefat"> <table class="widefat">
<thead> <thead>
<div> <div>
<th><?php _e( 'Name', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the name of the download shown to the customer.', 'woocommerce' ) ); ?></th> <th><?php esc_html_e( 'Name', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the name of the download shown to the customer.', 'woocommerce' ) ); ?></th>
<th colspan="2"><?php _e( 'File URL', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the URL or absolute path to the file which customers will get access to. URLs entered here should already be encoded.', 'woocommerce' ) ); ?></th> <th colspan="2"><?php esc_html_e( 'File URL', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the URL or absolute path to the file which customers will get access to. URLs entered here should already be encoded.', 'woocommerce' ) ); ?></th>
<th>&nbsp;</th> <th>&nbsp;</th>
</div> </div>
</thead> </thead>
@ -349,7 +349,7 @@ if ( ! defined( 'ABSPATH' ) ) {
ob_start(); ob_start();
include( 'html-product-variation-download.php' ); include( 'html-product-variation-download.php' );
echo esc_attr( ob_get_clean() ); echo esc_attr( ob_get_clean() );
?>"><?php _e( 'Add file', 'woocommerce' ); ?></a> ?>"><?php esc_html_e( 'Add file', 'woocommerce' ); ?></a>
</th> </th>
</div> </div>
</tfoot> </tfoot>

View File

@ -658,8 +658,12 @@ class WC_Admin_Report {
return; return;
} }
if ( ! isset( $_GET['wc_reports_nonce'] ) || ! wp_verify_nonce( $_GET['wc_reports_nonce'], 'custom_range' ) ) { if ( ! isset( $_GET['wc_reports_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_GET['wc_reports_nonce'] ), 'custom_range' ) ) { // WPCS: input var ok, CSRF ok.
wp_safe_redirect( remove_query_arg( array( 'start_date', 'end_date', 'range', 'wc_reports_nonce' ) ) ); 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; exit;
} }
} }

View File

@ -507,7 +507,7 @@ class WC_REST_Coupons_Controller extends WC_REST_Legacy_Coupons_Controller {
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
), ),

View File

@ -354,7 +354,7 @@ class WC_REST_Customers_Controller extends WC_REST_Customers_V1_Controller {
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
), ),

View File

@ -401,7 +401,7 @@ class WC_REST_Order_Refunds_Controller extends WC_REST_Orders_Controller {
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
), ),
@ -422,12 +422,12 @@ class WC_REST_Order_Refunds_Controller extends WC_REST_Orders_Controller {
), ),
'name' => array( 'name' => array(
'description' => __( 'Product name.', 'woocommerce' ), 'description' => __( 'Product name.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'product_id' => array( 'product_id' => array(
'description' => __( 'Product ID.', 'woocommerce' ), 'description' => __( 'Product ID.', 'woocommerce' ),
'type' => 'integer', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'variation_id' => array( 'variation_id' => array(
@ -513,7 +513,7 @@ class WC_REST_Order_Refunds_Controller extends WC_REST_Orders_Controller {
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
), ),

View File

@ -597,8 +597,9 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
protected function maybe_set_item_meta_data( $item, $posted ) { protected function maybe_set_item_meta_data( $item, $posted ) {
if ( ! empty( $posted['meta_data'] ) && is_array( $posted['meta_data'] ) ) { if ( ! empty( $posted['meta_data'] ) && is_array( $posted['meta_data'] ) ) {
foreach ( $posted['meta_data'] as $meta ) { foreach ( $posted['meta_data'] as $meta ) {
if ( isset( $meta['key'], $meta['value'] ) ) { if ( isset( $meta['key'] ) ) {
$item->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' ); $value = isset( $meta['value'] ) ? $meta['value'] : null;
$item->update_meta_data( $meta['key'], $value, isset( $meta['id'] ) ? $meta['id'] : '' );
} }
} }
} }
@ -1118,7 +1119,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
), ),
@ -1139,12 +1140,12 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
), ),
'name' => array( 'name' => array(
'description' => __( 'Product name.', 'woocommerce' ), 'description' => __( 'Product name.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'product_id' => array( 'product_id' => array(
'description' => __( 'Product ID.', 'woocommerce' ), 'description' => __( 'Product ID.', 'woocommerce' ),
'type' => 'integer', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'variation_id' => array( 'variation_id' => array(
@ -1230,7 +1231,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
), ),
@ -1321,7 +1322,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
), ),
@ -1345,12 +1346,12 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
), ),
'method_title' => array( 'method_title' => array(
'description' => __( 'Shipping method name.', 'woocommerce' ), 'description' => __( 'Shipping method name.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'method_id' => array( 'method_id' => array(
'description' => __( 'Shipping method ID.', 'woocommerce' ), 'description' => __( 'Shipping method ID.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'total' => array( 'total' => array(
@ -1407,7 +1408,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
), ),
@ -1431,7 +1432,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
), ),
'name' => array( 'name' => array(
'description' => __( 'Fee name.', 'woocommerce' ), 'description' => __( 'Fee name.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'tax_class' => array( 'tax_class' => array(
@ -1505,7 +1506,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
), ),
@ -1529,7 +1530,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
), ),
'code' => array( 'code' => array(
'description' => __( 'Coupon code.', 'woocommerce' ), 'description' => __( 'Coupon code.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'discount' => array( 'discount' => array(
@ -1563,7 +1564,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
), ),

View File

@ -945,7 +945,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Products_Controller
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
), ),

View File

@ -1991,7 +1991,7 @@ class WC_REST_Products_Controller extends WC_REST_Legacy_Products_Controller {
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
), ),

View File

@ -378,7 +378,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller {
), ),
'name' => array( 'name' => array(
'description' => __( 'Product name.', 'woocommerce' ), 'description' => __( 'Product name.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
'readonly' => true, 'readonly' => true,
), ),
@ -390,7 +390,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller {
), ),
'product_id' => array( 'product_id' => array(
'description' => __( 'Product ID.', 'woocommerce' ), 'description' => __( 'Product ID.', 'woocommerce' ),
'type' => 'integer', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'variation_id' => array( 'variation_id' => array(
@ -486,7 +486,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller {
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
'readonly' => true, 'readonly' => true,
), ),

View File

@ -1211,7 +1211,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
), ),
'name' => array( 'name' => array(
'description' => __( 'Product name.', 'woocommerce' ), 'description' => __( 'Product name.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
'readonly' => true, 'readonly' => true,
), ),
@ -1223,7 +1223,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
), ),
'product_id' => array( 'product_id' => array(
'description' => __( 'Product ID.', 'woocommerce' ), 'description' => __( 'Product ID.', 'woocommerce' ),
'type' => 'integer', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'variation_id' => array( 'variation_id' => array(
@ -1319,7 +1319,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
), ),
'value' => array( 'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ), 'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
'readonly' => true, 'readonly' => true,
), ),
@ -1397,12 +1397,12 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
), ),
'method_title' => array( 'method_title' => array(
'description' => __( 'Shipping method name.', 'woocommerce' ), 'description' => __( 'Shipping method name.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'method_id' => array( 'method_id' => array(
'description' => __( 'Shipping method ID.', 'woocommerce' ), 'description' => __( 'Shipping method ID.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'total' => array( 'total' => array(
@ -1457,7 +1457,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
), ),
'name' => array( 'name' => array(
'description' => __( 'Fee name.', 'woocommerce' ), 'description' => __( 'Fee name.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'tax_class' => array( 'tax_class' => array(
@ -1528,7 +1528,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
), ),
'code' => array( 'code' => array(
'description' => __( 'Coupon code.', 'woocommerce' ), 'description' => __( 'Coupon code.', 'woocommerce' ),
'type' => 'string', 'type' => 'mixed',
'context' => array( 'view', 'edit' ), 'context' => array( 'view', 'edit' ),
), ),
'discount' => array( 'discount' => array(

View File

@ -388,7 +388,7 @@ class WC_AJAX {
} }
/** /**
* AJAX add to cart. * AJAX remove from cart.
*/ */
public static function remove_from_cart() { public static function remove_from_cart() {
ob_start(); ob_start();
@ -1735,9 +1735,6 @@ class WC_AJAX {
wp_send_json_success( $response_data ); wp_send_json_success( $response_data );
} catch ( Exception $e ) { } 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() ) ); wp_send_json_error( array( 'error' => $e->getMessage() ) );
} }
} }

View File

@ -227,7 +227,7 @@ final class WC_Cart_Totals {
$item->taxable = 'taxable' === $cart_item['data']->get_tax_status(); $item->taxable = 'taxable' === $cart_item['data']->get_tax_status();
$item->price_includes_tax = wc_prices_include_tax(); $item->price_includes_tax = wc_prices_include_tax();
$item->quantity = $cart_item['quantity']; $item->quantity = $cart_item['quantity'];
$item->price = wc_add_number_precision_deep( $cart_item['data']->get_price() ) * $cart_item['quantity']; $item->price = wc_add_number_precision_deep( $cart_item['data']->get_price() * $cart_item['quantity'] );
$item->product = $cart_item['data']; $item->product = $cart_item['data'];
$item->tax_rates = $this->get_item_tax_rates( $item ); $item->tax_rates = $this->get_item_tax_rates( $item );
$this->items[ $cart_item_key ] = $item; $this->items[ $cart_item_key ] = $item;
@ -349,8 +349,8 @@ final class WC_Cart_Totals {
$shipping_line->tax_class = get_option( 'woocommerce_shipping_tax_class' ); $shipping_line->tax_class = get_option( 'woocommerce_shipping_tax_class' );
$shipping_line->taxable = true; $shipping_line->taxable = true;
$shipping_line->total = wc_add_number_precision_deep( $shipping_object->cost ); $shipping_line->total = wc_add_number_precision_deep( $shipping_object->cost );
$shipping_line->taxes = wc_add_number_precision_deep( $shipping_object->taxes ); $shipping_line->taxes = wc_add_number_precision_deep( $shipping_object->taxes, false );
$shipping_line->total_tax = wc_add_number_precision_deep( array_sum( $shipping_object->taxes ) ); $shipping_line->total_tax = wc_add_number_precision_deep( array_sum( $shipping_object->taxes ), false );
if ( ! $this->round_at_subtotal() ) { if ( ! $this->round_at_subtotal() ) {
$shipping_line->total_tax = wc_round_tax_total( $shipping_line->total_tax, wc_get_rounding_precision() ); $shipping_line->total_tax = wc_round_tax_total( $shipping_line->total_tax, wc_get_rounding_precision() );
@ -423,7 +423,7 @@ final class WC_Cart_Totals {
* @return object * @return object
*/ */
protected function remove_item_base_taxes( $item ) { 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' ) ); $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. // Work out a new base price without the shop's base tax.
@ -449,7 +449,7 @@ final class WC_Cart_Totals {
* @return object * @return object
*/ */
protected function adjust_non_base_location_price( $item ) { 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' ) ); $base_tax_rates = WC_Tax::get_base_tax_rates( $item->product->get_tax_class( 'unfiltered' ) );
if ( $item->tax_rates !== $base_tax_rates ) { if ( $item->tax_rates !== $base_tax_rates ) {

View File

@ -981,6 +981,23 @@ class WC_Cart extends WC_Legacy_Cart {
return array_unique( $found_tax_classes ); return array_unique( $found_tax_classes );
} }
/**
* Get all tax classes for shipping based on the items in the cart.
*
* @return array
*/
public function get_cart_item_tax_classes_for_shipping() {
$found_tax_classes = array();
foreach ( WC()->cart->get_cart() as $item ) {
if ( $item['data'] && ( $item['data']->is_shipping_taxable() ) ) {
$found_tax_classes[] = $item['data']->get_tax_class();
}
}
return array_unique( $found_tax_classes );
}
/** /**
* Determines the value that the customer spent and the subtotal * Determines the value that the customer spent and the subtotal
* displayed, used for things like coupon validation. * displayed, used for things like coupon validation.
@ -1085,7 +1102,7 @@ class WC_Cart extends WC_Legacy_Cart {
} }
// Load cart item data - may be added by other plugins. // Load cart item data - may be added by other plugins.
$cart_item_data = (array) apply_filters( 'woocommerce_add_cart_item_data', $cart_item_data, $product_id, $variation_id ); $cart_item_data = (array) apply_filters( 'woocommerce_add_cart_item_data', $cart_item_data, $product_id, $variation_id, $quantity );
// Generate a ID based on product ID, variation ID, variation data, and other cart item data. // Generate a ID based on product ID, variation ID, variation data, and other cart item data.
$cart_id = $this->generate_cart_id( $product_id, $variation_id, $variation, $cart_item_data ); $cart_id = $this->generate_cart_id( $product_id, $variation_id, $variation, $cart_item_data );

View File

@ -469,7 +469,7 @@ class WC_Checkout {
* @param WC_Cart $cart * @param WC_Cart $cart
*/ */
public function create_order_tax_lines( &$order, $cart ) { public function create_order_tax_lines( &$order, $cart ) {
foreach ( array_keys( $cart->get_cart_contents_taxes() + $cart->get_shipping_taxes() ) as $tax_rate_id ) { foreach ( array_keys( $cart->get_cart_contents_taxes() + $cart->get_shipping_taxes() + $cart->get_fee_taxes() ) as $tax_rate_id ) {
if ( $tax_rate_id && apply_filters( 'woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated' ) !== $tax_rate_id ) { if ( $tax_rate_id && apply_filters( 'woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated' ) !== $tax_rate_id ) {
$item = new WC_Order_Item_Tax(); $item = new WC_Order_Item_Tax();
$item->set_props( array( $item->set_props( array(

View File

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

View File

@ -1,12 +1,18 @@
<?php <?php
/**
* Deprecated action hooks
*
* @package WooCommerce\Abstracts
* @since 3.0.0
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
/** /**
* Handles deprecation notices and triggering of legacy action hooks. * Handles deprecation notices and triggering of legacy action hooks.
*
* @since 3.0.0
*/ */
class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks { class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
@ -16,7 +22,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
* @var array * @var array
*/ */
protected $deprecated_hooks = array( protected $deprecated_hooks = array(
'woocommerce_new_order_item' => array( 'woocommerce_new_order_item' => array(
'woocommerce_order_add_shipping', 'woocommerce_order_add_shipping',
'woocommerce_order_add_coupon', 'woocommerce_order_add_coupon',
'woocommerce_order_add_tax', 'woocommerce_order_add_tax',
@ -25,21 +31,45 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
'woocommerce_add_order_item_meta', 'woocommerce_add_order_item_meta',
'woocommerce_add_order_fee_meta', 'woocommerce_add_order_fee_meta',
), ),
'woocommerce_update_order_item' => array( 'woocommerce_update_order_item' => array(
'woocommerce_order_edit_product', 'woocommerce_order_edit_product',
'woocommerce_order_update_coupon', 'woocommerce_order_update_coupon',
'woocommerce_order_update_shipping', 'woocommerce_order_update_shipping',
'woocommerce_order_update_fee', 'woocommerce_order_update_fee',
'woocommerce_order_update_tax', 'woocommerce_order_update_tax',
), ),
'woocommerce_new_payment_token' => 'woocommerce_payment_token_created', 'woocommerce_new_payment_token' => 'woocommerce_payment_token_created',
'woocommerce_new_product_variation' => 'woocommerce_create_product_variation', '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. * 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 ) { public function hook_in( $hook_name ) {
add_action( $hook_name, array( $this, 'maybe_handle_deprecated_hook' ), -1000, 8 ); 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. * If the old hook is in-use, trigger it.
* *
* @param string $new_hook * @param string $new_hook New hook name.
* @param string $old_hook * @param string $old_hook Old hook name.
* @param array $new_callback_args * @param array $new_callback_args New callback args.
* @param mixed $return_value * @param mixed $return_value Returned value.
* @return mixed * @return mixed
*/ */
public function handle_deprecated_hook( $new_hook, $old_hook, $new_callback_args, $return_value ) { 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. * Fire off a legacy hook with it's args.
* *
* @param string $old_hook * @param string $old_hook Old hook name.
* @param array $new_callback_args * @param array $new_callback_args New callback args.
* @return mixed * @return mixed
*/ */
protected function trigger_hook( $old_hook, $new_callback_args ) { protected function trigger_hook( $old_hook, $new_callback_args ) {
switch ( $old_hook ) { switch ( $old_hook ) {
case 'woocommerce_order_add_shipping' : case 'woocommerce_order_add_shipping':
case 'woocommerce_order_add_fee' : case 'woocommerce_order_add_fee':
$item_id = $new_callback_args[0]; $item_id = $new_callback_args[0];
$item = $new_callback_args[1]; $item = $new_callback_args[1];
$order_id = $new_callback_args[2]; $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 ); do_action( $old_hook, $order_id, $item_id, $item );
} }
break; break;
case 'woocommerce_order_add_coupon' : case 'woocommerce_order_add_coupon':
$item_id = $new_callback_args[0]; $item_id = $new_callback_args[0];
$item = $new_callback_args[1]; $item = $new_callback_args[1];
$order_id = $new_callback_args[2]; $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() ); do_action( $old_hook, $order_id, $item_id, $item->get_code(), $item->get_discount(), $item->get_discount_tax() );
} }
break; break;
case 'woocommerce_order_add_tax' : case 'woocommerce_order_add_tax':
$item_id = $new_callback_args[0]; $item_id = $new_callback_args[0];
$item = $new_callback_args[1]; $item = $new_callback_args[1];
$order_id = $new_callback_args[2]; $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() ); do_action( $old_hook, $order_id, $item_id, $item->get_rate_id(), $item->get_tax_total(), $item->get_shipping_tax_total() );
} }
break; break;
case 'woocommerce_add_shipping_order_item' : case 'woocommerce_add_shipping_order_item':
$item_id = $new_callback_args[0]; $item_id = $new_callback_args[0];
$item = $new_callback_args[1]; $item = $new_callback_args[1];
$order_id = $new_callback_args[2]; $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 ); do_action( $old_hook, $order_id, $item_id, $item->legacy_package_key );
} }
break; break;
case 'woocommerce_add_order_item_meta' : case 'woocommerce_add_order_item_meta':
$item_id = $new_callback_args[0]; $item_id = $new_callback_args[0];
$item = $new_callback_args[1]; $item = $new_callback_args[1];
$order_id = $new_callback_args[2]; $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 ); do_action( $old_hook, $item_id, $item->legacy_values, $item->legacy_cart_item_key );
} }
break; break;
case 'woocommerce_add_order_fee_meta' : case 'woocommerce_add_order_fee_meta':
$item_id = $new_callback_args[0]; $item_id = $new_callback_args[0];
$item = $new_callback_args[1]; $item = $new_callback_args[1];
$order_id = $new_callback_args[2]; $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 ); do_action( $old_hook, $order_id, $item_id, $item->legacy_fee, $item->legacy_fee_key );
} }
break; break;
case 'woocommerce_order_edit_product' : case 'woocommerce_order_edit_product':
$item_id = $new_callback_args[0]; $item_id = $new_callback_args[0];
$item = $new_callback_args[1]; $item = $new_callback_args[1];
$order_id = $new_callback_args[2]; $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() ); do_action( $old_hook, $order_id, $item_id, $item, $item->get_product() );
} }
break; break;
case 'woocommerce_order_update_coupon' : case 'woocommerce_order_update_coupon':
case 'woocommerce_order_update_shipping' : case 'woocommerce_order_update_shipping':
case 'woocommerce_order_update_fee' : case 'woocommerce_order_update_fee':
case 'woocommerce_order_update_tax' : case 'woocommerce_order_update_tax':
if ( ! is_a( $item, 'WC_Order_Item_Product' ) ) { if ( ! is_a( $item, 'WC_Order_Item_Product' ) ) {
do_action( $old_hook, $order_id, $item_id, $item ); do_action( $old_hook, $order_id, $item_id, $item );
} }
break; break;
default : default:
do_action_ref_array( $old_hook, $new_callback_args ); do_action_ref_array( $old_hook, $new_callback_args );
break; break;
} }

View File

@ -1,12 +1,18 @@
<?php <?php
/**
* Deprecated filter hooks
*
* @package WooCommerce\Abstracts
* @since 3.0.0
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
/** /**
* Handles deprecation notices and triggering of legacy filter hooks. * Handles deprecation notices and triggering of legacy filter hooks
*
* @since 3.0.0
*/ */
class WC_Deprecated_Filter_Hooks extends WC_Deprecated_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', '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. * 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 ) { public function hook_in( $hook_name ) {
add_filter( $hook_name, array( $this, 'maybe_handle_deprecated_hook' ), -1000, 8 ); 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. * If the old hook is in-use, trigger it.
* *
* @param string $new_hook * @param string $new_hook New hook name.
* @param string $old_hook * @param string $old_hook Old hook name.
* @param array $new_callback_args * @param array $new_callback_args New callback args.
* @param mixed $return_value * @param mixed $return_value Returned value.
* @return mixed * @return mixed
*/ */
public function handle_deprecated_hook( $new_hook, $old_hook, $new_callback_args, $return_value ) { 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. * Fire off a legacy hook with it's args.
* *
* @param string $old_hook * @param string $old_hook Old hook name.
* @param array $new_callback_args * @param array $new_callback_args New callback args.
* @return mixed * @return mixed
*/ */
protected function trigger_hook( $old_hook, $new_callback_args ) { protected function trigger_hook( $old_hook, $new_callback_args ) {

View File

@ -887,7 +887,7 @@ class WC_Form_Handler {
// Don't use wc_clean as it destroys sanitized characters. // Don't use wc_clean as it destroys sanitized characters.
$value = sanitize_title( wp_unslash( $_REQUEST[ $taxonomy ] ) ); $value = sanitize_title( wp_unslash( $_REQUEST[ $taxonomy ] ) );
} else { } else {
$value = wc_clean( wp_unslash( $_REQUEST[ $taxonomy ] ) ); // WPCS: sanitization ok. $value = html_entity_decode( wc_clean( wp_unslash( $_REQUEST[ $taxonomy ] ) ), ENT_QUOTES, get_bloginfo( 'charset' ) ); // WPCS: sanitization ok.
} }
// Allow if valid or show error. // Allow if valid or show error.

View File

@ -21,11 +21,21 @@ if ( ! defined( 'ABSPATH' ) ) {
*/ */
class WC_Geolocation { class WC_Geolocation {
/** URL to the geolocation database we're using */ /**
const GEOLITE_DB = 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz'; * 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'; 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( private static $ip_lookup_apis = array(
'icanhazip' => 'http://icanhazip.com', 'icanhazip' => 'http://icanhazip.com',
'ipify' => 'http://api.ipify.org/', 'ipify' => 'http://api.ipify.org/',
@ -35,7 +45,11 @@ class WC_Geolocation {
'ip.appspot' => 'http://ip.appspot.com', '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( private static $geoip_apis = array(
'freegeoip' => 'https://freegeoip.net/json/%s', 'freegeoip' => 'https://freegeoip.net/json/%s',
'ipinfo.io' => 'https://ipinfo.io/%s/json', 'ipinfo.io' => 'https://ipinfo.io/%s/json',
@ -46,7 +60,7 @@ class WC_Geolocation {
* Hook in tabs. * Hook in tabs.
*/ */
public static function init() { 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 ) ) { 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' ) ); 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. * 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 * @return string
*/ */
public static function maybe_update_database( $new_value, $old_value ) { public static function maybe_update_database( $new_value, $old_value ) {
@ -66,46 +81,20 @@ class WC_Geolocation {
return $new_value; 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. * Get current user IP Address.
*
* @return string * @return string
*/ */
public static function get_ip_address() { public static function get_ip_address() {
if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) { if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) { // WPCS: input var ok, CSRF ok.
return $_SERVER['HTTP_X_REAL_IP']; return sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_REAL_IP'] ) ); // WPCS: input var ok, CSRF ok.
} elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { } 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 // 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. // 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'] ) ) ) ); 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'] ) ) { } elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) { // @codingStandardsIgnoreLine
return $_SERVER['REMOTE_ADDR']; return sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); // @codingStandardsIgnoreLine
} }
return ''; return '';
} }
@ -114,6 +103,7 @@ class WC_Geolocation {
* Get user IP Address using an external service. * Get user IP Address using an external service.
* This is used mainly as a fallback for users on localhost where * This is used mainly as a fallback for users on localhost where
* get_ip_address() will be a local IP and non-geolocatable. * get_ip_address() will be a local IP and non-geolocatable.
*
* @return string * @return string
*/ */
public static function get_external_ip_address() { public static function get_external_ip_address() {
@ -148,8 +138,9 @@ class WC_Geolocation {
/** /**
* Geolocate an IP address. * Geolocate an IP address.
* @param string $ip_address *
* @param bool $fallback If true, fallbacks to alternative IP detection (can be slower). * @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). * @param bool $api_fallback If true, uses geolocation APIs if the database file doesn't exist (can be slower).
* @return array * @return array
*/ */
@ -158,19 +149,19 @@ class WC_Geolocation {
$country_code = apply_filters( 'woocommerce_geolocate_ip', false, $ip_address, $fallback, $api_fallback ); $country_code = apply_filters( 'woocommerce_geolocate_ip', false, $ip_address, $fallback, $api_fallback );
if ( false === $country_code ) { if ( false === $country_code ) {
// If GEOIP is enabled in CloudFlare, we can use that (Settings -> CloudFlare Settings -> Settings Overview) // If GEOIP is enabled in CloudFlare, we can use that (Settings -> CloudFlare Settings -> Settings Overview).
if ( ! empty( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ) { if ( ! empty( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ) { // WPCS: input var ok, CSRF ok.
$country_code = sanitize_text_field( strtoupper( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ); $country_code = strtoupper( sanitize_text_field( wp_unslash( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ) ); // WPCS: input var ok, CSRF ok.
// WP.com VIP has a variable available. } elseif ( ! empty( $_SERVER['GEOIP_COUNTRY_CODE'] ) ) { // WPCS: input var ok, CSRF ok.
} elseif ( ! empty( $_SERVER['GEOIP_COUNTRY_CODE'] ) ) { // WP.com VIP has a variable available.
$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.
// VIP Go has a variable available also. } elseif ( ! empty( $_SERVER['HTTP_X_COUNTRY_CODE'] ) ) { // WPCS: input var ok, CSRF ok.
} elseif ( ! empty( $_SERVER['HTTP_X_COUNTRY_CODE'] ) ) { // VIP Go has a variable available also.
$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 { } else {
$ip_address = $ip_address ? $ip_address : self::get_ip_address(); $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' ); $database = self::get_local_database_path( 'v6' );
} else { } else {
$database = self::get_local_database_path(); $database = self::get_local_database_path();
@ -185,7 +176,7 @@ class WC_Geolocation {
} }
if ( ! $country_code && $fallback ) { 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 ); return self::geolocate_ip( self::get_external_ip_address(), false, $api_fallback );
} }
} }
@ -199,11 +190,12 @@ class WC_Geolocation {
/** /**
* Path to our local db. * Path to our local db.
* @param string $version *
* @param string $version Version.
* @return string * @return string
*/ */
public static function get_local_database_path( $version = 'v4' ) { public static function get_local_database_path( $version = 'v4' ) {
$version = ( 'v4' == $version ) ? '' : 'v6'; $version = 'v4' === $version ? '' : 'v6';
$upload_dir = wp_upload_dir(); $upload_dir = wp_upload_dir();
return apply_filters( 'woocommerce_geolocation_local_database_path', $upload_dir['basedir'] . '/GeoIP' . $version . '.dat', $version ); return apply_filters( 'woocommerce_geolocation_local_database_path', $upload_dir['basedir'] . '/GeoIP' . $version . '.dat', $version );
@ -220,7 +212,7 @@ class WC_Geolocation {
return; return;
} }
require_once( ABSPATH . 'wp-admin/includes/file.php' ); require_once ABSPATH . 'wp-admin/includes/file.php';
$tmp_databases = array( $tmp_databases = array(
'v4' => download_url( self::GEOLITE_DB ), 'v4' => download_url( self::GEOLITE_DB ),
@ -229,20 +221,20 @@ class WC_Geolocation {
foreach ( $tmp_databases as $tmp_database_version => $tmp_database_path ) { foreach ( $tmp_databases as $tmp_database_version => $tmp_database_path ) {
if ( ! is_wp_error( $tmp_database_path ) ) { if ( ! is_wp_error( $tmp_database_path ) ) {
$gzhandle = @gzopen( $tmp_database_path, 'r' ); $gzhandle = @gzopen( $tmp_database_path, 'r' ); // @codingStandardsIgnoreLine
$handle = @fopen( self::get_local_database_path( $tmp_database_version ), 'w' ); $handle = @fopen( self::get_local_database_path( $tmp_database_version ), 'w' ); // @codingStandardsIgnoreLine
if ( $gzhandle && $handle ) { if ( $gzhandle && $handle ) {
while ( $string = gzread( $gzhandle, 4096 ) ) { while ( $string = gzread( $gzhandle, 4096 ) ) { // @codingStandardsIgnoreLine
fwrite( $handle, $string, strlen( $string ) ); fwrite( $handle, $string, strlen( $string ) ); // @codingStandardsIgnoreLine
} }
gzclose( $gzhandle ); gzclose( $gzhandle );
$s_array = fstat( $handle ); $s_array = fstat( $handle );
fclose( $handle ); fclose( $handle ); // @codingStandardsIgnoreLine
if ( ! isset( $s_array['size'] ) || 0 === $s_array['size'] ) { if ( ! isset( $s_array['size'] ) || 0 === $s_array['size'] ) {
$logger->notice( 'Empty database file, deleting local copy.', array( 'source' => 'geolocation' ) ); $logger->notice( 'Empty database file, deleting local copy.', array( 'source' => 'geolocation' ) );
// Delete empty DB, we do not want to keep empty files around. // 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. // Reschedule download of DB.
wp_clear_scheduled_hook( 'woocommerce_geoip_updater' ); wp_clear_scheduled_hook( 'woocommerce_geoip_updater' );
wp_schedule_event( strtotime( 'first tuesday of next month' ), 'monthly', 'woocommerce_geoip_updater' ); wp_schedule_event( strtotime( 'first tuesday of next month' ), 'monthly', 'woocommerce_geoip_updater' );
@ -250,7 +242,7 @@ class WC_Geolocation {
} else { } else {
$logger->notice( 'Unable to open database file', array( 'source' => 'geolocation' ) ); $logger->notice( 'Unable to open database file', array( 'source' => 'geolocation' ) );
} }
@unlink( $tmp_database_path ); @unlink( $tmp_database_path ); // @codingStandardsIgnoreLine
} else { } else {
$logger->notice( $logger->notice(
'Unable to download GeoIP Database: ' . $tmp_database_path->get_error_message(), '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. * Use MAXMIND GeoLite database to geolocation the user.
* @param string $ip_address *
* @param string $ip_address IP address.
* @return string * @return string
*/ */
private static function geolocate_via_db( $ip_address ) { private static function geolocate_via_db( $ip_address ) {
if ( ! class_exists( 'WC_Geo_IP', false ) ) { 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(); $gi = new WC_Geo_IP();
if ( self::is_IPv6( $ip_address ) ) { if ( self::is_ipv6( $ip_address ) ) {
$database = self::get_local_database_path( 'v6' ); $database = self::get_local_database_path( 'v6' );
if ( ! self::get_file_size( $database ) ) { if ( ! self::get_file_size( $database ) ) {
return false; return false;
@ -301,14 +294,14 @@ class WC_Geolocation {
* @return bool|int * @return bool|int
*/ */
private static function get_file_size( $filename ) { private static function get_file_size( $filename ) {
$handle = @fopen( $filename, 'r' ); $handle = @fopen( $filename, 'r' ); // @codingStandardsIgnoreLine
$s_array = fstat( $handle ); $s_array = fstat( $handle ); // @codingStandardsIgnoreLine
@fclose( $handle ); @fclose( $handle ); // @codingStandardsIgnoreLine
if ( ! isset( $s_array['size'] ) || 0 === $s_array['size'] ) { if ( ! isset( $s_array['size'] ) || 0 === $s_array['size'] ) {
$logger = wc_get_logger(); $logger = wc_get_logger();
$logger->notice( 'Empty database file, deleting local copy.', array( 'source' => 'geolocation' ) ); $logger->notice( 'Empty database file, deleting local copy.', array( 'source' => 'geolocation' ) );
// Delete the file as we do not want to keep empty files around. // Delete the file as we do not want to keep empty files around.
@unlink( $filename ); @unlink( $filename ); // @codingStandardsIgnoreLine
return false; return false;
} }
return $s_array['size']; return $s_array['size'];
@ -316,7 +309,8 @@ class WC_Geolocation {
/** /**
* Use APIs to Geolocate the user. * Use APIs to Geolocate the user.
* @param string $ip_address *
* @param string $ip_address IP address.
* @return string|bool * @return string|bool
*/ */
private static function geolocate_via_api( $ip_address ) { private static function geolocate_via_api( $ip_address ) {
@ -333,21 +327,21 @@ class WC_Geolocation {
if ( ! is_wp_error( $response ) && $response['body'] ) { if ( ! is_wp_error( $response ) && $response['body'] ) {
switch ( $service_name ) { switch ( $service_name ) {
case 'ipinfo.io' : case 'ipinfo.io':
$data = json_decode( $response['body'] ); $data = json_decode( $response['body'] );
$country_code = isset( $data->country ) ? $data->country : ''; $country_code = isset( $data->country ) ? $data->country : '';
break; break;
case 'ip-api.com' : case 'ip-api.com':
$data = json_decode( $response['body'] ); $data = json_decode( $response['body'] );
$country_code = isset( $data->countryCode ) ? $data->countryCode : ''; $country_code = isset( $data->countryCode ) ? $data->countryCode : ''; // @codingStandardsIgnoreLine
break; break;
case 'freegeoip' : case 'freegeoip':
$data = json_decode( $response['body'] ); $data = json_decode( $response['body'] );
$country_code = isset( $data->country_code ) ? $data->country_code : ''; $country_code = isset( $data->country_code ) ? $data->country_code : '';
break; break;
default : default:
$country_code = apply_filters( 'woocommerce_geolocation_geoip_response_' . $service_name, '', $response['body'] ); $country_code = apply_filters( 'woocommerce_geolocation_geoip_response_' . $service_name, '', $response['body'] );
break; break;
} }
$country_code = sanitize_text_field( strtoupper( $country_code ) ); $country_code = sanitize_text_field( strtoupper( $country_code ) );
@ -369,10 +363,10 @@ class WC_Geolocation {
* *
* @since 2.4.0 * @since 2.4.0
* *
* @param string $ip_address * @param string $ip_address IP Address.
* @return bool * @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 ); return false !== filter_var( $ip_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 );
} }
} }

View File

@ -96,7 +96,11 @@ class WC_Install {
), ),
'3.3.0' => array( '3.3.0' => array(
'wc_update_330_image_options', 'wc_update_330_image_options',
<<<<<<< HEAD
'wc_update_330_webhooks', 'wc_update_330_webhooks',
=======
'wc_update_330_set_default_product_cat',
>>>>>>> master
'wc_update_330_db_version', 'wc_update_330_db_version',
), ),
); );
@ -127,7 +131,7 @@ class WC_Install {
* Init background updates * Init background updates
*/ */
public static function init_background_updater() { 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(); self::$background_updater = new WC_Background_Updater();
} }
@ -201,7 +205,7 @@ class WC_Install {
* @since 3.2.0 * @since 3.2.0
*/ */
private static function remove_admin_notices() { 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(); WC_Admin_Notices::remove_all_notices();
} }
@ -318,7 +322,8 @@ class WC_Install {
/** /**
* Update DB version to current. * 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 ) { public static function update_db_version( $version = null ) {
delete_option( 'woocommerce_db_version' ); delete_option( 'woocommerce_db_version' );
@ -327,7 +332,8 @@ class WC_Install {
/** /**
* Add more cron schedules. * Add more cron schedules.
* @param array $schedules *
* @param array $schedules List of WP scheduled cron jobs.
* @return array * @return array
*/ */
public static function cron_schedules( $schedules ) { public static function cron_schedules( $schedules ) {
@ -367,30 +373,32 @@ class WC_Install {
* Create pages that the plugin relies on, storing page IDs in variables. * Create pages that the plugin relies on, storing page IDs in variables.
*/ */
public static function create_pages() { 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(
'shop' => array( 'woocommerce_create_pages', array(
'name' => _x( 'shop', 'Page slug', 'woocommerce' ), 'shop' => array(
'title' => _x( 'Shop', 'Page title', 'woocommerce' ), 'name' => _x( 'shop', 'Page slug', 'woocommerce' ),
'content' => '', 'title' => _x( 'Shop', 'Page title', 'woocommerce' ),
), 'content' => '',
'cart' => array( ),
'name' => _x( 'cart', 'Page slug', 'woocommerce' ), 'cart' => array(
'title' => _x( 'Cart', 'Page title', 'woocommerce' ), 'name' => _x( 'cart', 'Page slug', 'woocommerce' ),
'content' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', 'title' => _x( 'Cart', 'Page title', 'woocommerce' ),
), 'content' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']',
'checkout' => array( ),
'name' => _x( 'checkout', 'Page slug', 'woocommerce' ), 'checkout' => array(
'title' => _x( 'Checkout', 'Page title', 'woocommerce' ), 'name' => _x( 'checkout', 'Page slug', 'woocommerce' ),
'content' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', 'title' => _x( 'Checkout', 'Page title', 'woocommerce' ),
), 'content' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']',
'myaccount' => array( ),
'name' => _x( 'my-account', 'Page slug', 'woocommerce' ), 'myaccount' => array(
'title' => _x( 'My account', 'Page title', 'woocommerce' ), 'name' => _x( 'my-account', 'Page slug', 'woocommerce' ),
'content' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', 'title' => _x( 'My account', 'Page title', 'woocommerce' ),
), 'content' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']',
) ); ),
)
);
foreach ( $pages as $key => $page ) { 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'] ) : '' ); wc_create_page( esc_sql( $page['name'] ), 'woocommerce_' . $key . '_page_id', $page['title'], $page['content'], ! empty( $page['parent'] ) ? wc_get_page_id( $page['parent'] ) : '' );
@ -405,8 +413,8 @@ class WC_Install {
* Sets up the default options used on the settings page. * Sets up the default options used on the settings page.
*/ */
private static function create_options() { private static function create_options() {
// Include settings so that we can run through defaults // Include settings so that we can run through defaults.
include_once( dirname( __FILE__ ) . '/admin/class-wc-admin-settings.php' ); include_once dirname( __FILE__ ) . '/admin/class-wc-admin-settings.php';
$settings = WC_Admin_Settings::get_settings_pages(); $settings = WC_Admin_Settings::get_settings_pages();
@ -432,7 +440,7 @@ class WC_Install {
*/ */
public static function create_terms() { public static function create_terms() {
$taxonomies = array( $taxonomies = array(
'product_type' => array( 'product_type' => array(
'simple', 'simple',
'grouped', 'grouped',
'variable', 'variable',
@ -453,32 +461,54 @@ class WC_Install {
foreach ( $taxonomies as $taxonomy => $terms ) { foreach ( $taxonomies as $taxonomy => $terms ) {
foreach ( $terms as $term ) { foreach ( $terms as $term ) {
if ( ! get_term_by( 'name', $term, $taxonomy ) ) { if ( ! get_term_by( 'name', $term, $taxonomy ) ) { // @codingStandardsIgnoreLine.
wp_insert_term( $term, $taxonomy ); 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 );
}
}
} }
/** /**
* Set up the database tables which the plugin needs to function. * Set up the database tables which the plugin needs to function.
* *
* Tables: * Tables:
* woocommerce_attribute_taxonomies - Table for storing attribute taxonomies - these are user defined * woocommerce_attribute_taxonomies - Table for storing attribute taxonomies - these are user defined
* woocommerce_termmeta - Term meta table - sadly WordPress does not have termmeta so we need our own * woocommerce_termmeta - Term meta table - sadly WordPress does not have termmeta so we need our own
* woocommerce_downloadable_product_permissions - Table for storing user and guest download permissions. * woocommerce_downloadable_product_permissions - Table for storing user and guest download permissions.
* KEY(order_id, product_id, download_id) used for organizing downloads on the My Account page * KEY(order_id, product_id, download_id) used for organizing downloads on the My Account page
* woocommerce_order_items - Order line items are stored in a table to make them easily queryable for reports * woocommerce_order_items - Order line items are stored in a table to make them easily queryable for reports
* woocommerce_order_itemmeta - Order line item meta is stored in a table for storing extra data. * woocommerce_order_itemmeta - Order line item meta is stored in a table for storing extra data.
* woocommerce_tax_rates - Tax Rates are stored inside 2 tables making tax queries simple and efficient. * woocommerce_tax_rates - Tax Rates are stored inside 2 tables making tax queries simple and efficient.
* woocommerce_tax_rate_locations - Each rate can be applied to more than one postcode/city hence the second table. * woocommerce_tax_rate_locations - Each rate can be applied to more than one postcode/city hence the second table.
*/ */
private static function create_tables() { private static function create_tables() {
global $wpdb; global $wpdb;
$wpdb->hide_errors(); $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 * Before updating with DBDELTA, remove any primary keys which could be
@ -504,7 +534,7 @@ class WC_Install {
/** /**
* Get Table schema. * 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. * 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 * As of WordPress 4.2, however, we moved to utf8mb4, which uses 4 bytes per character. This means that an index which
@ -730,56 +760,64 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
} }
if ( ! isset( $wp_roles ) ) { if ( ! isset( $wp_roles ) ) {
$wp_roles = new WP_Roles(); $wp_roles = new WP_Roles(); // @codingStandardsIgnoreLine
} }
// Customer role // Customer role.
add_role( 'customer', __( 'Customer', 'woocommerce' ), array( add_role(
'read' => true, 'customer',
) ); __( 'Customer', 'woocommerce' ),
array(
'read' => true,
)
);
// Shop manager role // Shop manager role.
add_role( 'shop_manager', __( 'Shop manager', 'woocommerce' ), array( add_role(
'level_9' => true, 'shop_manager',
'level_8' => true, __( 'Shop manager', 'woocommerce' ),
'level_7' => true, array(
'level_6' => true, 'level_9' => true,
'level_5' => true, 'level_8' => true,
'level_4' => true, 'level_7' => true,
'level_3' => true, 'level_6' => true,
'level_2' => true, 'level_5' => true,
'level_1' => true, 'level_4' => true,
'level_0' => true, 'level_3' => true,
'read' => true, 'level_2' => true,
'read_private_pages' => true, 'level_1' => true,
'read_private_posts' => true, 'level_0' => true,
'edit_users' => true, 'read' => true,
'edit_posts' => true, 'read_private_pages' => true,
'edit_pages' => true, 'read_private_posts' => true,
'edit_published_posts' => true, 'edit_users' => true,
'edit_published_pages' => true, 'edit_posts' => true,
'edit_private_pages' => true, 'edit_pages' => true,
'edit_private_posts' => true, 'edit_published_posts' => true,
'edit_others_posts' => true, 'edit_published_pages' => true,
'edit_others_pages' => true, 'edit_private_pages' => true,
'publish_posts' => true, 'edit_private_posts' => true,
'publish_pages' => true, 'edit_others_posts' => true,
'delete_posts' => true, 'edit_others_pages' => true,
'delete_pages' => true, 'publish_posts' => true,
'delete_private_pages' => true, 'publish_pages' => true,
'delete_private_posts' => true, 'delete_posts' => true,
'delete_published_pages' => true, 'delete_pages' => true,
'delete_published_posts' => true, 'delete_private_pages' => true,
'delete_others_posts' => true, 'delete_private_posts' => true,
'delete_others_pages' => true, 'delete_published_pages' => true,
'manage_categories' => true, 'delete_published_posts' => true,
'manage_links' => true, 'delete_others_posts' => true,
'moderate_comments' => true, 'delete_others_pages' => true,
'upload_files' => true, 'manage_categories' => true,
'export' => true, 'manage_links' => true,
'import' => true, 'moderate_comments' => true,
'list_users' => true, 'upload_files' => true,
) ); 'export' => true,
'import' => true,
'list_users' => true,
)
);
$capabilities = self::get_core_capabilities(); $capabilities = self::get_core_capabilities();
@ -796,7 +834,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
* *
* @return array * @return array
*/ */
private static function get_core_capabilities() { private static function get_core_capabilities() {
$capabilities = array(); $capabilities = array();
$capabilities['core'] = array( $capabilities['core'] = array(
@ -809,7 +847,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
foreach ( $capability_types as $capability_type ) { foreach ( $capability_types as $capability_type ) {
$capabilities[ $capability_type ] = array( $capabilities[ $capability_type ] = array(
// Post type // Post type.
"edit_{$capability_type}", "edit_{$capability_type}",
"read_{$capability_type}", "read_{$capability_type}",
"delete_{$capability_type}", "delete_{$capability_type}",
@ -824,7 +862,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
"edit_private_{$capability_type}s", "edit_private_{$capability_type}s",
"edit_published_{$capability_type}s", "edit_published_{$capability_type}s",
// Terms // Terms.
"manage_{$capability_type}_terms", "manage_{$capability_type}_terms",
"edit_{$capability_type}_terms", "edit_{$capability_type}_terms",
"delete_{$capability_type}_terms", "delete_{$capability_type}_terms",
@ -836,7 +874,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
} }
/** /**
* woocommerce_remove_roles function. * Remove WooCommerce roles.
*/ */
public static function remove_roles() { public static function remove_roles() {
global $wp_roles; global $wp_roles;
@ -846,7 +884,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
} }
if ( ! isset( $wp_roles ) ) { if ( ! isset( $wp_roles ) ) {
$wp_roles = new WP_Roles(); $wp_roles = new WP_Roles(); // @codingStandardsIgnoreLine
} }
$capabilities = self::get_core_capabilities(); $capabilities = self::get_core_capabilities();
@ -866,44 +904,45 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
* Create files/directories. * Create files/directories.
*/ */
private static function create_files() { 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 ) ) { if ( apply_filters( 'woocommerce_install_skip_create_files', false ) ) {
return; 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(); $upload_dir = wp_upload_dir();
$download_method = get_option( 'woocommerce_file_download_method', 'force' ); $download_method = get_option( 'woocommerce_file_download_method', 'force' );
$files = array( $files = array(
array( array(
'base' => $upload_dir['basedir'] . '/woocommerce_uploads', 'base' => $upload_dir['basedir'] . '/woocommerce_uploads',
'file' => 'index.html', 'file' => 'index.html',
'content' => '', 'content' => '',
), ),
array( array(
'base' => WC_LOG_DIR, 'base' => WC_LOG_DIR,
'file' => '.htaccess', 'file' => '.htaccess',
'content' => 'deny from all', 'content' => 'deny from all',
), ),
array( array(
'base' => WC_LOG_DIR, 'base' => WC_LOG_DIR,
'file' => 'index.html', 'file' => 'index.html',
'content' => '', 'content' => '',
), ),
); );
if ( 'redirect' !== $download_method ) { if ( 'redirect' !== $download_method ) {
$files[] = array( $files[] = array(
'base' => $upload_dir['basedir'] . '/woocommerce_uploads', 'base' => $upload_dir['basedir'] . '/woocommerce_uploads',
'file' => '.htaccess', 'file' => '.htaccess',
'content' => 'deny from all', 'content' => 'deny from all',
); );
} }
foreach ( $files as $file ) { foreach ( $files as $file ) {
if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['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'] ); fwrite( $file_handle, $file['content'] );
fclose( $file_handle ); fclose( $file_handle );
} }
@ -914,8 +953,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/** /**
* Show action links on the plugin screen. * Show action links on the plugin screen.
* *
* @param mixed $links Plugin Action links * @param mixed $links Plugin Action links.
* @return array * @return array
*/ */
public static function plugin_action_links( $links ) { public static function plugin_action_links( $links ) {
$action_links = array( $action_links = array(
@ -928,9 +967,9 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/** /**
* Show row meta on the plugin screen. * Show row meta on the plugin screen.
* *
* @param mixed $links Plugin Row Meta * @param mixed $links Plugin Row Meta.
* @param mixed $file Plugin Base file * @param mixed $file Plugin Base file.
* @return array * @return array
*/ */
public static function plugin_row_meta( $links, $file ) { public static function plugin_row_meta( $links, $file ) {
if ( WC_PLUGIN_BASENAME == $file ) { if ( WC_PLUGIN_BASENAME == $file ) {
@ -948,7 +987,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/** /**
* Uninstall tables when MU blog is deleted. * Uninstall tables when MU blog is deleted.
* @param array $tables *
* @param array $tables List of tables that will be deleted by WP.
* @return string[] * @return string[]
*/ */
public static function wpmu_drop_tables( $tables ) { public static function wpmu_drop_tables( $tables ) {
@ -973,7 +1013,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/** /**
* Get slug from path * Get slug from path
* @param string $key *
* @param string $key Plugin relative path. Example: woocommerce/woocommerce.php.
* @return string * @return string
*/ */
private static function format_plugin_slug( $key ) { private static function format_plugin_slug( $key ) {
@ -985,8 +1026,10 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/** /**
* Install a plugin from .org in the background via a cron job (used by * Install a plugin from .org in the background via a cron job (used by
* installer - opt in). * 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 * @since 2.6.0
*/ */
public static function background_installer( $plugin_to_install_id, $plugin_to_install ) { public static function background_installer( $plugin_to_install_id, $plugin_to_install ) {
@ -994,14 +1037,14 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
wp_clear_scheduled_hook( 'woocommerce_plugin_background_installer', func_get_args() ); wp_clear_scheduled_hook( 'woocommerce_plugin_background_installer', func_get_args() );
if ( ! empty( $plugin_to_install['repo-slug'] ) ) { if ( ! empty( $plugin_to_install['repo-slug'] ) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' ); require_once ABSPATH . 'wp-admin/includes/file.php';
require_once( ABSPATH . 'wp-admin/includes/plugin-install.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/class-wp-upgrader.php';
require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); require_once ABSPATH . 'wp-admin/includes/plugin.php';
WP_Filesystem(); WP_Filesystem();
$skin = new Automatic_Upgrader_Skin; $skin = new Automatic_Upgrader_Skin();
$upgrader = new WP_Upgrader( $skin ); $upgrader = new WP_Upgrader( $skin );
$installed_plugins = array_map( array( __CLASS__, 'format_plugin_slug' ), array_keys( get_plugins() ) ); $installed_plugins = array_map( array( __CLASS__, 'format_plugin_slug' ), array_keys( get_plugins() ) );
$plugin_slug = $plugin_to_install['repo-slug']; $plugin_slug = $plugin_to_install['repo-slug'];
@ -1009,7 +1052,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
$installed = false; $installed = false;
$activate = 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 ) ) { if ( in_array( $plugin_to_install['repo-slug'], $installed_plugins ) ) {
$installed = true; $installed = true;
$activate = ! is_plugin_active( $plugin ); $activate = ! is_plugin_active( $plugin );
@ -1017,28 +1060,31 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
// Install this thing! // Install this thing!
if ( ! $installed ) { if ( ! $installed ) {
// Suppress feedback // Suppress feedback.
ob_start(); ob_start();
try { try {
$plugin_information = plugins_api( 'plugin_information', array( $plugin_information = plugins_api(
'slug' => $plugin_to_install['repo-slug'], 'plugin_information',
'fields' => array( array(
'short_description' => false, 'slug' => $plugin_to_install['repo-slug'],
'sections' => false, 'fields' => array(
'requires' => false, 'short_description' => false,
'rating' => false, 'sections' => false,
'ratings' => false, 'requires' => false,
'downloaded' => false, 'rating' => false,
'last_updated' => false, 'ratings' => false,
'added' => false, 'downloaded' => false,
'tags' => false, 'last_updated' => false,
'homepage' => false, 'added' => false,
'donate_link' => false, 'tags' => false,
'author_profile' => false, 'homepage' => false,
'author' => false, 'donate_link' => false,
), 'author_profile' => false,
) ); 'author' => false,
),
)
);
if ( is_wp_error( $plugin_information ) ) { if ( is_wp_error( $plugin_information ) ) {
throw new Exception( $plugin_information->get_error_message() ); throw new Exception( $plugin_information->get_error_message() );
@ -1057,17 +1103,19 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
throw new Exception( $working_dir->get_error_message() ); throw new Exception( $working_dir->get_error_message() );
} }
$result = $upgrader->install_package( array( $result = $upgrader->install_package(
'source' => $working_dir, array(
'destination' => WP_PLUGIN_DIR, 'source' => $working_dir,
'clear_destination' => false, 'destination' => WP_PLUGIN_DIR,
'abort_if_destination_exists' => false, 'clear_destination' => false,
'clear_working' => true, 'abort_if_destination_exists' => false,
'hook_extra' => array( 'clear_working' => true,
'type' => 'plugin', 'hook_extra' => array(
'action' => 'install', 'type' => 'plugin',
), 'action' => 'install',
) ); ),
)
);
if ( is_wp_error( $result ) ) { if ( is_wp_error( $result ) ) {
throw new Exception( $result->get_error_message() ); throw new Exception( $result->get_error_message() );
@ -1079,6 +1127,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
WC_Admin_Notices::add_custom_notice( WC_Admin_Notices::add_custom_notice(
$plugin_to_install_id . '_install_error', $plugin_to_install_id . '_install_error',
sprintf( 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' ), __( '%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'], $plugin_to_install['name'],
$e->getMessage(), $e->getMessage(),
@ -1087,13 +1136,13 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
); );
} }
// Discard feedback // Discard feedback.
ob_end_clean(); ob_end_clean();
} }
wp_clean_plugins_cache(); wp_clean_plugins_cache();
// Activate this thing // Activate this thing.
if ( $activate ) { if ( $activate ) {
try { try {
$result = activate_plugin( $plugin ); $result = activate_plugin( $plugin );
@ -1105,6 +1154,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
WC_Admin_Notices::add_custom_notice( WC_Admin_Notices::add_custom_notice(
$plugin_to_install_id . '_install_error', $plugin_to_install_id . '_install_error',
sprintf( 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' ), __( '%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'], $plugin_to_install['name'],
admin_url( 'plugins.php' ) admin_url( 'plugins.php' )
@ -1118,7 +1168,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/** /**
* Install a theme from .org in the background via a cron job (used by installer - opt in). * 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 * @since 3.1.0
*/ */
public static function theme_background_installer( $theme_slug ) { public static function theme_background_installer( $theme_slug ) {
@ -1126,25 +1177,27 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
wp_clear_scheduled_hook( 'woocommerce_theme_background_installer', func_get_args() ); wp_clear_scheduled_hook( 'woocommerce_theme_background_installer', func_get_args() );
if ( ! empty( $theme_slug ) ) { if ( ! empty( $theme_slug ) ) {
// Suppress feedback // Suppress feedback.
ob_start(); ob_start();
try { try {
$theme = wp_get_theme( $theme_slug ); $theme = wp_get_theme( $theme_slug );
if ( ! $theme->exists() ) { if ( ! $theme->exists() ) {
require_once( ABSPATH . 'wp-admin/includes/file.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/class-wp-upgrader.php';
include_once( ABSPATH . 'wp-admin/includes/theme.php' ); include_once ABSPATH . 'wp-admin/includes/theme.php';
WP_Filesystem(); WP_Filesystem();
$skin = new Automatic_Upgrader_Skin; $skin = new Automatic_Upgrader_Skin();
$upgrader = new Theme_Upgrader( $skin ); $upgrader = new Theme_Upgrader( $skin );
$api = themes_api( 'theme_information', array( $api = themes_api(
'slug' => $theme_slug, 'theme_information', array(
'fields' => array( 'sections' => false ), 'slug' => $theme_slug,
) ); 'fields' => array( 'sections' => false ),
)
);
$result = $upgrader->install( $api->download_link ); $result = $upgrader->install( $api->download_link );
if ( is_wp_error( $result ) ) { if ( is_wp_error( $result ) ) {
@ -1161,6 +1214,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
WC_Admin_Notices::add_custom_notice( WC_Admin_Notices::add_custom_notice(
$theme_slug . '_install_error', $theme_slug . '_install_error',
sprintf( 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' ), __( '%1$s could not be installed (%2$s). <a href="%3$s">Please install it manually by clicking here.</a>', 'woocommerce' ),
$theme_slug, $theme_slug,
$e->getMessage(), $e->getMessage(),
@ -1169,7 +1223,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
); );
} }
// Discard feedback // Discard feedback.
ob_end_clean(); ob_end_clean();
} }
} }

View File

@ -258,7 +258,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
$meta->value = rawurldecode( (string) $meta->value ); $meta->value = rawurldecode( (string) $meta->value );
$attribute_key = str_replace( 'attribute_', '', $meta->key ); $attribute_key = str_replace( 'attribute_', '', $meta->key );
$display_key = wc_attribute_label( $attribute_key, $product ); $display_key = wc_attribute_label( $attribute_key, $product );
$display_value = $meta->value; $display_value = sanitize_text_field( $meta->value );
if ( taxonomy_exists( $attribute_key ) ) { if ( taxonomy_exists( $attribute_key ) ) {
$term = get_term_by( 'slug', $meta->value, $attribute_key ); $term = get_term_by( 'slug', $meta->value, $attribute_key );

View File

@ -31,6 +31,7 @@ class WC_Post_Data {
add_filter( 'post_type_link', array( __CLASS__, 'variation_post_link' ), 10, 2 ); add_filter( 'post_type_link', array( __CLASS__, 'variation_post_link' ), 10, 2 );
add_action( 'shutdown', array( __CLASS__, 'do_deferred_product_sync' ), 10 ); 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__, '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( 'transition_post_status', array( __CLASS__, 'transition_post_status' ), 10, 3 );
add_action( 'woocommerce_product_set_stock_status', array( __CLASS__, 'delete_product_query_transients' ) ); 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 ) { public static function flush_object_meta_cache( $meta_id, $object_id, $meta_key, $meta_value ) {
WC_Cache_Helper::incr_cache_prefix( 'object_' . $object_id ); 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(); 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__, 'register_post_status' ), 9 );
add_action( 'init', array( __CLASS__, 'support_jetpack_omnisearch' ) ); add_action( 'init', array( __CLASS__, 'support_jetpack_omnisearch' ) );
add_filter( 'rest_api_allowed_post_types', array( __CLASS__, 'rest_api_allowed_post_types' ) ); 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' ) ); add_action( 'woocommerce_flush_rewrite_rules', array( __CLASS__, 'flush_rewrite_rules' ) );
} }
@ -493,6 +494,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. * Flush rewrite rules.
*/ */

View File

@ -3,7 +3,7 @@
* Contains the query functions for WooCommerce which alter the front-end post queries and loops * Contains the query functions for WooCommerce which alter the front-end post queries and loops
* *
* @version 3.2.0 * @version 3.2.0
* @package WooCommerce/Classes * @package WooCommerce\Classes
* @author Automattic * @author Automattic
*/ */
@ -50,7 +50,9 @@ class WC_Query {
* Get any errors from querystring. * Get any errors from querystring.
*/ */
public function get_errors() { public function get_errors() {
if ( ! empty( $_GET['wc_error'] ) && ( $error = sanitize_text_field( $_GET['wc_error'] ) ) && ! wc_has_notice( $error, 'error' ) ) { $error = ! empty( $_GET['wc_error'] ) ? sanitize_text_field( wp_unslash( $_GET['wc_error'] ) ) : ''; // WPCS: input var ok, CSRF ok.
if ( $error && ! wc_has_notice( $error, 'error' ) ) {
wc_add_notice( $error, 'error' ); wc_add_notice( $error, 'error' );
} }
} }
@ -81,53 +83,54 @@ class WC_Query {
/** /**
* Get page title for an endpoint. * Get page title for an endpoint.
* @param string *
* @param string $endpoint Endpoint key.
* @return string * @return string
*/ */
public function get_endpoint_title( $endpoint ) { public function get_endpoint_title( $endpoint ) {
global $wp; global $wp;
switch ( $endpoint ) { switch ( $endpoint ) {
case 'order-pay' : case 'order-pay':
$title = __( 'Pay for order', 'woocommerce' ); $title = __( 'Pay for order', 'woocommerce' );
break; break;
case 'order-received' : case 'order-received':
$title = __( 'Order received', 'woocommerce' ); $title = __( 'Order received', 'woocommerce' );
break; break;
case 'orders' : case 'orders':
if ( ! empty( $wp->query_vars['orders'] ) ) { if ( ! empty( $wp->query_vars['orders'] ) ) {
/* translators: %s: page */ /* translators: %s: page */
$title = sprintf( __( 'Orders (page %d)', 'woocommerce' ), intval( $wp->query_vars['orders'] ) ); $title = sprintf( __( 'Orders (page %d)', 'woocommerce' ), intval( $wp->query_vars['orders'] ) );
} else { } else {
$title = __( 'Orders', 'woocommerce' ); $title = __( 'Orders', 'woocommerce' );
} }
break; break;
case 'view-order' : case 'view-order':
$order = wc_get_order( $wp->query_vars['view-order'] ); $order = wc_get_order( $wp->query_vars['view-order'] );
/* translators: %s: order number */ /* translators: %s: order number */
$title = ( $order ) ? sprintf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ) : ''; $title = ( $order ) ? sprintf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ) : '';
break; break;
case 'downloads' : case 'downloads':
$title = __( 'Downloads', 'woocommerce' ); $title = __( 'Downloads', 'woocommerce' );
break; break;
case 'edit-account' : case 'edit-account':
$title = __( 'Account details', 'woocommerce' ); $title = __( 'Account details', 'woocommerce' );
break; break;
case 'edit-address' : case 'edit-address':
$title = __( 'Addresses', 'woocommerce' ); $title = __( 'Addresses', 'woocommerce' );
break; break;
case 'payment-methods' : case 'payment-methods':
$title = __( 'Payment methods', 'woocommerce' ); $title = __( 'Payment methods', 'woocommerce' );
break; break;
case 'add-payment-method' : case 'add-payment-method':
$title = __( 'Add payment method', 'woocommerce' ); $title = __( 'Add payment method', 'woocommerce' );
break; break;
case 'lost-password' : case 'lost-password':
$title = __( 'Lost password', 'woocommerce' ); $title = __( 'Lost password', 'woocommerce' );
break; break;
default : default:
$title = ''; $title = '';
break; break;
} }
return apply_filters( 'woocommerce_endpoint_' . $endpoint . '_title', $title, $endpoint ); return apply_filters( 'woocommerce_endpoint_' . $endpoint . '_title', $title, $endpoint );
@ -145,7 +148,7 @@ class WC_Query {
$myaccount_page_id = get_option( 'woocommerce_myaccount_page_id' ); $myaccount_page_id = get_option( 'woocommerce_myaccount_page_id' );
$checkout_page_id = get_option( 'woocommerce_checkout_page_id' ); $checkout_page_id = get_option( 'woocommerce_checkout_page_id' );
if ( in_array( $page_on_front, array( $myaccount_page_id, $checkout_page_id ) ) ) { if ( in_array( $page_on_front, array( $myaccount_page_id, $checkout_page_id ), true ) ) {
return EP_ROOT | EP_PAGES; return EP_ROOT | EP_PAGES;
} }
} }
@ -159,7 +162,7 @@ class WC_Query {
public function add_endpoints() { public function add_endpoints() {
$mask = $this->get_endpoints_mask(); $mask = $this->get_endpoints_mask();
foreach ( $this->query_vars as $key => $var ) { foreach ( $this->get_query_vars() as $key => $var ) {
if ( ! empty( $var ) ) { if ( ! empty( $var ) ) {
add_rewrite_endpoint( $var, $mask ); add_rewrite_endpoint( $var, $mask );
} }
@ -170,7 +173,8 @@ class WC_Query {
* Add query vars. * Add query vars.
* *
* @access public * @access public
* @param array $vars *
* @param array $vars Query vars.
* @return array * @return array
*/ */
public function add_query_vars( $vars ) { public function add_query_vars( $vars ) {
@ -210,10 +214,10 @@ class WC_Query {
public function parse_request() { public function parse_request() {
global $wp; global $wp;
// Map query vars to their keys, or get them if endpoints are not supported // Map query vars to their keys, or get them if endpoints are not supported.
foreach ( $this->get_query_vars() as $key => $var ) { foreach ( $this->get_query_vars() as $key => $var ) {
if ( isset( $_GET[ $var ] ) ) { if ( isset( $_GET[ $var ] ) ) { // WPCS: input var ok, CSRF ok.
$wp->query_vars[ $key ] = $_GET[ $var ]; $wp->query_vars[ $key ] = sanitize_text_field( wp_unslash( $_GET[ $var ] ) ); // WPCS: input var ok, CSRF ok.
} elseif ( isset( $wp->query_vars[ $var ] ) ) { } elseif ( isset( $wp->query_vars[ $var ] ) ) {
$wp->query_vars[ $key ] = $wp->query_vars[ $var ]; $wp->query_vars[ $key ] = $wp->query_vars[ $var ];
} }
@ -223,8 +227,7 @@ class WC_Query {
/** /**
* Are we currently on the front page? * Are we currently on the front page?
* *
* @param object $q * @param WP_Query $q Query instance.
*
* @return bool * @return bool
*/ */
private function is_showing_page_on_front( $q ) { private function is_showing_page_on_front( $q ) {
@ -234,8 +237,7 @@ class WC_Query {
/** /**
* Is the front page a page we define? * Is the front page a page we define?
* *
* @param int $page_id * @param int $page_id Page ID.
*
* @return bool * @return bool
*/ */
private function page_on_front_is( $page_id ) { private function page_on_front_is( $page_id ) {
@ -245,18 +247,18 @@ class WC_Query {
/** /**
* Hook into pre_get_posts to do the main product query. * Hook into pre_get_posts to do the main product query.
* *
* @param object $q query object * @param WP_Query $q Query instance.
*/ */
public function pre_get_posts( $q ) { public function pre_get_posts( $q ) {
// We only want to affect the main query // We only want to affect the main query.
if ( ! $q->is_main_query() ) { if ( ! $q->is_main_query() ) {
return; return;
} }
// Fix for endpoints on the homepage // Fix for endpoints on the homepage.
if ( $this->is_showing_page_on_front( $q ) && ! $this->page_on_front_is( $q->get( 'page_id' ) ) ) { if ( $this->is_showing_page_on_front( $q ) && ! $this->page_on_front_is( $q->get( 'page_id' ) ) ) {
$_query = wp_parse_args( $q->query ); $_query = wp_parse_args( $q->query );
if ( ! empty( $_query ) && array_intersect( array_keys( $_query ), array_keys( $this->query_vars ) ) ) { if ( ! empty( $_query ) && array_intersect( array_keys( $_query ), array_keys( $this->get_query_vars() ) ) ) {
$q->is_page = true; $q->is_page = true;
$q->is_home = false; $q->is_home = false;
$q->is_singular = true; $q->is_singular = true;
@ -276,14 +278,14 @@ class WC_Query {
} }
} }
// Fix product feeds // Fix product feeds.
if ( $q->is_feed() && $q->is_post_type_archive( 'product' ) ) { if ( $q->is_feed() && $q->is_post_type_archive( 'product' ) ) {
$q->is_comment_feed = false; $q->is_comment_feed = false;
} }
// Special check for shops with the product archive on front // Special check for shops with the product archive on front.
if ( $q->is_page() && 'page' === get_option( 'show_on_front' ) && absint( $q->get( 'page_id' ) ) === wc_get_page_id( 'shop' ) ) { if ( $q->is_page() && 'page' === get_option( 'show_on_front' ) && absint( $q->get( 'page_id' ) ) === wc_get_page_id( 'shop' ) ) {
// This is a front-page shop // This is a front-page shop.
$q->set( 'post_type', 'product' ); $q->set( 'post_type', 'product' );
$q->set( 'page_id', '' ); $q->set( 'page_id', '' );
@ -291,54 +293,55 @@ class WC_Query {
$q->set( 'paged', $q->query['paged'] ); $q->set( 'paged', $q->query['paged'] );
} }
// Define a variable so we know this is the front page shop later on // Define a variable so we know this is the front page shop later on.
wc_maybe_define_constant( 'SHOP_IS_ON_FRONT', true ); wc_maybe_define_constant( 'SHOP_IS_ON_FRONT', true );
// Get the actual WP page to avoid errors and let us use is_front_page() // Get the actual WP page to avoid errors and let us use is_front_page().
// This is hacky but works. Awaiting https://core.trac.wordpress.org/ticket/21096 // This is hacky but works. Awaiting https://core.trac.wordpress.org/ticket/21096.
global $wp_post_types; global $wp_post_types;
$shop_page = get_post( wc_get_page_id( 'shop' ) ); $shop_page = get_post( wc_get_page_id( 'shop' ) );
$wp_post_types['product']->ID = $shop_page->ID; $wp_post_types['product']->ID = $shop_page->ID;
$wp_post_types['product']->post_title = $shop_page->post_title; $wp_post_types['product']->post_title = $shop_page->post_title;
$wp_post_types['product']->post_name = $shop_page->post_name; $wp_post_types['product']->post_name = $shop_page->post_name;
$wp_post_types['product']->post_type = $shop_page->post_type; $wp_post_types['product']->post_type = $shop_page->post_type;
$wp_post_types['product']->ancestors = get_ancestors( $shop_page->ID, $shop_page->post_type ); $wp_post_types['product']->ancestors = get_ancestors( $shop_page->ID, $shop_page->post_type );
// Fix conditional Functions like is_front_page // Fix conditional Functions like is_front_page.
$q->is_singular = false; $q->is_singular = false;
$q->is_post_type_archive = true; $q->is_post_type_archive = true;
$q->is_archive = true; $q->is_archive = true;
$q->is_page = true; $q->is_page = true;
// Remove post type archive name from front page title tag // Remove post type archive name from front page title tag.
add_filter( 'post_type_archive_title', '__return_empty_string', 5 ); add_filter( 'post_type_archive_title', '__return_empty_string', 5 );
// Fix WP SEO // Fix WP SEO.
if ( class_exists( 'WPSEO_Meta' ) ) { if ( class_exists( 'WPSEO_Meta' ) ) {
add_filter( 'wpseo_metadesc', array( $this, 'wpseo_metadesc' ) ); add_filter( 'wpseo_metadesc', array( $this, 'wpseo_metadesc' ) );
add_filter( 'wpseo_metakey', array( $this, 'wpseo_metakey' ) ); add_filter( 'wpseo_metakey', array( $this, 'wpseo_metakey' ) );
} }
// Only apply to product categories, the product post archive, the shop page, product tags, and product attribute taxonomies
} elseif ( ! $q->is_post_type_archive( 'product' ) && ! $q->is_tax( get_object_taxonomies( 'product' ) ) ) { } elseif ( ! $q->is_post_type_archive( 'product' ) && ! $q->is_tax( get_object_taxonomies( 'product' ) ) ) {
// Only apply to product categories, the product post archive, the shop page, product tags, and product attribute taxonomies.
return; return;
} }
$this->product_query( $q ); $this->product_query( $q );
// And remove the pre_get_posts hook // And remove the pre_get_posts hook.
$this->remove_product_query(); $this->remove_product_query();
} }
/** /**
* Search post excerpt. * Search post excerpt.
*
* @deprecated 3.2.0 - Not needed anymore since WordPress 4.5. * @deprecated 3.2.0 - Not needed anymore since WordPress 4.5.
* @param string $deprecated Deprecated.
*/ */
public function search_post_excerpt( $where = '' ) { public function search_post_excerpt( $deprecated = '' ) {
wc_deprecated_function( 'WC_Query::search_post_excerpt', '3.2.0', 'Excerpt added to search query by default since WordPress 4.5.' ); wc_deprecated_function( 'WC_Query::search_post_excerpt', '3.2.0', 'Excerpt added to search query by default since WordPress 4.5.' );
return $where; return $deprecated;
} }
/** /**
@ -346,7 +349,6 @@ class WC_Query {
* *
* Hooked into wpseo_ hook already, so no need for function_exist. * Hooked into wpseo_ hook already, so no need for function_exist.
* *
* @access public
* @return string * @return string
*/ */
public function wpseo_metadesc() { public function wpseo_metadesc() {
@ -366,9 +368,10 @@ class WC_Query {
} }
/** /**
* Query the products, applying sorting/ordering etc. This applies to the main wordpress loop. * Query the products, applying sorting/ordering etc.
* This applies to the main WordPress loop.
* *
* @param mixed $q * @param WP_Query $q Query instance.
*/ */
public function product_query( $q ) { public function product_query( $q ) {
if ( ! is_feed() ) { if ( ! is_feed() ) {
@ -381,7 +384,7 @@ class WC_Query {
} }
} }
// Query vars that affect posts shown // Query vars that affect posts shown.
$q->set( 'meta_query', $this->get_meta_query( $q->get( 'meta_query' ), true ) ); $q->set( 'meta_query', $this->get_meta_query( $q->get( 'meta_query' ), true ) );
$q->set( 'tax_query', $this->get_tax_query( $q->get( 'tax_query' ), true ) ); $q->set( 'tax_query', $this->get_tax_query( $q->get( 'tax_query' ), true ) );
$q->set( 'posts_per_page', $q->get( 'posts_per_page' ) ? $q->get( 'posts_per_page' ) : apply_filters( 'loop_shop_per_page', get_option( 'posts_per_page' ) ) ); $q->set( 'posts_per_page', $q->get( 'posts_per_page' ) ? $q->get( 'posts_per_page' ) : apply_filters( 'loop_shop_per_page', get_option( 'posts_per_page' ) ) );
@ -391,7 +394,6 @@ class WC_Query {
do_action( 'woocommerce_product_query', $q, $this ); do_action( 'woocommerce_product_query', $q, $this );
} }
/** /**
* Remove the query. * Remove the query.
*/ */
@ -411,6 +413,7 @@ class WC_Query {
/** /**
* Remove the posts_where filter. * Remove the posts_where filter.
*
* @deprecated 3.2.0 - Nothing to remove anymore because search_post_excerpt() is deprecated. * @deprecated 3.2.0 - Nothing to remove anymore because search_post_excerpt() is deprecated.
*/ */
public function remove_posts_where() { public function remove_posts_where() {
@ -420,19 +423,17 @@ class WC_Query {
/** /**
* Returns an array of arguments for ordering products based on the selected values. * Returns an array of arguments for ordering products based on the selected values.
* *
* @access public * @param string $orderby Order by.
* * @param string $order Sorting order.
* @param string $orderby
* @param string $order
* *
* @return array * @return array
*/ */
public function get_catalog_ordering_args( $orderby = '', $order = '' ) { public function get_catalog_ordering_args( $orderby = '', $order = '' ) {
// Get ordering from query string unless defined // Get ordering from query string unless defined.
if ( ! $orderby ) { if ( ! $orderby ) {
$orderby_value = isset( $_GET['orderby'] ) ? wc_clean( (string) $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) ); $orderby_value = isset( $_GET['orderby'] ) ? wc_clean( wp_unslash( (string) $_GET['orderby'] ) ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) ); // WPCS: input var ok, CSRF ok.
// Get order + orderby args from string // Get order + orderby args from string.
$orderby_value = explode( '-', $orderby_value ); $orderby_value = explode( '-', $orderby_value );
$orderby = esc_attr( $orderby_value[0] ); $orderby = esc_attr( $orderby_value[0] );
$order = ! empty( $orderby_value[1] ) ? $orderby_value[1] : $order; $order = ! empty( $orderby_value[1] ) ? $orderby_value[1] : $order;
@ -443,49 +444,49 @@ class WC_Query {
$args = array( $args = array(
'orderby' => 'relevance', 'orderby' => 'relevance',
'order' => 'DESC', 'order' => 'DESC',
'meta_key' => '', 'meta_key' => '', // WPCS: slow query ok.
); );
// Set to default. Menu order for non-searches, relevance for searches. // Set to default. Menu order for non-searches, relevance for searches.
if ( ! is_search() ) { if ( ! is_search() ) {
$args['orderby'] = 'menu_order title'; $args['orderby'] = 'menu_order title';
$args['order'] = ( 'DESC' === $order ) ? 'DESC' : 'ASC'; $args['order'] = ( 'DESC' === $order ) ? 'DESC' : 'ASC';
$args['meta_key'] = ''; $args['meta_key'] = ''; // WPCS: slow query ok.
} }
switch ( $orderby ) { switch ( $orderby ) {
case 'rand' : case 'rand':
$args['orderby'] = 'rand'; $args['orderby'] = 'rand';
break; break;
case 'date' : case 'date':
$args['orderby'] = 'date ID'; $args['orderby'] = 'date ID';
$args['order'] = ( 'ASC' === $order ) ? 'ASC' : 'DESC'; $args['order'] = ( 'ASC' === $order ) ? 'ASC' : 'DESC';
break; break;
case 'price' : case 'price':
if ( 'DESC' === $order ) { if ( 'DESC' === $order ) {
add_filter( 'posts_clauses', array( $this, 'order_by_price_desc_post_clauses' ) ); add_filter( 'posts_clauses', array( $this, 'order_by_price_desc_post_clauses' ) );
} else { } else {
add_filter( 'posts_clauses', array( $this, 'order_by_price_asc_post_clauses' ) ); add_filter( 'posts_clauses', array( $this, 'order_by_price_asc_post_clauses' ) );
} }
break; break;
case 'popularity' : case 'popularity':
$args['meta_key'] = 'total_sales'; $args['meta_key'] = 'total_sales'; // WPCS: slow query ok.
// Sorting handled later though a hook // Sorting handled later though a hook.
add_filter( 'posts_clauses', array( $this, 'order_by_popularity_post_clauses' ) ); add_filter( 'posts_clauses', array( $this, 'order_by_popularity_post_clauses' ) );
break; break;
case 'rating' : case 'rating':
$args['meta_key'] = '_wc_average_rating'; $args['meta_key'] = '_wc_average_rating'; // WPCS: slow query ok.
$args['orderby'] = array( $args['orderby'] = array(
'meta_value_num' => 'DESC', 'meta_value_num' => 'DESC',
'ID' => 'ASC', 'ID' => 'ASC',
); );
break; break;
case 'title' : case 'title':
$args['orderby'] = 'title'; $args['orderby'] = 'title';
$args['order'] = ( 'DESC' === $order ) ? 'DESC' : 'ASC'; $args['order'] = ( 'DESC' === $order ) ? 'DESC' : 'ASC';
break; break;
case 'relevance' : case 'relevance':
$args['orderby'] = 'relevance'; $args['orderby'] = 'relevance';
$args['order'] = 'DESC'; $args['order'] = 'DESC';
break; break;
@ -497,8 +498,7 @@ class WC_Query {
/** /**
* Handle numeric price sorting. * Handle numeric price sorting.
* *
* @access public * @param array $args Query args.
* @param array $args
* @return array * @return array
*/ */
public function order_by_price_asc_post_clauses( $args ) { public function order_by_price_asc_post_clauses( $args ) {
@ -527,8 +527,7 @@ class WC_Query {
/** /**
* Handle numeric price sorting. * Handle numeric price sorting.
* *
* @access public * @param array $args Query args.
* @param array $args
* @return array * @return array
*/ */
public function order_by_price_desc_post_clauses( $args ) { public function order_by_price_desc_post_clauses( $args ) {
@ -560,8 +559,7 @@ class WC_Query {
* *
* This lets us sort by meta value desc, and have a second orderby param. * This lets us sort by meta value desc, and have a second orderby param.
* *
* @access public * @param array $args Query args.
* @param array $args
* @return array * @return array
*/ */
public function order_by_popularity_post_clauses( $args ) { public function order_by_popularity_post_clauses( $args ) {
@ -574,7 +572,7 @@ class WC_Query {
* Order by rating post clauses. * Order by rating post clauses.
* *
* @deprecated 3.0.0 * @deprecated 3.0.0
* @param array $args * @param array $args Query args.
* @return array * @return array
*/ */
public function order_by_rating_post_clauses( $args ) { public function order_by_rating_post_clauses( $args ) {
@ -597,8 +595,8 @@ class WC_Query {
/** /**
* Appends meta queries to an array. * Appends meta queries to an array.
* *
* @param array $meta_query * @param array $meta_query Meta query.
* @param bool $main_query * @param bool $main_query If is main query.
* @return array * @return array
*/ */
public function get_meta_query( $meta_query = array(), $main_query = false ) { public function get_meta_query( $meta_query = array(), $main_query = false ) {
@ -611,18 +609,21 @@ class WC_Query {
/** /**
* Appends tax queries to an array. * Appends tax queries to an array.
* @param array $tax_query *
* @param bool $main_query * @param array $tax_query Tax query.
* @param bool $main_query If is main query.
* @return array * @return array
*/ */
public function get_tax_query( $tax_query = array(), $main_query = false ) { public function get_tax_query( $tax_query = array(), $main_query = false ) {
if ( ! is_array( $tax_query ) ) { if ( ! is_array( $tax_query ) ) {
$tax_query = array( 'relation' => 'AND' ); $tax_query = array(
'relation' => 'AND',
);
} }
// Layered nav filters on terms. // Layered nav filters on terms.
if ( $main_query && ( $_chosen_attributes = $this->get_layered_nav_chosen_attributes() ) ) { if ( $main_query ) {
foreach ( $_chosen_attributes as $taxonomy => $data ) { foreach ( $this->get_layered_nav_chosen_attributes() as $taxonomy => $data ) {
$tax_query[] = array( $tax_query[] = array(
'taxonomy' => $taxonomy, 'taxonomy' => $taxonomy,
'field' => 'slug', 'field' => 'slug',
@ -642,11 +643,11 @@ class WC_Query {
} }
// Filter by rating. // Filter by rating.
if ( isset( $_GET['rating_filter'] ) ) { if ( isset( $_GET['rating_filter'] ) ) { // WPCS: input var ok, CSRF ok.
$rating_filter = array_filter( array_map( 'absint', explode( ',', $_GET['rating_filter'] ) ) ); $rating_filter = array_filter( array_map( 'absint', explode( ',', $_GET['rating_filter'] ) ) ); // WPCS: input var ok, CSRF ok, Sanitization ok.
$rating_terms = array(); $rating_terms = array();
for ( $i = 1; $i <= 5; $i ++ ) { for ( $i = 1; $i <= 5; $i ++ ) {
if ( in_array( $i, $rating_filter ) && isset( $product_visibility_terms[ 'rated-' . $i ] ) ) { if ( in_array( $i, $rating_filter, true ) && isset( $product_visibility_terms[ 'rated-' . $i ] ) ) {
$rating_terms[] = $product_visibility_terms[ 'rated-' . $i ]; $rating_terms[] = $product_visibility_terms[ 'rated-' . $i ];
} }
} }
@ -675,11 +676,12 @@ class WC_Query {
/** /**
* Return a meta query for filtering by price. * Return a meta query for filtering by price.
*
* @return array * @return array
*/ */
private function price_filter_meta_query() { private function price_filter_meta_query() {
if ( isset( $_GET['max_price'] ) || isset( $_GET['min_price'] ) ) { if ( isset( $_GET['max_price'] ) || isset( $_GET['min_price'] ) ) { // WPCS: input var ok, CSRF ok.
$meta_query = wc_get_min_max_price_meta_query( $_GET ); $meta_query = wc_get_min_max_price_meta_query( $_GET ); // WPCS: input var ok, CSRF ok.
$meta_query['price_filter'] = true; $meta_query['price_filter'] = true;
return $meta_query; return $meta_query;
@ -702,7 +704,7 @@ class WC_Query {
* Returns a meta query to handle product visibility. * Returns a meta query to handle product visibility.
* *
* @deprecated 3.0.0 Replaced with taxonomy. * @deprecated 3.0.0 Replaced with taxonomy.
* @param string $compare (default: 'IN') * @param string $compare Compare type.
* @return array * @return array
*/ */
public function visibility_meta_query( $compare = 'IN' ) { public function visibility_meta_query( $compare = 'IN' ) {
@ -713,7 +715,7 @@ class WC_Query {
* Returns a meta query to handle product stock status. * Returns a meta query to handle product stock status.
* *
* @deprecated 3.0.0 Replaced with taxonomy. * @deprecated 3.0.0 Replaced with taxonomy.
* @param string $status (default: 'instock') * @param string $status Status.
* @return array * @return array
*/ */
public function stock_status_meta_query( $status = 'instock' ) { public function stock_status_meta_query( $status = 'instock' ) {
@ -722,6 +724,7 @@ class WC_Query {
/** /**
* Get the tax query which was used by the main query. * Get the tax query which was used by the main query.
*
* @return array * @return array
*/ */
public static function get_main_tax_query() { public static function get_main_tax_query() {
@ -734,6 +737,7 @@ class WC_Query {
/** /**
* Get the meta query which was used by the main query. * Get the meta query which was used by the main query.
*
* @return array * @return array
*/ */
public static function get_main_meta_query() { public static function get_main_meta_query() {
@ -769,7 +773,7 @@ class WC_Query {
} }
$like = '%' . $wpdb->esc_like( $term ) . '%'; $like = '%' . $wpdb->esc_like( $term ) . '%';
$sql[] = $wpdb->prepare( "(($wpdb->posts.post_title $like_op %s) $andor_op ($wpdb->posts.post_excerpt $like_op %s) $andor_op ($wpdb->posts.post_content $like_op %s))", $like, $like, $like ); $sql[] = $wpdb->prepare( "(($wpdb->posts.post_title $like_op %s) $andor_op ($wpdb->posts.post_excerpt $like_op %s) $andor_op ($wpdb->posts.post_content $like_op %s))", $like, $like, $like ); // WPCS: db call ok, cache ok, unprepared SQL ok.
} }
if ( ! empty( $sql ) && ! is_user_logged_in() ) { if ( ! empty( $sql ) && ! is_user_logged_in() ) {
@ -781,23 +785,26 @@ class WC_Query {
/** /**
* Layered Nav Init. * Layered Nav Init.
*
* @return array
*/ */
public static function get_layered_nav_chosen_attributes() { public static function get_layered_nav_chosen_attributes() {
if ( ! is_array( self::$_chosen_attributes ) ) { if ( ! is_array( self::$_chosen_attributes ) ) {
self::$_chosen_attributes = array(); self::$_chosen_attributes = array();
if ( $attribute_taxonomies = wc_get_attribute_taxonomies() ) { $attribute_taxonomies = wc_get_attribute_taxonomies();
if ( $attribute_taxonomies ) {
foreach ( $attribute_taxonomies as $tax ) { foreach ( $attribute_taxonomies as $tax ) {
$attribute = wc_sanitize_taxonomy_name( $tax->attribute_name ); $attribute = wc_sanitize_taxonomy_name( $tax->attribute_name );
$taxonomy = wc_attribute_taxonomy_name( $attribute ); $taxonomy = wc_attribute_taxonomy_name( $attribute );
$filter_terms = ! empty( $_GET[ 'filter_' . $attribute ] ) ? explode( ',', wc_clean( $_GET[ 'filter_' . $attribute ] ) ) : array(); $filter_terms = ! empty( $_GET[ 'filter_' . $attribute ] ) ? explode( ',', wc_clean( wp_unslash( $_GET[ 'filter_' . $attribute ] ) ) ) : array(); // WPCS: input var ok, CSRF ok.
if ( empty( $filter_terms ) || ! taxonomy_exists( $taxonomy ) ) { if ( empty( $filter_terms ) || ! taxonomy_exists( $taxonomy ) ) {
continue; continue;
} }
$query_type = ! empty( $_GET[ 'query_type_' . $attribute ] ) && in_array( $_GET[ 'query_type_' . $attribute ], array( 'and', 'or' ) ) ? wc_clean( $_GET[ 'query_type_' . $attribute ] ) : ''; $query_type = ! empty( $_GET[ 'query_type_' . $attribute ] ) && in_array( wp_unslash( $_GET[ 'query_type_' . $attribute ] ), array( 'and', 'or' ), true ) ? wc_clean( wp_unslash( $_GET[ 'query_type_' . $attribute ] ) ) : ''; // WPCS: input var ok, CSRF ok.
self::$_chosen_attributes[ $taxonomy ]['terms'] = array_map( 'sanitize_title', $filter_terms ); // Ensures correct encoding self::$_chosen_attributes[ $taxonomy ]['terms'] = array_map( 'sanitize_title', $filter_terms ); // Ensures correct encoding.
self::$_chosen_attributes[ $taxonomy ]['query_type'] = $query_type ? $query_type : apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' ); self::$_chosen_attributes[ $taxonomy ]['query_type'] = $query_type ? $query_type : apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' );
} }
} }
@ -806,6 +813,8 @@ class WC_Query {
} }
/** /**
* Layered nav init.
*
* @deprecated 2.6.0 * @deprecated 2.6.0
*/ */
public function layered_nav_init() { public function layered_nav_init() {
@ -814,6 +823,7 @@ class WC_Query {
/** /**
* Get an unpaginated list all product IDs (both filtered and unfiltered). Makes use of transients. * Get an unpaginated list all product IDs (both filtered and unfiltered). Makes use of transients.
*
* @deprecated 2.6.0 due to performance concerns * @deprecated 2.6.0 due to performance concerns
*/ */
public function get_products_in_view() { public function get_products_in_view() {
@ -822,11 +832,12 @@ class WC_Query {
/** /**
* Layered Nav post filter. * Layered Nav post filter.
*
* @deprecated 2.6.0 due to performance concerns * @deprecated 2.6.0 due to performance concerns
* *
* @param $filtered_posts * @param mixed $deprecated Deprecated.
*/ */
public function layered_nav_query( $filtered_posts ) { public function layered_nav_query( $deprecated ) {
wc_deprecated_function( 'layered_nav_query', '2.6' ); wc_deprecated_function( 'layered_nav_query', '2.6' );
} }
} }

View File

@ -579,7 +579,7 @@ class WC_Tax {
} elseif ( WC()->cart->get_cart() ) { } elseif ( WC()->cart->get_cart() ) {
// This will be per order shipping - loop through the order and find the highest tax class rate // This will be per order shipping - loop through the order and find the highest tax class rate
$cart_tax_classes = WC()->cart->get_cart_item_tax_classes(); $cart_tax_classes = WC()->cart->get_cart_item_tax_classes_for_shipping();
// No tax classes = no taxable items. // No tax classes = no taxable items.
if ( empty( $cart_tax_classes ) ) { if ( empty( $cart_tax_classes ) ) {

View File

@ -1,4 +1,10 @@
<?php <?php
/**
* Abstract_WC_Order_Data_Store_CPT class file.
*
* @package WooCommerce/Classes
*/
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
@ -46,25 +52,31 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/** /**
* Method to create a new order in the database. * Method to create a new order in the database.
* @param WC_Order $order *
* @param WC_Order $order Order object.
*/ */
public function create( &$order ) { public function create( &$order ) {
$order->set_version( WC_VERSION ); $order->set_version( WC_VERSION );
$order->set_date_created( current_time( 'timestamp', true ) ); $order->set_date_created( current_time( 'timestamp', true ) );
$order->set_currency( $order->get_currency() ? $order->get_currency() : get_woocommerce_currency() ); $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(
'post_date' => gmdate( 'Y-m-d H:i:s', $order->get_date_created( 'edit' )->getOffsetTimestamp() ), apply_filters(
'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $order->get_date_created( 'edit' )->getTimestamp() ), 'woocommerce_new_order_data',
'post_type' => $order->get_type( 'edit' ), array(
'post_status' => 'wc-' . ( $order->get_status( 'edit' ) ? $order->get_status( 'edit' ) : apply_filters( 'woocommerce_default_order_status', 'pending' ) ), 'post_date' => gmdate( 'Y-m-d H:i:s', $order->get_date_created( 'edit' )->getOffsetTimestamp() ),
'ping_status' => 'closed', 'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $order->get_date_created( 'edit' )->getTimestamp() ),
'post_author' => 1, 'post_type' => $order->get_type( 'edit' ),
'post_title' => $this->get_post_title(), 'post_status' => 'wc-' . ( $order->get_status( 'edit' ) ? $order->get_status( 'edit' ) : apply_filters( 'woocommerce_default_order_status', 'pending' ) ),
'post_password' => uniqid( 'order_' ), 'ping_status' => 'closed',
'post_parent' => $order->get_parent_id( 'edit' ), 'post_author' => 1,
'post_excerpt' => $this->get_post_excerpt( $order ), 'post_title' => $this->get_post_title(),
) ), true ); 'post_password' => uniqid( 'order_' ),
'post_parent' => $order->get_parent_id( 'edit' ),
'post_excerpt' => $this->get_post_excerpt( $order ),
)
), true
);
if ( $id && ! is_wp_error( $id ) ) { if ( $id && ! is_wp_error( $id ) ) {
$order->set_id( $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. * 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 ) { public function read( &$order ) {
$order->set_defaults(); $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' ) ); throw new Exception( __( 'Invalid order.', 'woocommerce' ) );
} }
$order->set_props( array( $order->set_props(
'parent_id' => $post_object->post_parent, array(
'date_created' => 0 < $post_object->post_date_gmt ? wc_string_to_timestamp( $post_object->post_date_gmt ) : null, 'parent_id' => $post_object->post_parent,
'date_modified' => 0 < $post_object->post_modified_gmt ? wc_string_to_timestamp( $post_object->post_modified_gmt ) : null, 'date_created' => 0 < $post_object->post_date_gmt ? wc_string_to_timestamp( $post_object->post_date_gmt ) : null,
'status' => $post_object->post_status, '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 ); $this->read_order_data( $order, $post_object );
$order->read_meta_data(); $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. * Method to update an order in the database.
* @param WC_Order $order *
* @param WC_Order $order Order object.
*/ */
public function update( &$order ) { public function update( &$order ) {
$order->save_meta_data(); $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. * Method to delete an order from the database.
* @param WC_Order $order *
* @param array $args Array of args to pass to the delete method. * @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() ) { public function delete( &$order, $args = array() ) {
$id = $order->get_id(); $id = $order->get_id();
$args = wp_parse_args( $args, array( $args = wp_parse_args(
'force_delete' => false, $args,
) ); array(
'force_delete' => false,
)
);
if ( ! $id ) { if ( ! $id ) {
return; return;
@ -188,7 +210,7 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/** /**
* Excerpt for post. * Excerpt for post.
* *
* @param WC_order $order * @param WC_order $order Order object.
* @return string * @return string
*/ */
protected function get_post_excerpt( $order ) { protected function get_post_excerpt( $order ) {
@ -210,24 +232,26 @@ 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. * Read order data. Can be overridden by child classes to load other props.
* *
* @param WC_Order $order * @param WC_Order $order Order object.
* @param object $post_object * @param object $post_object Post object.
* @since 3.0.0 * @since 3.0.0
*/ */
protected function read_order_data( &$order, $post_object ) { protected function read_order_data( &$order, $post_object ) {
$id = $order->get_id(); $id = $order->get_id();
$order->set_props( array( $order->set_props(
'currency' => get_post_meta( $id, '_order_currency', true ), array(
'discount_total' => get_post_meta( $id, '_cart_discount', true ), 'currency' => get_post_meta( $id, '_order_currency', true ),
'discount_tax' => get_post_meta( $id, '_cart_discount_tax', true ), 'discount_total' => get_post_meta( $id, '_cart_discount', true ),
'shipping_total' => get_post_meta( $id, '_order_shipping', true ), 'discount_tax' => get_post_meta( $id, '_cart_discount_tax', true ),
'shipping_tax' => get_post_meta( $id, '_order_shipping_tax', true ), 'shipping_total' => get_post_meta( $id, '_order_shipping', true ),
'cart_tax' => get_post_meta( $id, '_order_tax', true ), 'shipping_tax' => get_post_meta( $id, '_order_shipping_tax', true ),
'total' => get_post_meta( $id, '_order_total', true ), 'cart_tax' => get_post_meta( $id, '_order_tax', true ),
'version' => get_post_meta( $id, '_order_version', true ), 'total' => get_post_meta( $id, '_order_total', 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' ), '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. // Gets extra data associated with the order if needed.
foreach ( $order->get_extra_data_keys() as $key ) { 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. * 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 * @since 3.0.0
*/ */
protected function update_post_meta( &$order ) { 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. * Clear any caches.
* *
* @param WC_Order $order * @param WC_Order $order Order object.
* @since 3.0.0 * @since 3.0.0
*/ */
protected function clear_caches( &$order ) { 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. * Read order items of a specific type from the database for this order.
* *
* @param WC_Order $order * @param WC_Order $order Order object.
* @param string $type * @param string $type Order item type.
* @return array * @return array
*/ */
public function read_items( $order, $type ) { 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' ); $items = wp_cache_get( 'order-items-' . $order->get_id(), 'orders' );
if ( false === $items ) { 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(
$items = $wpdb->get_results( $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() )
);
foreach ( $items as $item ) { foreach ( $items as $item ) {
wp_cache_set( 'item-' . $item->order_item_id, $item, 'order-items' ); 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. * 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. * @param string $type Order item type. Default null.
*/ */
public function delete_items( $order, $type = 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. * Get token ids for an order.
* *
* @param WC_Order $order * @param WC_Order $order Order object.
* @return array * @return array
*/ */
public function get_payment_token_ids( $order ) { 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. * Update token ids for an order.
* *
* @param WC_Order $order * @param WC_Order $order Order object.
* @param array $token_ids * @param array $token_ids Payment token ids.
*/ */
public function update_payment_token_ids( $order, $token_ids ) { public function update_payment_token_ids( $order, $token_ids ) {
update_post_meta( $order->get_id(), '_payment_tokens', $token_ids ); update_post_meta( $order->get_id(), '_payment_tokens', $token_ids );

View File

@ -1,4 +1,10 @@
<?php <?php
/**
* WC_Order_Data_Store_CPT class file.
*
* @package WooCommerce/Classes
*/
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; 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. * Data stored in meta keys, but not considered "meta" for an order.
*
* @since 3.0.0 * @since 3.0.0
* @var array * @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. * Method to create a new order in the database.
* @param WC_Order $order *
* @param WC_Order $order Order object.
*/ */
public function create( &$order ) { public function create( &$order ) {
$order->set_order_key( 'wc_' . apply_filters( 'woocommerce_generate_order_key', uniqid( '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. * Read order data. Can be overridden by child classes to load other props.
* *
* @param WC_Order $order * @param WC_Order $order Order object.
* @param object $post_object * @param object $post_object Post object.
* @since 3.0.0 * @since 3.0.0
*/ */
protected function read_order_data( &$order, $post_object ) { protected function read_order_data( &$order, $post_object ) {
@ -99,45 +107,48 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
$date_paid = get_post_meta( $id, '_paid_date', true ); $date_paid = get_post_meta( $id, '_paid_date', true );
} }
$order->set_props( array( $order->set_props(
'order_key' => get_post_meta( $id, '_order_key', true ), array(
'customer_id' => get_post_meta( $id, '_customer_user', true ), 'order_key' => get_post_meta( $id, '_order_key', true ),
'billing_first_name' => get_post_meta( $id, '_billing_first_name', true ), 'customer_id' => get_post_meta( $id, '_customer_user', true ),
'billing_last_name' => get_post_meta( $id, '_billing_last_name', true ), 'billing_first_name' => get_post_meta( $id, '_billing_first_name', true ),
'billing_company' => get_post_meta( $id, '_billing_company', true ), 'billing_last_name' => get_post_meta( $id, '_billing_last_name', true ),
'billing_address_1' => get_post_meta( $id, '_billing_address_1', true ), 'billing_company' => get_post_meta( $id, '_billing_company', true ),
'billing_address_2' => get_post_meta( $id, '_billing_address_2', true ), 'billing_address_1' => get_post_meta( $id, '_billing_address_1', true ),
'billing_city' => get_post_meta( $id, '_billing_city', true ), 'billing_address_2' => get_post_meta( $id, '_billing_address_2', true ),
'billing_state' => get_post_meta( $id, '_billing_state', true ), 'billing_city' => get_post_meta( $id, '_billing_city', true ),
'billing_postcode' => get_post_meta( $id, '_billing_postcode', true ), 'billing_state' => get_post_meta( $id, '_billing_state', true ),
'billing_country' => get_post_meta( $id, '_billing_country', true ), 'billing_postcode' => get_post_meta( $id, '_billing_postcode', true ),
'billing_email' => get_post_meta( $id, '_billing_email', true ), 'billing_country' => get_post_meta( $id, '_billing_country', true ),
'billing_phone' => get_post_meta( $id, '_billing_phone', true ), 'billing_email' => get_post_meta( $id, '_billing_email', true ),
'shipping_first_name' => get_post_meta( $id, '_shipping_first_name', true ), 'billing_phone' => get_post_meta( $id, '_billing_phone', true ),
'shipping_last_name' => get_post_meta( $id, '_shipping_last_name', true ), 'shipping_first_name' => get_post_meta( $id, '_shipping_first_name', true ),
'shipping_company' => get_post_meta( $id, '_shipping_company', true ), 'shipping_last_name' => get_post_meta( $id, '_shipping_last_name', true ),
'shipping_address_1' => get_post_meta( $id, '_shipping_address_1', true ), 'shipping_company' => get_post_meta( $id, '_shipping_company', true ),
'shipping_address_2' => get_post_meta( $id, '_shipping_address_2', true ), 'shipping_address_1' => get_post_meta( $id, '_shipping_address_1', true ),
'shipping_city' => get_post_meta( $id, '_shipping_city', true ), 'shipping_address_2' => get_post_meta( $id, '_shipping_address_2', true ),
'shipping_state' => get_post_meta( $id, '_shipping_state', true ), 'shipping_city' => get_post_meta( $id, '_shipping_city', true ),
'shipping_postcode' => get_post_meta( $id, '_shipping_postcode', true ), 'shipping_state' => get_post_meta( $id, '_shipping_state', true ),
'shipping_country' => get_post_meta( $id, '_shipping_country', true ), 'shipping_postcode' => get_post_meta( $id, '_shipping_postcode', true ),
'payment_method' => get_post_meta( $id, '_payment_method', true ), 'shipping_country' => get_post_meta( $id, '_shipping_country', true ),
'payment_method_title' => get_post_meta( $id, '_payment_method_title', true ), 'payment_method' => get_post_meta( $id, '_payment_method', true ),
'transaction_id' => get_post_meta( $id, '_transaction_id', true ), 'payment_method_title' => get_post_meta( $id, '_payment_method_title', true ),
'customer_ip_address' => get_post_meta( $id, '_customer_ip_address', true ), 'transaction_id' => get_post_meta( $id, '_transaction_id', true ),
'customer_user_agent' => get_post_meta( $id, '_customer_user_agent', true ), 'customer_ip_address' => get_post_meta( $id, '_customer_ip_address', true ),
'created_via' => get_post_meta( $id, '_created_via', true ), 'customer_user_agent' => get_post_meta( $id, '_customer_user_agent', true ),
'date_completed' => $date_completed, 'created_via' => get_post_meta( $id, '_created_via', true ),
'date_paid' => $date_paid, 'date_completed' => $date_completed,
'cart_hash' => get_post_meta( $id, '_cart_hash', true ), 'date_paid' => $date_paid,
'customer_note' => $post_object->post_excerpt, 'cart_hash' => get_post_meta( $id, '_cart_hash', true ),
) ); 'customer_note' => $post_object->post_excerpt,
)
);
} }
/** /**
* Method to update an order in the database. * Method to update an order in the database.
* @param WC_Order $order *
* @param WC_Order $order Order object.
*/ */
public function update( &$order ) { public function update( &$order ) {
// Before updating, ensure date paid is set if missing. // 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. * 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 * @since 3.0.0
*/ */
protected function update_post_meta( &$order ) { protected function update_post_meta( &$order ) {
@ -201,7 +212,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
} }
$address_props = array( $address_props = array(
'billing' => array( 'billing' => array(
'_billing_first_name' => 'billing_first_name', '_billing_first_name' => 'billing_first_name',
'_billing_last_name' => 'billing_last_name', '_billing_last_name' => 'billing_last_name',
'_billing_company' => 'billing_company', '_billing_company' => 'billing_company',
@ -259,7 +270,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/** /**
* Excerpt for post. * Excerpt for post.
* *
* @param WC_Order $order * @param WC_Order $order Order object.
* @return string * @return string
*/ */
protected function get_post_excerpt( $order ) { 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. * Get amount already refunded.
* *
* @param WC_Order $order * @param WC_Order $order Order object.
* @return string * @return string
*/ */
public function get_total_refunded( $order ) { public function get_total_refunded( $order ) {
global $wpdb; global $wpdb;
$total = $wpdb->get_var( $wpdb->prepare( " $total = $wpdb->get_var(
SELECT SUM( postmeta.meta_value ) $wpdb->prepare(
FROM $wpdb->postmeta AS postmeta "SELECT SUM( postmeta.meta_value )
INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d ) FROM $wpdb->postmeta AS postmeta
WHERE postmeta.meta_key = '_refund_amount' INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )
AND postmeta.post_id = posts.ID WHERE postmeta.meta_key = '_refund_amount'
", $order->get_id() ) ); AND postmeta.post_id = posts.ID",
$order->get_id()
)
);
return $total; 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. * Get the total tax refunded.
* *
* @param WC_Order $order * @param WC_Order $order Order object.
* @return float * @return float
*/ */
public function get_total_tax_refunded( $order ) { public function get_total_tax_refunded( $order ) {
global $wpdb; global $wpdb;
$total = $wpdb->get_var( $wpdb->prepare( " $total = $wpdb->get_var(
SELECT SUM( order_itemmeta.meta_value ) $wpdb->prepare(
FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta "SELECT SUM( order_itemmeta.meta_value )
INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d ) FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'tax' ) INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )
WHERE order_itemmeta.order_item_id = order_items.order_item_id INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'tax' )
AND order_itemmeta.meta_key IN ('tax_amount', 'shipping_tax_amount') WHERE order_itemmeta.order_item_id = order_items.order_item_id
", $order->get_id() ) ); AND order_itemmeta.meta_key IN ('tax_amount', 'shipping_tax_amount')",
$order->get_id()
)
);
return abs( $total ); 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. * Get the total shipping refunded.
* *
* @param WC_Order $order * @param WC_Order $order Order object.
* @return float * @return float
*/ */
public function get_total_shipping_refunded( $order ) { public function get_total_shipping_refunded( $order ) {
global $wpdb; global $wpdb;
$total = $wpdb->get_var( $wpdb->prepare( " $total = $wpdb->get_var(
SELECT SUM( order_itemmeta.meta_value ) $wpdb->prepare(
FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta "SELECT SUM( order_itemmeta.meta_value )
INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d ) FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'shipping' ) INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )
WHERE order_itemmeta.order_item_id = order_items.order_item_id INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'shipping' )
AND order_itemmeta.meta_key IN ('cost') WHERE order_itemmeta.order_item_id = order_items.order_item_id
", $order->get_id() ) ); AND order_itemmeta.meta_key IN ('cost')",
$order->get_id()
)
);
return abs( $total ); 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. * 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 * @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 ) { 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. * 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 * @return int
*/ */
public function get_order_count( $status ) { 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. * @deprecated 3.1.0 - Use wc_get_orders instead.
* @see wc_get_orders() * @see wc_get_orders()
* *
* @param array $args * @param array $args List of args passed to wc_get_orders().
* *
* @return array|object * @return array|object
*/ */
@ -368,19 +388,19 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
/** /**
* Generate meta query for wc_get_orders. * Generate meta query for wc_get_orders.
* *
* @param array $values * @param array $values List of customers ids or emails.
* @param string $relation * @param string $relation 'or' or 'and' relation used to build the WP meta_query.
* @return array * @return array
*/ */
private function get_orders_generate_customer_meta_query( $values, $relation = 'or' ) { private function get_orders_generate_customer_meta_query( $values, $relation = 'or' ) {
$meta_query = array( $meta_query = array(
'relation' => strtoupper( $relation ), 'relation' => strtoupper( $relation ),
'customer_emails' => array( 'customer_emails' => array(
'key' => '_billing_email', 'key' => '_billing_email',
'value' => array(), 'value' => array(),
'compare' => 'IN', 'compare' => 'IN',
), ),
'customer_ids' => array( 'customer_ids' => array(
'key' => '_customer_user', 'key' => '_customer_user',
'value' => array(), 'value' => array(),
'compare' => 'IN', 'compare' => 'IN',
@ -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, * Get unpaid orders after a certain date,
* *
* @param int $date timestamp * @param int $date Timestamp.
* @return array * @return array
*/ */
public function get_unpaid_orders( $date ) { public function get_unpaid_orders( $date ) {
global $wpdb; global $wpdb;
$unpaid_orders = $wpdb->get_col( $wpdb->prepare( " $unpaid_orders = $wpdb->get_col(
SELECT posts.ID $wpdb->prepare(
FROM {$wpdb->posts} AS posts // @codingStandardsIgnoreStart
WHERE posts.post_type IN ('" . implode( "','", wc_get_order_types() ) . "') "SELECT posts.ID
AND posts.post_status = 'wc-pending' FROM {$wpdb->posts} AS posts
AND posts.post_modified < %s WHERE posts.post_type IN ('" . implode( "','", wc_get_order_types() ) . "')
", date( 'Y-m-d H:i:s', absint( $date ) ) ) ); AND posts.post_status = 'wc-pending'
AND posts.post_modified < %s",
// @codingStandardsIgnoreEnd
date( 'Y-m-d H:i:s', absint( $date ) )
)
);
return $unpaid_orders; 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. * Search order data for a term and return ids.
* *
* @param string $term * @param string $term Searched term.
* @return array of ids * @return array of ids
*/ */
public function search_orders( $term ) { public function search_orders( $term ) {
@ -448,36 +473,45 @@ 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. * 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. * 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). * This however won't work on older orders unless updated, so search a few others (expand this using the filter if needed).
*
* @var array * @var array
*/ */
$search_fields = array_map( 'wc_clean', apply_filters( 'woocommerce_shop_order_search_fields', array( $search_fields = array_map(
'_billing_address_index', 'wc_clean', apply_filters(
'_shipping_address_index', 'woocommerce_shop_order_search_fields', array(
'_billing_last_name', '_billing_address_index',
'_billing_email', '_shipping_address_index',
) ) ); '_billing_last_name',
$order_ids = array(); '_billing_email',
)
)
);
$order_ids = array();
if ( is_numeric( $term ) ) { if ( is_numeric( $term ) ) {
$order_ids[] = absint( $term ); $order_ids[] = absint( $term );
} }
if ( ! empty( $search_fields ) ) { if ( ! empty( $search_fields ) ) {
$order_ids = array_unique( array_merge( $order_ids = array_unique(
$order_ids, array_merge(
$wpdb->get_col( $order_ids,
$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->get_col(
), $wpdb->prepare(
$wpdb->get_col( "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->prepare( " '%' . $wpdb->esc_like( wc_clean( $term ) ) . '%'
SELECT order_id )
FROM {$wpdb->prefix}woocommerce_order_items as order_items ),
WHERE order_item_name LIKE '%%%s%%' $wpdb->get_col(
", $wpdb->prepare(
$wpdb->esc_like( wc_clean( $term ) ) "SELECT order_id
FROM {$wpdb->prefix}woocommerce_order_items as order_items
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 ); 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. * 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 * @return bool
*/ */
public function get_download_permissions_granted( $order ) { 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. * Stores information about whether permissions were generated yet.
* *
* @param WC_Order|int $order * @param WC_Order|int $order Order ID or order object.
* @param bool $set * @param bool $set True or false.
*/ */
public function set_download_permissions_granted( $order, $set ) { public function set_download_permissions_granted( $order, $set ) {
$order_id = WC_Order_Factory::get_order_id( $order ); $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. * Gets information about whether sales were recorded.
* *
* @param WC_Order|int $order * @param WC_Order|int $order Order ID or order object.
* @return bool * @return bool
*/ */
public function get_recorded_sales( $order ) { 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. * Stores information about whether sales were recorded.
* *
* @param WC_Order|int $order * @param WC_Order|int $order Order ID or order object.
* @param bool $set * @param bool $set True or false.
*/ */
public function set_recorded_sales( $order, $set ) { public function set_recorded_sales( $order, $set ) {
$order_id = WC_Order_Factory::get_order_id( $order ); $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. * 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 * @return bool
*/ */
public function get_recorded_coupon_usage_counts( $order ) { 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. * Stores information about whether coupon counts were updated.
* *
* @param WC_Order|int $order * @param WC_Order|int $order Order ID or order object.
* @param bool $set * @param bool $set True or false.
*/ */
public function set_recorded_coupon_usage_counts( $order, $set ) { public function set_recorded_coupon_usage_counts( $order, $set ) {
$order_id = WC_Order_Factory::get_order_id( $order ); $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. * Gets information about whether stock was reduced.
* *
* @param WC_Order|int $order * @param WC_Order|int $order Order ID or order object.
* @return bool * @return bool
*/ */
public function get_stock_reduced( $order ) { 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. * Stores information about whether stock was reduced.
* *
* @param WC_Order|int $order * @param WC_Order|int $order Order ID or order object.
* @param bool $set * @param bool $set True or false.
*/ */
public function set_stock_reduced( $order, $set ) { public function set_stock_reduced( $order, $set ) {
$order_id = WC_Order_Factory::get_order_id( $order ); $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. * Get the order type based on Order ID.
* *
* @since 3.0.0 * @since 3.0.0
* @param int $order_id * @param int $order_id Order ID.
* @return string * @return string
*/ */
public function get_order_type( $order_id ) { 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. * Get valid WP_Query args from a WC_Order_Query's query variables.
* *
* @since 3.1.0 * @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 * @return array
*/ */
protected function get_wp_query_args( $query_vars ) { protected function get_wp_query_args( $query_vars ) {
@ -654,7 +688,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
} }
if ( isset( $query_vars['customer'] ) && '' !== $query_vars['customer'] && array() !== $query_vars['customer'] ) { if ( isset( $query_vars['customer'] ) && '' !== $query_vars['customer'] && array() !== $query_vars['customer'] ) {
$values = is_array( $query_vars['customer'] ) ? $query_vars['customer'] : array( $query_vars['customer'] ); $values = is_array( $query_vars['customer'] ) ? $query_vars['customer'] : array( $query_vars['customer'] );
$customer_query = $this->get_orders_generate_customer_meta_query( $values ); $customer_query = $this->get_orders_generate_customer_meta_query( $values );
if ( is_wp_error( $customer_query ) ) { if ( is_wp_error( $customer_query ) ) {
$wp_query_args['errors'][] = $customer_query; $wp_query_args['errors'][] = $customer_query;
@ -675,7 +709,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
* *
* @since 3.1.0 * @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 * @return array|object
*/ */
@ -684,8 +718,8 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
if ( ! empty( $args['errors'] ) ) { if ( ! empty( $args['errors'] ) ) {
$query = (object) array( $query = (object) array(
'posts' => array(), 'posts' => array(),
'found_posts' => 0, 'found_posts' => 0,
'max_num_pages' => 0, 'max_num_pages' => 0,
); );
} else { } else {

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. * For all stored terms in all taxonomies, save them to the DB.
* *
* @param WC_Product * @param WC_Product $product Product object.
* @param bool Force update. Used during create. * @param bool $force Force update. Used during create.
* @since 3.0.0 * @since 3.0.0
*/ */
protected function update_terms( &$product, $force = false ) { protected function update_terms( &$product, $force = false ) {
$changes = $product->get_changes(); $changes = $product->get_changes();
if ( $force || array_key_exists( 'category_ids', $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 ) ) { if ( $force || array_key_exists( 'tag_ids', $changes ) ) {
wp_set_post_terms( $product->get_id(), $product->get_tag_ids( 'edit' ), 'product_tag', false ); wp_set_post_terms( $product->get_id(), $product->get_tag_ids( 'edit' ), 'product_tag', false );

View File

@ -133,7 +133,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
public function get_params() { public function get_params() {
return $this->params; return $this->params;
} }
/** /**
* Get file pointer position from the last read. * Get file pointer position from the last read.
* *
@ -503,7 +503,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
* @param int $product_id Product ID. * @param int $product_id Product ID.
* @return int * @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 ) ) { if ( empty( $url ) ) {
return 0; return 0;
} }
@ -590,7 +590,7 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
* @param string $name Attribute name. * @param string $name Attribute name.
* @return int * @return int
*/ */
protected function get_attribute_taxonomy_id( $raw_name ) { public function get_attribute_taxonomy_id( $raw_name ) {
global $wpdb, $wc_product_attributes; global $wpdb, $wc_product_attributes;
// These are exported as labels, so convert the label to a name if possible first. // 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() { public function includes() {
// API server / response handlers. // 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-exception.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-server.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/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-json-handler.php' );
// Authentication. // 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(); $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-resource.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-coupons.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-customers.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-orders.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-products.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-reports.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-taxes.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-webhooks.php' ); include_once( dirname( __FILE__ ) . '/../api/legacy/v3/class-wc-api-webhooks.php' );
// Allow plugins to load other response handlers or resource classes. // Allow plugins to load other response handlers or resource classes.
do_action( 'woocommerce_api_loaded' ); do_action( 'woocommerce_api_loaded' );
@ -186,20 +186,20 @@ class WC_Legacy_API {
private function handle_v1_rest_api_request() { private function handle_v1_rest_api_request() {
// Include legacy required files for 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/class-wc-api-server.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v1/interface-wc-api-handler.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-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-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(); $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-resource.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-coupons.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-customers.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-orders.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-products.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-reports.php' ); include_once( dirname( __FILE__ ) . '/../api/legacy/v1/class-wc-api-reports.php' );
// Allow plugins to load other response handlers or resource classes. // Allow plugins to load other response handlers or resource classes.
do_action( 'woocommerce_api_loaded' ); do_action( 'woocommerce_api_loaded' );
@ -232,21 +232,21 @@ class WC_Legacy_API {
* @deprecated 2.6.0 * @deprecated 2.6.0
*/ */
private function handle_v2_rest_api_request() { 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-exception.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-server.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/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-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(); $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-resource.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-coupons.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-customers.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-orders.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-products.php' );
include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-reports.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-webhooks.php' );
// allow plugins to load other response handlers or resource classes. // allow plugins to load other response handlers or resource classes.
do_action( 'woocommerce_api_loaded' ); do_action( 'woocommerce_api_loaded' );

View File

@ -211,7 +211,7 @@ class WC_Shortcode_Products {
*/ */
protected function set_skus_query_args( &$query_args ) { protected function set_skus_query_args( &$query_args ) {
if ( ! empty( $this->attributes['skus'] ) ) { if ( ! empty( $this->attributes['skus'] ) ) {
$skus = array_map( 'trim', explode( ',', $this->attributes['skus'] ) ); $skus = array_map( 'trim', explode( ',', $this->attributes['skus'] ) );
$query_args['meta_query'][] = array( $query_args['meta_query'][] = array(
'key' => '_sku', 'key' => '_sku',
'value' => 1 === count( $skus ) ? $skus[0] : $skus, 'value' => 1 === count( $skus ) ? $skus[0] : $skus,
@ -263,12 +263,10 @@ class WC_Shortcode_Products {
*/ */
protected function set_categories_query_args( &$query_args ) { protected function set_categories_query_args( &$query_args ) {
if ( ! empty( $this->attributes['category'] ) ) { if ( ! empty( $this->attributes['category'] ) ) {
$ordering_args = WC()->query->get_catalog_ordering_args( $query_args['orderby'], $query_args['order'] ); $ordering_args = WC()->query->get_catalog_ordering_args( $query_args['orderby'], $query_args['order'] );
$query_args['orderby'] = $ordering_args['orderby']; $query_args['orderby'] = $ordering_args['orderby'];
$query_args['order'] = $ordering_args['order']; $query_args['order'] = $ordering_args['order'];
// @codingStandardsIgnoreStart $query_args['meta_key'] = $ordering_args['meta_key']; // @codingStandardsIgnoreLine
$query_args['meta_key'] = $ordering_args['meta_key'];
// @codingStandardsIgnoreEnd
$query_args['tax_query'][] = array( $query_args['tax_query'][] = array(
'taxonomy' => 'product_cat', 'taxonomy' => 'product_cat',
@ -296,9 +294,7 @@ class WC_Shortcode_Products {
* @param array $query_args Query args. * @param array $query_args Query args.
*/ */
protected function set_best_selling_products_query_args( &$query_args ) { protected function set_best_selling_products_query_args( &$query_args ) {
// @codingStandardsIgnoreStart $query_args['meta_key'] = 'total_sales'; // @codingStandardsIgnoreLine
$query_args['meta_key'] = 'total_sales';
// @codingStandardsIgnoreEnd
$query_args['order'] = 'DESC'; $query_args['order'] = 'DESC';
$query_args['orderby'] = 'meta_value_num'; $query_args['orderby'] = 'meta_value_num';
} }
@ -310,7 +306,7 @@ class WC_Shortcode_Products {
* @param array $query_args Query args. * @param array $query_args Query args.
*/ */
protected function set_visibility_hidden_query_args( &$query_args ) { protected function set_visibility_hidden_query_args( &$query_args ) {
$this->custom_visibility = true; $this->custom_visibility = true;
$query_args['tax_query'][] = array( $query_args['tax_query'][] = array(
'taxonomy' => 'product_visibility', 'taxonomy' => 'product_visibility',
'terms' => array( 'exclude-from-catalog', 'exclude-from-search' ), 'terms' => array( 'exclude-from-catalog', 'exclude-from-search' ),
@ -327,7 +323,7 @@ class WC_Shortcode_Products {
* @param array $query_args Query args. * @param array $query_args Query args.
*/ */
protected function set_visibility_catalog_query_args( &$query_args ) { protected function set_visibility_catalog_query_args( &$query_args ) {
$this->custom_visibility = true; $this->custom_visibility = true;
$query_args['tax_query'][] = array( $query_args['tax_query'][] = array(
'taxonomy' => 'product_visibility', 'taxonomy' => 'product_visibility',
'terms' => 'exclude-from-search', 'terms' => 'exclude-from-search',
@ -351,7 +347,7 @@ class WC_Shortcode_Products {
* @param array $query_args Query args. * @param array $query_args Query args.
*/ */
protected function set_visibility_search_query_args( &$query_args ) { protected function set_visibility_search_query_args( &$query_args ) {
$this->custom_visibility = true; $this->custom_visibility = true;
$query_args['tax_query'][] = array( $query_args['tax_query'][] = array(
'taxonomy' => 'product_visibility', 'taxonomy' => 'product_visibility',
'terms' => 'exclude-from-catalog', 'terms' => 'exclude-from-catalog',
@ -515,9 +511,8 @@ class WC_Shortcode_Products {
woocommerce_product_loop_start(); woocommerce_product_loop_start();
foreach ( $products_ids as $product_id ) { foreach ( $products_ids as $product_id ) {
$post_object = get_post( $product_id ); $GLOBALS['post'] = get_post( $product_id ); // WPCS: override ok.
$GLOBALS['post'] =& $post_object; // WPCS: override ok. setup_postdata( $GLOBALS['post'] );
setup_postdata( $post_object );
// Set custom product visibility when quering hidden products. // Set custom product visibility when quering hidden products.
add_action( 'woocommerce_product_is_visible', array( $this, 'set_product_as_visible' ) ); add_action( 'woocommerce_product_is_visible', array( $this, 'set_product_as_visible' ) );
@ -554,8 +549,8 @@ class WC_Shortcode_Products {
public static function order_by_rating_post_clauses( $args ) { public static function order_by_rating_post_clauses( $args ) {
global $wpdb; global $wpdb;
$args['where'] .= " AND $wpdb->commentmeta.meta_key = 'rating' "; $args['where'] .= " AND $wpdb->commentmeta.meta_key = 'rating' ";
$args['join'] .= "LEFT JOIN $wpdb->comments ON($wpdb->posts.ID = $wpdb->comments.comment_post_ID) LEFT JOIN $wpdb->commentmeta ON($wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id)"; $args['join'] .= "LEFT JOIN $wpdb->comments ON($wpdb->posts.ID = $wpdb->comments.comment_post_ID) LEFT JOIN $wpdb->commentmeta ON($wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id)";
$args['orderby'] = "$wpdb->commentmeta.meta_value DESC"; $args['orderby'] = "$wpdb->commentmeta.meta_value DESC";
$args['groupby'] = "$wpdb->posts.ID"; $args['groupby'] = "$wpdb->posts.ID";

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

@ -1507,11 +1507,13 @@ function wc_get_rounding_precision() {
* *
* @since 3.2.0 * @since 3.2.0
* @param float $value Number to add precision to. * @param float $value Number to add precision to.
* @return int * @param bool $round Should we round after adding precision?
* @return int|float
*/ */
function wc_add_number_precision( $value ) { function wc_add_number_precision( $value, $round = true ) {
$precision = pow( 10, wc_get_price_decimals() ); $precision = pow( 10, wc_get_price_decimals() );
return intval( round( $value * $precision ) ); $value = $value * $precision;
return $round ? intval( round( $value ) ) : $value;
} }
/** /**
@ -1531,15 +1533,16 @@ function wc_remove_number_precision( $value ) {
* *
* @since 3.2.0 * @since 3.2.0
* @param array $value Number to add precision to. * @param array $value Number to add precision to.
* @param bool $round Should we round after adding precision?
* @return int * @return int
*/ */
function wc_add_number_precision_deep( $value ) { function wc_add_number_precision_deep( $value, $round = true ) {
if ( is_array( $value ) ) { if ( is_array( $value ) ) {
foreach ( $value as $key => $subvalue ) { foreach ( $value as $key => $subvalue ) {
$value[ $key ] = wc_add_number_precision_deep( $subvalue ); $value[ $key ] = wc_add_number_precision_deep( $subvalue, $round );
} }
} else { } else {
$value = wc_add_number_precision( $value ); $value = wc_add_number_precision( $value, $round );
} }
return $value; return $value;
} }

View File

@ -4,10 +4,10 @@
* *
* Where functions come to die. * Where functions come to die.
* *
* @author WooThemes * @author Automattic
* @category Core * @category Core
* @package WooCommerce/Functions * @package WooCommerce\Functions
* @version 2.1.0 * @version 3.3.0
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
@ -17,17 +17,20 @@ if ( ! defined( 'ABSPATH' ) ) {
/** /**
* Runs a deprecated action with notice only if used. * Runs a deprecated action with notice only if used.
* *
* @since 3.0.0 * @since 3.0.0
* @param string $action * @param string $tag The name of the action hook.
* @param array $args * @param array $args Array of additional function arguments to be passed to do_action().
* @param string $deprecated_in * @param string $version The version of WooCommerce that deprecated the hook.
* @param string $replacement * @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 ) { function wc_do_deprecated_action( $tag, $args, $version, $replacement = null, $message = null ) {
if ( has_action( $action ) ) { if ( ! has_action( $tag ) ) {
wc_deprecated_function( 'Action: ' . $action, $deprecated_in, $replacement ); return;
do_action_ref_array( $action, $args );
} }
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 // @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. * 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() ); do_action( 'woocommerce_order_refunded', $order->get_id(), $refund->get_id() );
} catch ( Exception $e ) { } 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() ); return new WP_Error( 'error', $e->getMessage() );
} }

View File

@ -4,30 +4,29 @@
* *
* Functions related to pages and menus. * Functions related to pages and menus.
* *
* @author WooThemes * @author Automattic
* @category Core * @category Core
* @package WooCommerce/Functions * @package WooCommerce\Functions
* @version 2.6.0 * @version 2.6.0
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly exit; // Exit if accessed directly.
} }
/** /**
* Replace a page title with the endpoint title. * Replace a page title with the endpoint title.
* @param string $title *
* @param string $title Post title.
* @return string * @return string
*/ */
function wc_page_endpoint_title( $title ) { function wc_page_endpoint_title( $title ) {
global $wp_query; global $wp_query;
if ( ! is_null( $wp_query ) && ! is_admin() && is_main_query() && in_the_loop() && is_page() && is_wc_endpoint_url() ) { if ( ! is_null( $wp_query ) && ! is_admin() && is_main_query() && in_the_loop() && is_page() && is_wc_endpoint_url() ) {
$endpoint = WC()->query->get_current_endpoint(); $endpoint = WC()->query->get_current_endpoint();
$endpoint_title = WC()->query->get_endpoint_title( $endpoint );
if ( $endpoint_title = WC()->query->get_endpoint_title( $endpoint ) ) { $title = $endpoint_title ? $endpoint_title : $title;
$title = $endpoint_title;
}
remove_filter( 'the_title', 'wc_page_endpoint_title' ); remove_filter( 'the_title', 'wc_page_endpoint_title' );
} }
@ -40,12 +39,11 @@ add_filter( 'the_title', 'wc_page_endpoint_title' );
/** /**
* Retrieve page ids - used for myaccount, edit_address, shop, cart, checkout, pay, view_order, terms. returns -1 if no page is found. * Retrieve page ids - used for myaccount, edit_address, shop, cart, checkout, pay, view_order, terms. returns -1 if no page is found.
* *
* @param string $page * @param string $page Page slug.
* @return int * @return int
*/ */
function wc_get_page_id( $page ) { function wc_get_page_id( $page ) {
if ( 'pay' === $page || 'thanks' === $page ) {
if ( 'pay' == $page || 'thanks' == $page ) {
wc_deprecated_argument( __FUNCTION__, '2.1', 'The "pay" and "thanks" pages are no-longer used - an endpoint is added to the checkout instead. To get a valid link use the WC_Order::get_checkout_payment_url() or WC_Order::get_checkout_order_received_url() methods instead.' ); wc_deprecated_argument( __FUNCTION__, '2.1', 'The "pay" and "thanks" pages are no-longer used - an endpoint is added to the checkout instead. To get a valid link use the WC_Order::get_checkout_payment_url() or WC_Order::get_checkout_order_received_url() methods instead.' );
$page = 'checkout'; $page = 'checkout';
@ -64,7 +62,7 @@ function wc_get_page_id( $page ) {
/** /**
* Retrieve page permalink. * Retrieve page permalink.
* *
* @param string $page * @param string $page page slug.
* @return string * @return string
*/ */
function wc_get_page_permalink( $page ) { function wc_get_page_permalink( $page ) {
@ -78,9 +76,9 @@ function wc_get_page_permalink( $page ) {
* *
* Gets the URL for an endpoint, which varies depending on permalink settings. * Gets the URL for an endpoint, which varies depending on permalink settings.
* *
* @param string $endpoint * @param string $endpoint Endpoint slug.
* @param string $value * @param string $value Query param value.
* @param string $permalink * @param string $permalink Permalink.
* *
* @return string * @return string
*/ */
@ -89,13 +87,14 @@ function wc_get_endpoint_url( $endpoint, $value = '', $permalink = '' ) {
$permalink = get_permalink(); $permalink = get_permalink();
} }
// Map endpoint to options // Map endpoint to options.
$endpoint = ! empty( WC()->query->query_vars[ $endpoint ] ) ? WC()->query->query_vars[ $endpoint ] : $endpoint; $query_vars = WC()->query->get_query_vars();
$value = ( get_option( 'woocommerce_myaccount_edit_address_endpoint', 'edit-address' ) === $endpoint ) ? wc_edit_address_i18n( $value ) : $value; $endpoint = ! empty( $query_vars[ $endpoint ] ) ? $query_vars[ $endpoint ] : $endpoint;
$value = ( get_option( 'woocommerce_myaccount_edit_address_endpoint', 'edit-address' ) === $endpoint ) ? wc_edit_address_i18n( $value ) : $value;
if ( get_option( 'permalink_structure' ) ) { if ( get_option( 'permalink_structure' ) ) {
if ( strstr( $permalink, '?' ) ) { if ( strstr( $permalink, '?' ) ) {
$query_string = '?' . parse_url( $permalink, PHP_URL_QUERY ); $query_string = '?' . wp_parse_url( $permalink, PHP_URL_QUERY );
$permalink = current( explode( '?', $permalink ) ); $permalink = current( explode( '?', $permalink ) );
} else { } else {
$query_string = ''; $query_string = '';
@ -123,8 +122,8 @@ function wc_nav_menu_items( $items ) {
if ( empty( $item->url ) ) { if ( empty( $item->url ) ) {
continue; continue;
} }
$path = parse_url( $item->url, PHP_URL_PATH ); $path = wp_parse_url( $item->url, PHP_URL_PATH );
$query = parse_url( $item->url, PHP_URL_QUERY ); $query = wp_parse_url( $item->url, PHP_URL_QUERY );
if ( strstr( $path, $customer_logout ) || strstr( $query, $customer_logout ) ) { if ( strstr( $path, $customer_logout ) || strstr( $query, $customer_logout ) ) {
unset( $items[ $key ] ); unset( $items[ $key ] );
@ -141,43 +140,41 @@ add_filter( 'wp_nav_menu_objects', 'wc_nav_menu_items', 10 );
/** /**
* Fix active class in nav for shop page. * Fix active class in nav for shop page.
* *
* @param array $menu_items * @param array $menu_items Menu items.
* @return array * @return array
*/ */
function wc_nav_menu_item_classes( $menu_items ) { function wc_nav_menu_item_classes( $menu_items ) {
if ( ! is_woocommerce() ) { if ( ! is_woocommerce() ) {
return $menu_items; return $menu_items;
} }
$shop_page = (int) wc_get_page_id( 'shop' ); $shop_page = (int) wc_get_page_id( 'shop' );
$page_for_posts = (int) get_option( 'page_for_posts' ); $page_for_posts = (int) get_option( 'page_for_posts' );
if ( ! empty( $menu_items ) && is_array( $menu_items ) ) { if ( ! empty( $menu_items ) && is_array( $menu_items ) ) {
foreach ( $menu_items as $key => $menu_item ) { foreach ( $menu_items as $key => $menu_item ) {
$classes = (array) $menu_item->classes; $classes = (array) $menu_item->classes;
$menu_id = (int) $menu_item->object_id;
// Unset active class for blog page // Unset active class for blog page.
if ( $page_for_posts == $menu_item->object_id ) { if ( $page_for_posts === $menu_id ) {
$menu_items[ $key ]->current = false; $menu_items[ $key ]->current = false;
if ( in_array( 'current_page_parent', $classes ) ) { if ( in_array( 'current_page_parent', $classes, true ) ) {
unset( $classes[ array_search( 'current_page_parent', $classes ) ] ); unset( $classes[ array_search( 'current_page_parent', $classes, true ) ] );
} }
if ( in_array( 'current-menu-item', $classes ) ) { if ( in_array( 'current-menu-item', $classes, true ) ) {
unset( $classes[ array_search( 'current-menu-item', $classes ) ] ); unset( $classes[ array_search( 'current-menu-item', $classes, true ) ] );
} }
} elseif ( is_shop() && $shop_page === $menu_id && 'page' === $menu_item->object ) {
// Set active state if this is the shop page link // Set active state if this is the shop page link.
} elseif ( is_shop() && $shop_page == $menu_item->object_id && 'page' === $menu_item->object ) {
$menu_items[ $key ]->current = true; $menu_items[ $key ]->current = true;
$classes[] = 'current-menu-item'; $classes[] = 'current-menu-item';
$classes[] = 'current_page_item'; $classes[] = 'current_page_item';
// Set parent state if this is a product page } elseif ( is_singular( 'product' ) && $shop_page === $menu_id ) {
} elseif ( is_singular( 'product' ) && $shop_page == $menu_item->object_id ) { // Set parent state if this is a product page.
$classes[] = 'current_page_parent'; $classes[] = 'current_page_parent';
} }
@ -193,10 +190,9 @@ add_filter( 'wp_nav_menu_objects', 'wc_nav_menu_item_classes', 2 );
/** /**
* Fix active class in wp_list_pages for shop page. * Fix active class in wp_list_pages for shop page.
* *
* https://github.com/woocommerce/woocommerce/issues/177. * See details in https://github.com/woocommerce/woocommerce/issues/177.
* *
* @author Jessor, Peter Sterling * @param string $pages Pages list.
* @param string $pages
* @return string * @return string
*/ */
function wc_list_pages( $pages ) { function wc_list_pages( $pages ) {

View File

@ -4,9 +4,9 @@
* *
* Functions for the templating system. * Functions for the templating system.
* *
* @author WooThemes * @author Automattic
* @category Core * @category Core
* @package WooCommerce/Functions * @package WooCommerce\Functions
* @version 2.5.0 * @version 2.5.0
*/ */
@ -20,7 +20,7 @@ if ( ! defined( 'ABSPATH' ) ) {
function wc_template_redirect() { function wc_template_redirect() {
global $wp_query, $wp; global $wp_query, $wp;
if ( ! empty( $_GET['page_id'] ) && '' === get_option( 'permalink_structure' ) && wc_get_page_id( 'shop' ) == $_GET['page_id'] ) { if ( ! empty( $_GET['page_id'] ) && '' === get_option( 'permalink_structure' ) && wc_get_page_id( 'shop' ) === absint( $_GET['page_id'] ) ) { // WPCS: input var ok, CSRF ok.
// When default permalinks are enabled, redirect shop page to post type archive url. // When default permalinks are enabled, redirect shop page to post type archive url.
wp_safe_redirect( get_post_type_archive_link( 'product' ) ); wp_safe_redirect( get_post_type_archive_link( 'product' ) );
@ -33,11 +33,7 @@ function wc_template_redirect() {
wp_redirect( wc_get_page_permalink( 'cart' ) ); wp_redirect( wc_get_page_permalink( 'cart' ) );
exit; exit;
} elseif ( } elseif ( isset( $wp->query_vars['customer-logout'] ) && ! empty( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'customer-logout' ) ) { // WPCS: input var ok, CSRF ok.
isset( $wp->query_vars['customer-logout'] ) &&
! empty( $_REQUEST['_wpnonce'] ) &&
wp_verify_nonce( sanitize_key( $_REQUEST['_wpnonce'] ), 'customer-logout' )
) {
// Logout. // Logout.
wp_redirect( str_replace( '&amp;', '&', wp_logout_url( wc_get_page_permalink( 'myaccount' ) ) ) ); wp_redirect( str_replace( '&amp;', '&', wp_logout_url( wc_get_page_permalink( 'myaccount' ) ) ) );
@ -97,8 +93,8 @@ add_action( 'template_redirect', 'wc_send_frame_options_header' );
* @since 2.5.3 * @since 2.5.3
*/ */
function wc_prevent_endpoint_indexing() { function wc_prevent_endpoint_indexing() {
if ( is_wc_endpoint_url() || isset( $_GET['download_file'] ) ) { if ( is_wc_endpoint_url() || isset( $_GET['download_file'] ) ) { // WPCS: input var ok, CSRF ok.
@header( 'X-Robots-Tag: noindex' ); @header( 'X-Robots-Tag: noindex' ); // @codingStandardsIgnoreLine
} }
} }
add_action( 'template_redirect', 'wc_prevent_endpoint_indexing' ); add_action( 'template_redirect', 'wc_prevent_endpoint_indexing' );
@ -142,7 +138,7 @@ function wc_setup_product_data( $post ) {
$the_post = $post; $the_post = $post;
} }
if ( empty( $the_post->post_type ) || ! in_array( $the_post->post_type, array( 'product', 'product_variation' ) ) ) { if ( empty( $the_post->post_type ) || ! in_array( $the_post->post_type, array( 'product', 'product_variation' ), true ) ) {
return; return;
} }
@ -156,8 +152,6 @@ if ( ! function_exists( 'woocommerce_reset_loop' ) ) {
/** /**
* Reset the loop's index and columns when we're done outputting a product loop. * Reset the loop's index and columns when we're done outputting a product loop.
*
* @subpackage Loop
*/ */
function woocommerce_reset_loop() { function woocommerce_reset_loop() {
$GLOBALS['woocommerce_loop'] = array( $GLOBALS['woocommerce_loop'] = array(
@ -189,6 +183,7 @@ function wc_products_rss_feed() {
if ( $term ) { if ( $term ) {
$feed = add_query_arg( 'product_cat', $term->slug, get_post_type_archive_feed_link( 'product' ) ); $feed = add_query_arg( 'product_cat', $term->slug, get_post_type_archive_feed_link( 'product' ) );
/* translators: %s: category name */
echo '<link rel="alternate" type="application/rss+xml" title="' . esc_attr( sprintf( __( 'New products added to %s', 'woocommerce' ), $term->name ) ) . '" href="' . esc_url( $feed ) . '" />'; echo '<link rel="alternate" type="application/rss+xml" title="' . esc_attr( sprintf( __( 'New products added to %s', 'woocommerce' ), $term->name ) ) . '" href="' . esc_url( $feed ) . '" />';
} }
} elseif ( is_tax( 'product_tag' ) ) { } elseif ( is_tax( 'product_tag' ) ) {
@ -197,7 +192,8 @@ function wc_products_rss_feed() {
if ( $term ) { if ( $term ) {
$feed = add_query_arg( 'product_tag', $term->slug, get_post_type_archive_feed_link( 'product' ) ); $feed = add_query_arg( 'product_tag', $term->slug, get_post_type_archive_feed_link( 'product' ) );
echo '<link rel="alternate" type="application/rss+xml" title="' . sprintf( esc_attr__( 'New products tagged %s', 'woocommerce' ), urlencode( $term->name ) ) . '" href="' . esc_url( $feed ) . '" />'; /* translators: %s: tag name */
echo '<link rel="alternate" type="application/rss+xml" title="' . sprintf( esc_attr__( 'New products tagged %s', 'woocommerce' ), rawurlencode( $term->name ) ) . '" href="' . esc_url( $feed ) . '" />';
} }
} }
} }
@ -259,7 +255,7 @@ function wc_body_class( $classes ) {
$classes[] = 'woocommerce-demo-store'; $classes[] = 'woocommerce-demo-store';
} }
foreach ( WC()->query->query_vars as $key => $value ) { foreach ( WC()->query->get_query_vars() as $key => $value ) {
if ( is_wc_endpoint_url( $key ) ) { if ( is_wc_endpoint_url( $key ) ) {
$classes[] = 'woocommerce-' . sanitize_html_class( $key ); $classes[] = 'woocommerce-' . sanitize_html_class( $key );
} }
@ -289,7 +285,7 @@ function wc_product_cat_class( $class = '', $category = null ) {
function wc_get_loop_class() { function wc_get_loop_class() {
global $woocommerce_loop; global $woocommerce_loop;
$woocommerce_loop['loop'] = ! empty( $woocommerce_loop['loop'] ) ? $woocommerce_loop['loop'] + 1 : 1; $woocommerce_loop['loop'] = ! empty( $woocommerce_loop['loop'] ) ? $woocommerce_loop['loop'] + 1 : 1;
$woocommerce_loop['columns'] = max( 1, ! empty( $woocommerce_loop['columns'] ) ? $woocommerce_loop['columns'] : apply_filters( 'loop_shop_columns', 4 ) ); $woocommerce_loop['columns'] = max( 1, ! empty( $woocommerce_loop['columns'] ) ? $woocommerce_loop['columns'] : apply_filters( 'loop_shop_columns', 4 ) );
if ( 0 === ( $woocommerce_loop['loop'] - 1 ) % $woocommerce_loop['columns'] || 1 === $woocommerce_loop['columns'] ) { if ( 0 === ( $woocommerce_loop['loop'] - 1 ) % $woocommerce_loop['columns'] || 1 === $woocommerce_loop['columns'] ) {
@ -331,7 +327,7 @@ function wc_get_product_cat_class( $class = '', $category = null ) {
* @return array * @return array
*/ */
function wc_product_post_class( $classes, $class = '', $post_id = '' ) { function wc_product_post_class( $classes, $class = '', $post_id = '' ) {
if ( ! $post_id || ! in_array( get_post_type( $post_id ), array( 'product', 'product_variation' ) ) ) { if ( ! $post_id || ! in_array( get_post_type( $post_id ), array( 'product', 'product_variation' ), true ) ) {
return $classes; return $classes;
} }
@ -379,7 +375,8 @@ function wc_product_post_class( $classes, $class = '', $post_id = '' ) {
} }
} }
if ( false !== ( $key = array_search( 'hentry', $classes ) ) ) { $key = array_search( 'hentry', $classes, true );
if ( false !== $key ) {
unset( $classes[ $key ] ); unset( $classes[ $key ] );
} }
@ -398,7 +395,7 @@ function wc_product_post_class( $classes, $class = '', $post_id = '' ) {
*/ */
function wc_query_string_form_fields( $values = null, $exclude = array(), $current_key = '', $return = false ) { function wc_query_string_form_fields( $values = null, $exclude = array(), $current_key = '', $return = false ) {
if ( is_null( $values ) ) { if ( is_null( $values ) ) {
$values = $_GET; $values = $_GET; // WPCS: input var ok, CSRF ok.
} }
$html = ''; $html = '';
@ -440,13 +437,13 @@ if ( ! function_exists( 'woocommerce_content' ) ) {
if ( is_singular( 'product' ) ) { if ( is_singular( 'product' ) ) {
while ( have_posts() ) : the_post(); while ( have_posts() ) :
the_post();
wc_get_template_part( 'content', 'single-product' ); wc_get_template_part( 'content', 'single-product' );
endwhile; endwhile;
} else { ?> } else {
?>
<?php if ( apply_filters( 'woocommerce_show_page_title', true ) ) : ?> <?php if ( apply_filters( 'woocommerce_show_page_title', true ) ) : ?>
@ -464,7 +461,8 @@ if ( ! function_exists( 'woocommerce_content' ) ) {
<?php woocommerce_product_subcategories(); ?> <?php woocommerce_product_subcategories(); ?>
<?php while ( have_posts() ) : the_post(); ?> <?php while ( have_posts() ) : ?>
<?php the_post(); ?>
<?php wc_get_template_part( 'content', 'product' ); ?> <?php wc_get_template_part( 'content', 'product' ); ?>
@ -474,12 +472,17 @@ if ( ! function_exists( 'woocommerce_content' ) ) {
<?php do_action( 'woocommerce_after_shop_loop' ); ?> <?php do_action( 'woocommerce_after_shop_loop' ); ?>
<?php elseif ( ! woocommerce_product_subcategories( array( 'before' => woocommerce_product_loop_start( false ), 'after' => woocommerce_product_loop_end( false ) ) ) ) : ?> <?php
elseif ( ! woocommerce_product_subcategories( array(
'before' => woocommerce_product_loop_start( false ),
'after' => woocommerce_product_loop_end( false ),
) ) ) :
?>
<?php do_action( 'woocommerce_no_products_found' ); ?> <?php do_action( 'woocommerce_no_products_found' ); ?>
<?php endif; <?php
endif;
} }
} }
} }
@ -552,9 +555,11 @@ if ( ! function_exists( 'woocommerce_page_title' ) ) {
function woocommerce_page_title( $echo = true ) { function woocommerce_page_title( $echo = true ) {
if ( is_search() ) { if ( is_search() ) {
/* translators: %s: search query */
$page_title = sprintf( __( 'Search results: &ldquo;%s&rdquo;', 'woocommerce' ), get_search_query() ); $page_title = sprintf( __( 'Search results: &ldquo;%s&rdquo;', 'woocommerce' ), get_search_query() );
if ( get_query_var( 'paged' ) ) { if ( get_query_var( 'paged' ) ) {
/* translators: %s: page number */
$page_title .= sprintf( __( '&nbsp;&ndash; Page %s', 'woocommerce' ), get_query_var( 'paged' ) ); $page_title .= sprintf( __( '&nbsp;&ndash; Page %s', 'woocommerce' ), get_query_var( 'paged' ) );
} }
} elseif ( is_tax() ) { } elseif ( is_tax() ) {
@ -679,8 +684,6 @@ if ( ! function_exists( 'woocommerce_taxonomy_archive_description' ) ) {
/** /**
* Show an archive description on taxonomy archives. * Show an archive description on taxonomy archives.
*
* @subpackage Archives
*/ */
function woocommerce_taxonomy_archive_description() { function woocommerce_taxonomy_archive_description() {
if ( is_product_taxonomy() && 0 === absint( get_query_var( 'paged' ) ) ) { if ( is_product_taxonomy() && 0 === absint( get_query_var( 'paged' ) ) ) {
@ -720,8 +723,6 @@ if ( ! function_exists( 'woocommerce_template_loop_add_to_cart' ) ) {
/** /**
* Get the add to cart template for the loop. * Get the add to cart template for the loop.
* *
* @subpackage Loop
*
* @param array $args Arguments. * @param array $args Arguments.
*/ */
function woocommerce_template_loop_add_to_cart( $args = array() ) { function woocommerce_template_loop_add_to_cart( $args = array() ) {
@ -731,10 +732,10 @@ if ( ! function_exists( 'woocommerce_template_loop_add_to_cart' ) ) {
$defaults = array( $defaults = array(
'quantity' => 1, 'quantity' => 1,
'class' => implode( ' ', array_filter( array( 'class' => implode( ' ', array_filter( array(
'button', 'button',
'product_type_' . $product->get_type(), 'product_type_' . $product->get_type(),
$product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '', $product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
$product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '', $product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '',
) ) ), ) ) ),
); );
@ -748,8 +749,6 @@ if ( ! function_exists( 'woocommerce_template_loop_product_thumbnail' ) ) {
/** /**
* Get the product thumbnail for the loop. * Get the product thumbnail for the loop.
*
* @subpackage Loop
*/ */
function woocommerce_template_loop_product_thumbnail() { function woocommerce_template_loop_product_thumbnail() {
echo woocommerce_get_product_thumbnail(); // WPCS: XSS ok. echo woocommerce_get_product_thumbnail(); // WPCS: XSS ok.
@ -759,8 +758,6 @@ if ( ! function_exists( 'woocommerce_template_loop_price' ) ) {
/** /**
* Get the product price for the loop. * Get the product price for the loop.
*
* @subpackage Loop
*/ */
function woocommerce_template_loop_price() { function woocommerce_template_loop_price() {
wc_get_template( 'loop/price.php' ); wc_get_template( 'loop/price.php' );
@ -770,8 +767,6 @@ if ( ! function_exists( 'woocommerce_template_loop_rating' ) ) {
/** /**
* Display the average rating in the loop. * Display the average rating in the loop.
*
* @subpackage Loop
*/ */
function woocommerce_template_loop_rating() { function woocommerce_template_loop_rating() {
wc_get_template( 'loop/rating.php' ); wc_get_template( 'loop/rating.php' );
@ -781,8 +776,6 @@ if ( ! function_exists( 'woocommerce_show_product_loop_sale_flash' ) ) {
/** /**
* Get the sale flash for the loop. * Get the sale flash for the loop.
*
* @subpackage Loop
*/ */
function woocommerce_show_product_loop_sale_flash() { function woocommerce_show_product_loop_sale_flash() {
wc_get_template( 'loop/sale-flash.php' ); wc_get_template( 'loop/sale-flash.php' );
@ -794,7 +787,6 @@ if ( ! function_exists( 'woocommerce_get_product_thumbnail' ) ) {
/** /**
* Get the product thumbnail, or the placeholder if not set. * Get the product thumbnail, or the placeholder if not set.
* *
* @subpackage Loop
* @param string $size (default: 'woocommerce_thumbnail'). * @param string $size (default: 'woocommerce_thumbnail').
* @param int $deprecated1 Deprecated since WooCommerce 2.0 (default: 0). * @param int $deprecated1 Deprecated since WooCommerce 2.0 (default: 0).
* @param int $deprecated2 Deprecated since WooCommerce 2.0 (default: 0). * @param int $deprecated2 Deprecated since WooCommerce 2.0 (default: 0).
@ -813,8 +805,6 @@ if ( ! function_exists( 'woocommerce_result_count' ) ) {
/** /**
* Output the result count text (Showing x - x of x results). * Output the result count text (Showing x - x of x results).
*
* @subpackage Loop
*/ */
function woocommerce_result_count() { function woocommerce_result_count() {
wc_get_template( 'loop/result-count.php' ); wc_get_template( 'loop/result-count.php' );
@ -825,8 +815,6 @@ if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) {
/** /**
* Output the product sorting options. * Output the product sorting options.
*
* @subpackage Loop
*/ */
function woocommerce_catalog_ordering() { function woocommerce_catalog_ordering() {
global $wp_query; global $wp_query;
@ -835,7 +823,7 @@ if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) {
return; return;
} }
$orderby = isset( $_GET['orderby'] ) ? wc_clean( wp_unslash( $_GET['orderby'] ) ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) ); $orderby = isset( $_GET['orderby'] ) ? wc_clean( wp_unslash( $_GET['orderby'] ) ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) ); // WPCS: input var ok, CSRF ok.
$show_default_orderby = 'menu_order' === apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) ); $show_default_orderby = 'menu_order' === apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
$catalog_orderby_options = apply_filters( 'woocommerce_catalog_orderby', array( $catalog_orderby_options = apply_filters( 'woocommerce_catalog_orderby', array(
'menu_order' => __( 'Default sorting', 'woocommerce' ), 'menu_order' => __( 'Default sorting', 'woocommerce' ),
@ -847,7 +835,9 @@ if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) {
) ); ) );
if ( $wp_query->is_search() ) { if ( $wp_query->is_search() ) {
$catalog_orderby_options = array_merge( array( 'relevance' => __( 'Relevance', 'woocommerce' ) ), $catalog_orderby_options ); $catalog_orderby_options = array_merge( array(
'relevance' => __( 'Relevance', 'woocommerce' ),
), $catalog_orderby_options );
unset( $catalog_orderby_options['menu_order'] ); unset( $catalog_orderby_options['menu_order'] );
if ( 'menu_order' === $orderby ) { if ( 'menu_order' === $orderby ) {
$orderby = 'relevance'; $orderby = 'relevance';
@ -862,7 +852,11 @@ if ( ! function_exists( 'woocommerce_catalog_ordering' ) ) {
unset( $catalog_orderby_options['rating'] ); unset( $catalog_orderby_options['rating'] );
} }
wc_get_template( 'loop/orderby.php', array( 'catalog_orderby_options' => $catalog_orderby_options, 'orderby' => $orderby, 'show_default_orderby' => $show_default_orderby ) ); wc_get_template( 'loop/orderby.php', array(
'catalog_orderby_options' => $catalog_orderby_options,
'orderby' => $orderby,
'show_default_orderby' => $show_default_orderby,
) );
} }
} }
@ -870,8 +864,6 @@ if ( ! function_exists( 'woocommerce_pagination' ) ) {
/** /**
* Output the pagination. * Output the pagination.
*
* @subpackage Loop
*/ */
function woocommerce_pagination() { function woocommerce_pagination() {
wc_get_template( 'loop/pagination.php' ); wc_get_template( 'loop/pagination.php' );
@ -886,8 +878,6 @@ if ( ! function_exists( 'woocommerce_show_product_images' ) ) {
/** /**
* Output the product image before the single product summary. * Output the product image before the single product summary.
*
* @subpackage Product
*/ */
function woocommerce_show_product_images() { function woocommerce_show_product_images() {
wc_get_template( 'single-product/product-image.php' ); wc_get_template( 'single-product/product-image.php' );
@ -897,8 +887,6 @@ if ( ! function_exists( 'woocommerce_show_product_thumbnails' ) ) {
/** /**
* Output the product thumbnails. * Output the product thumbnails.
*
* @subpackage Product
*/ */
function woocommerce_show_product_thumbnails() { function woocommerce_show_product_thumbnails() {
wc_get_template( 'single-product/product-thumbnails.php' ); wc_get_template( 'single-product/product-thumbnails.php' );
@ -909,8 +897,6 @@ if ( ! function_exists( 'woocommerce_output_product_data_tabs' ) ) {
/** /**
* Output the product tabs. * Output the product tabs.
*
* @subpackage Product/Tabs
*/ */
function woocommerce_output_product_data_tabs() { function woocommerce_output_product_data_tabs() {
wc_get_template( 'single-product/tabs/tabs.php' ); wc_get_template( 'single-product/tabs/tabs.php' );
@ -920,8 +906,6 @@ if ( ! function_exists( 'woocommerce_template_single_title' ) ) {
/** /**
* Output the product title. * Output the product title.
*
* @subpackage Product
*/ */
function woocommerce_template_single_title() { function woocommerce_template_single_title() {
wc_get_template( 'single-product/title.php' ); wc_get_template( 'single-product/title.php' );
@ -931,8 +915,6 @@ if ( ! function_exists( 'woocommerce_template_single_rating' ) ) {
/** /**
* Output the product rating. * Output the product rating.
*
* @subpackage Product
*/ */
function woocommerce_template_single_rating() { function woocommerce_template_single_rating() {
if ( post_type_supports( 'product', 'comments' ) ) { if ( post_type_supports( 'product', 'comments' ) ) {
@ -944,8 +926,6 @@ if ( ! function_exists( 'woocommerce_template_single_price' ) ) {
/** /**
* Output the product price. * Output the product price.
*
* @subpackage Product
*/ */
function woocommerce_template_single_price() { function woocommerce_template_single_price() {
wc_get_template( 'single-product/price.php' ); wc_get_template( 'single-product/price.php' );
@ -955,8 +935,6 @@ if ( ! function_exists( 'woocommerce_template_single_excerpt' ) ) {
/** /**
* Output the product short description (excerpt). * Output the product short description (excerpt).
*
* @subpackage Product
*/ */
function woocommerce_template_single_excerpt() { function woocommerce_template_single_excerpt() {
wc_get_template( 'single-product/short-description.php' ); wc_get_template( 'single-product/short-description.php' );
@ -966,8 +944,6 @@ if ( ! function_exists( 'woocommerce_template_single_meta' ) ) {
/** /**
* Output the product meta. * Output the product meta.
*
* @subpackage Product
*/ */
function woocommerce_template_single_meta() { function woocommerce_template_single_meta() {
wc_get_template( 'single-product/meta.php' ); wc_get_template( 'single-product/meta.php' );
@ -977,8 +953,6 @@ if ( ! function_exists( 'woocommerce_template_single_sharing' ) ) {
/** /**
* Output the product sharing. * Output the product sharing.
*
* @subpackage Product
*/ */
function woocommerce_template_single_sharing() { function woocommerce_template_single_sharing() {
wc_get_template( 'single-product/share.php' ); wc_get_template( 'single-product/share.php' );
@ -988,8 +962,6 @@ if ( ! function_exists( 'woocommerce_show_product_sale_flash' ) ) {
/** /**
* Output the product sale flash. * Output the product sale flash.
*
* @subpackage Product
*/ */
function woocommerce_show_product_sale_flash() { function woocommerce_show_product_sale_flash() {
wc_get_template( 'single-product/sale-flash.php' ); wc_get_template( 'single-product/sale-flash.php' );
@ -1000,8 +972,6 @@ if ( ! function_exists( 'woocommerce_template_single_add_to_cart' ) ) {
/** /**
* Trigger the single product add to cart action. * Trigger the single product add to cart action.
*
* @subpackage Product
*/ */
function woocommerce_template_single_add_to_cart() { function woocommerce_template_single_add_to_cart() {
global $product; global $product;
@ -1012,8 +982,6 @@ if ( ! function_exists( 'woocommerce_simple_add_to_cart' ) ) {
/** /**
* Output the simple product add to cart area. * Output the simple product add to cart area.
*
* @subpackage Product
*/ */
function woocommerce_simple_add_to_cart() { function woocommerce_simple_add_to_cart() {
wc_get_template( 'single-product/add-to-cart/simple.php' ); wc_get_template( 'single-product/add-to-cart/simple.php' );
@ -1023,8 +991,6 @@ if ( ! function_exists( 'woocommerce_grouped_add_to_cart' ) ) {
/** /**
* Output the grouped product add to cart area. * Output the grouped product add to cart area.
*
* @subpackage Product
*/ */
function woocommerce_grouped_add_to_cart() { function woocommerce_grouped_add_to_cart() {
global $product; global $product;
@ -1044,8 +1010,6 @@ if ( ! function_exists( 'woocommerce_variable_add_to_cart' ) ) {
/** /**
* Output the variable product add to cart area. * Output the variable product add to cart area.
*
* @subpackage Product
*/ */
function woocommerce_variable_add_to_cart() { function woocommerce_variable_add_to_cart() {
global $product; global $product;
@ -1068,8 +1032,6 @@ if ( ! function_exists( 'woocommerce_external_add_to_cart' ) ) {
/** /**
* Output the external product add to cart area. * Output the external product add to cart area.
*
* @subpackage Product
*/ */
function woocommerce_external_add_to_cart() { function woocommerce_external_add_to_cart() {
global $product; global $product;
@ -1139,8 +1101,6 @@ if ( ! function_exists( 'woocommerce_product_description_tab' ) ) {
/** /**
* Output the description tab content. * Output the description tab content.
*
* @subpackage Product/Tabs
*/ */
function woocommerce_product_description_tab() { function woocommerce_product_description_tab() {
wc_get_template( 'single-product/tabs/description.php' ); wc_get_template( 'single-product/tabs/description.php' );
@ -1150,8 +1110,6 @@ if ( ! function_exists( 'woocommerce_product_additional_information_tab' ) ) {
/** /**
* Output the attributes tab content. * Output the attributes tab content.
*
* @subpackage Product/Tabs
*/ */
function woocommerce_product_additional_information_tab() { function woocommerce_product_additional_information_tab() {
wc_get_template( 'single-product/tabs/additional-information.php' ); wc_get_template( 'single-product/tabs/additional-information.php' );
@ -1162,8 +1120,7 @@ if ( ! function_exists( 'woocommerce_product_reviews_tab' ) ) {
/** /**
* Output the reviews tab content. * Output the reviews tab content.
* *
* @deprecated 2.4.0 Unused * @deprecated 2.4.0 Unused.
* @subpackage Product/Tabs
*/ */
function woocommerce_product_reviews_tab() { function woocommerce_product_reviews_tab() {
wc_deprecated_function( 'woocommerce_product_reviews_tab', '2.4' ); wc_deprecated_function( 'woocommerce_product_reviews_tab', '2.4' );
@ -1202,6 +1159,7 @@ if ( ! function_exists( 'woocommerce_default_product_tabs' ) ) {
// Reviews tab - shows comments. // Reviews tab - shows comments.
if ( comments_open() ) { if ( comments_open() ) {
$tabs['reviews'] = array( $tabs['reviews'] = array(
/* translators: %s: reviews count */
'title' => sprintf( __( 'Reviews (%d)', 'woocommerce' ), $product->get_review_count() ), 'title' => sprintf( __( 'Reviews (%d)', 'woocommerce' ), $product->get_review_count() ),
'priority' => 30, 'priority' => 30,
'callback' => 'comments_template', 'callback' => 'comments_template',
@ -1224,7 +1182,7 @@ if ( ! function_exists( 'woocommerce_sort_product_tabs' ) ) {
// Make sure the $tabs parameter is an array. // Make sure the $tabs parameter is an array.
if ( ! is_array( $tabs ) ) { if ( ! is_array( $tabs ) ) {
trigger_error( 'Function woocommerce_sort_product_tabs() expects an array as the first parameter. Defaulting to empty array.' ); trigger_error( 'Function woocommerce_sort_product_tabs() expects an array as the first parameter. Defaulting to empty array.' ); // @codingStandardsIgnoreLine
$tabs = array(); $tabs = array();
} }
@ -1256,14 +1214,17 @@ if ( ! function_exists( 'woocommerce_comments' ) ) {
/** /**
* Output the Review comments template. * Output the Review comments template.
* *
* @subpackage Product
* @param WP_Comment $comment Comment object. * @param WP_Comment $comment Comment object.
* @param array $args Arguments. * @param array $args Arguments.
* @param int $depth Depth. * @param int $depth Depth.
*/ */
function woocommerce_comments( $comment, $args, $depth ) { function woocommerce_comments( $comment, $args, $depth ) {
$GLOBALS['comment'] = $comment; // WPCS: override ok. $GLOBALS['comment'] = $comment; // WPCS: override ok.
wc_get_template( 'single-product/review.php', array( 'comment' => $comment, 'args' => $args, 'depth' => $depth ) ); wc_get_template( 'single-product/review.php', array(
'comment' => $comment,
'args' => $args,
'depth' => $depth,
) );
} }
} }
@ -1319,15 +1280,13 @@ if ( ! function_exists( 'woocommerce_output_related_products' ) ) {
/** /**
* Output the related products. * Output the related products.
*
* @subpackage Product
*/ */
function woocommerce_output_related_products() { function woocommerce_output_related_products() {
$args = array( $args = array(
'posts_per_page' => 4, 'posts_per_page' => 4,
'columns' => 4, 'columns' => 4,
'orderby' => 'rand', 'orderby' => 'rand',
); );
woocommerce_related_products( apply_filters( 'woocommerce_output_related_products_args', $args ) ); woocommerce_related_products( apply_filters( 'woocommerce_output_related_products_args', $args ) );
@ -1420,8 +1379,6 @@ if ( ! function_exists( 'woocommerce_shipping_calculator' ) ) {
/** /**
* Output the cart shipping calculator. * Output the cart shipping calculator.
*
* @subpackage Cart
*/ */
function woocommerce_shipping_calculator() { function woocommerce_shipping_calculator() {
wc_get_template( 'cart/shipping-calculator.php' ); wc_get_template( 'cart/shipping-calculator.php' );
@ -1432,8 +1389,6 @@ if ( ! function_exists( 'woocommerce_cart_totals' ) ) {
/** /**
* Output the cart totals. * Output the cart totals.
*
* @subpackage Cart
*/ */
function woocommerce_cart_totals() { function woocommerce_cart_totals() {
if ( is_checkout() ) { if ( is_checkout() ) {
@ -1486,8 +1441,6 @@ if ( ! function_exists( 'woocommerce_button_proceed_to_checkout' ) ) {
/** /**
* Output the proceed to checkout button. * Output the proceed to checkout button.
*
* @subpackage Cart
*/ */
function woocommerce_button_proceed_to_checkout() { function woocommerce_button_proceed_to_checkout() {
wc_get_template( 'cart/proceed-to-checkout-button.php' ); wc_get_template( 'cart/proceed-to-checkout-button.php' );
@ -1498,8 +1451,6 @@ if ( ! function_exists( 'woocommerce_widget_shopping_cart_button_view_cart' ) )
/** /**
* Output the view cart button. * Output the view cart button.
*
* @subpackage Cart
*/ */
function woocommerce_widget_shopping_cart_button_view_cart() { function woocommerce_widget_shopping_cart_button_view_cart() {
echo '<a href="' . esc_url( wc_get_cart_url() ) . '" class="button wc-forward">' . esc_html__( 'View cart', 'woocommerce' ) . '</a>'; echo '<a href="' . esc_url( wc_get_cart_url() ) . '" class="button wc-forward">' . esc_html__( 'View cart', 'woocommerce' ) . '</a>';
@ -1510,8 +1461,6 @@ if ( ! function_exists( 'woocommerce_widget_shopping_cart_proceed_to_checkout' )
/** /**
* Output the proceed to checkout button. * Output the proceed to checkout button.
*
* @subpackage Cart
*/ */
function woocommerce_widget_shopping_cart_proceed_to_checkout() { function woocommerce_widget_shopping_cart_proceed_to_checkout() {
echo '<a href="' . esc_url( wc_get_checkout_url() ) . '" class="button checkout wc-forward">' . esc_html__( 'Checkout', 'woocommerce' ) . '</a>'; echo '<a href="' . esc_url( wc_get_checkout_url() ) . '" class="button checkout wc-forward">' . esc_html__( 'Checkout', 'woocommerce' ) . '</a>';
@ -1546,7 +1495,6 @@ if ( ! function_exists( 'woocommerce_login_form' ) ) {
/** /**
* Output the WooCommerce Login Form. * Output the WooCommerce Login Form.
* *
* @subpackage Forms
* @param array $args Arguments. * @param array $args Arguments.
*/ */
function woocommerce_login_form( $args = array() ) { function woocommerce_login_form( $args = array() ) {
@ -1567,11 +1515,11 @@ if ( ! function_exists( 'woocommerce_checkout_login_form' ) ) {
/** /**
* Output the WooCommerce Checkout Login Form. * Output the WooCommerce Checkout Login Form.
*
* @subpackage Checkout
*/ */
function woocommerce_checkout_login_form() { function woocommerce_checkout_login_form() {
wc_get_template( 'checkout/form-login.php', array( 'checkout' => WC()->checkout() ) ); wc_get_template( 'checkout/form-login.php', array(
'checkout' => WC()->checkout(),
) );
} }
} }
@ -1616,12 +1564,12 @@ if ( ! function_exists( 'woocommerce_order_review' ) ) {
/** /**
* Output the Order review table for the checkout. * Output the Order review table for the checkout.
* *
* @subpackage Checkout
*
* @param bool $deprecated Deprecated param. * @param bool $deprecated Deprecated param.
*/ */
function woocommerce_order_review( $deprecated = false ) { function woocommerce_order_review( $deprecated = false ) {
wc_get_template( 'checkout/review-order.php', array( 'checkout' => WC()->checkout() ) ); wc_get_template( 'checkout/review-order.php', array(
'checkout' => WC()->checkout(),
) );
} }
} }
@ -1629,8 +1577,6 @@ if ( ! function_exists( 'woocommerce_checkout_payment' ) ) {
/** /**
* Output the Payment Methods on the checkout. * Output the Payment Methods on the checkout.
*
* @subpackage Checkout
*/ */
function woocommerce_checkout_payment() { function woocommerce_checkout_payment() {
if ( WC()->cart->needs_payment() ) { if ( WC()->cart->needs_payment() ) {
@ -1652,11 +1598,11 @@ if ( ! function_exists( 'woocommerce_checkout_coupon_form' ) ) {
/** /**
* Output the Coupon form for the checkout. * Output the Coupon form for the checkout.
*
* @subpackage Checkout
*/ */
function woocommerce_checkout_coupon_form() { function woocommerce_checkout_coupon_form() {
wc_get_template( 'checkout/form-coupon.php', array( 'checkout' => WC()->checkout() ) ); wc_get_template( 'checkout/form-coupon.php', array(
'checkout' => WC()->checkout(),
) );
} }
} }
@ -1665,7 +1611,6 @@ if ( ! function_exists( 'woocommerce_products_will_display' ) ) {
/** /**
* Check if we will be showing products or not (and not sub-categories only). * Check if we will be showing products or not (and not sub-categories only).
* *
* @subpackage Loop
* @return bool * @return bool
*/ */
function woocommerce_products_will_display() { function woocommerce_products_will_display() {
@ -1687,19 +1632,18 @@ if ( ! function_exists( 'woocommerce_products_will_display' ) ) {
if ( is_product_category() ) { if ( is_product_category() ) {
switch ( get_woocommerce_term_meta( $term->term_id, 'display_type', true ) ) { switch ( get_woocommerce_term_meta( $term->term_id, 'display_type', true ) ) {
case 'subcategories' : case 'subcategories':
// Nothing - we want to continue to see if there are products/subcats. // Nothing - we want to continue to see if there are products/subcats.
break; break;
case 'products' : case 'products':
case 'both' : case 'both':
return true; return true;
break; default:
default :
// Default - no setting. // Default - no setting.
if ( get_option( 'woocommerce_category_archive_display' ) != 'subcategories' ) { if ( get_option( 'woocommerce_category_archive_display' ) !== 'subcategories' ) {
return true; return true;
} }
break; break;
} }
} }
@ -1708,10 +1652,11 @@ if ( ! function_exists( 'woocommerce_products_will_display' ) ) {
return true; return true;
} }
$transient_name = 'wc_products_will_display_' . $term->term_id . '_' . WC_Cache_Helper::get_transient_version( 'product_query' ); $transient_name = 'wc_products_will_display_' . $term->term_id . '_' . WC_Cache_Helper::get_transient_version( 'product_query' );
$products_will_display = get_transient( $transient_name );
if ( false === ( $products_will_display = get_transient( $transient_name ) ) ) { if ( false === $products_will_display ) {
$has_children = $wpdb->get_col( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE parent = %d AND taxonomy = %s", $term->term_id, $term->taxonomy ) ); // WPCS: cache ok. $has_children = $wpdb->get_col( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE parent = %d AND taxonomy = %s", $term->term_id, $term->taxonomy ) ); // WPCS: db call ok, cache ok.
if ( $has_children ) { if ( $has_children ) {
// Check terms have products inside - parents first. If products are found inside, subcats will be shown instead of products so we can return false. // Check terms have products inside - parents first. If products are found inside, subcats will be shown instead of products so we can return false.
@ -1744,7 +1689,6 @@ if ( ! function_exists( 'woocommerce_product_subcategories' ) ) {
/** /**
* Display product sub categories as thumbnails. * Display product sub categories as thumbnails.
* *
* @subpackage Loop
* @param array $args Arguments. * @param array $args Arguments.
* @return null|boolean * @return null|boolean
*/ */
@ -1777,21 +1721,20 @@ if ( ! function_exists( 'woocommerce_product_subcategories' ) ) {
} }
// Find the category + category parent, if applicable. // Find the category + category parent, if applicable.
$term = get_queried_object(); $term = get_queried_object();
$parent_id = empty( $term->term_id ) ? 0 : $term->term_id; $parent_id = empty( $term->term_id ) ? 0 : $term->term_id;
if ( is_product_category() ) { if ( is_product_category() ) {
$display_type = get_woocommerce_term_meta( $term->term_id, 'display_type', true ); $display_type = get_woocommerce_term_meta( $term->term_id, 'display_type', true );
switch ( $display_type ) { switch ( $display_type ) {
case 'products' : case 'products':
return; return;
break; case '':
case '' :
if ( '' === get_option( 'woocommerce_category_archive_display' ) ) { if ( '' === get_option( 'woocommerce_category_archive_display' ) ) {
return; return;
} }
break; break;
} }
} }
@ -1806,7 +1749,9 @@ if ( ! function_exists( 'woocommerce_product_subcategories' ) ) {
) ) ); ) ) );
if ( apply_filters( 'woocommerce_product_subcategories_hide_empty', true ) ) { if ( apply_filters( 'woocommerce_product_subcategories_hide_empty', true ) ) {
$product_categories = wp_list_filter( $product_categories, array( 'count' => 0 ), 'NOT' ); $product_categories = wp_list_filter( $product_categories, array(
'count' => 0,
), 'NOT' );
} }
if ( $product_categories ) { if ( $product_categories ) {
@ -1823,16 +1768,16 @@ if ( ! function_exists( 'woocommerce_product_subcategories' ) ) {
$display_type = get_woocommerce_term_meta( $term->term_id, 'display_type', true ); $display_type = get_woocommerce_term_meta( $term->term_id, 'display_type', true );
switch ( $display_type ) { switch ( $display_type ) {
case 'subcategories' : case 'subcategories':
$wp_query->post_count = 0; $wp_query->post_count = 0;
$wp_query->max_num_pages = 0; $wp_query->max_num_pages = 0;
break; break;
case '' : case '':
if ( 'subcategories' === get_option( 'woocommerce_category_archive_display' ) ) { if ( 'subcategories' === get_option( 'woocommerce_category_archive_display' ) ) {
$wp_query->post_count = 0; $wp_query->post_count = 0;
$wp_query->max_num_pages = 0; $wp_query->max_num_pages = 0;
} }
break; break;
} }
} }
@ -1854,12 +1799,11 @@ if ( ! function_exists( 'woocommerce_subcategory_thumbnail' ) ) {
* Show subcategory thumbnails. * Show subcategory thumbnails.
* *
* @param mixed $category Category. * @param mixed $category Category.
* @subpackage Loop
*/ */
function woocommerce_subcategory_thumbnail( $category ) { function woocommerce_subcategory_thumbnail( $category ) {
$small_thumbnail_size = apply_filters( 'subcategory_archive_thumbnail_size', 'woocommerce_thumbnail' ); $small_thumbnail_size = apply_filters( 'subcategory_archive_thumbnail_size', 'woocommerce_thumbnail' );
$dimensions = wc_get_image_size( $small_thumbnail_size ); $dimensions = wc_get_image_size( $small_thumbnail_size );
$thumbnail_id = get_woocommerce_term_meta( $category->term_id, 'thumbnail_id', true ); $thumbnail_id = get_woocommerce_term_meta( $category->term_id, 'thumbnail_id', true );
if ( $thumbnail_id ) { if ( $thumbnail_id ) {
$image = wp_get_attachment_image_src( $thumbnail_id, $small_thumbnail_size ); $image = wp_get_attachment_image_src( $thumbnail_id, $small_thumbnail_size );
@ -1868,7 +1812,8 @@ if ( ! function_exists( 'woocommerce_subcategory_thumbnail' ) ) {
$image_sizes = function_exists( 'wp_get_attachment_image_sizes' ) ? wp_get_attachment_image_sizes( $thumbnail_id, $small_thumbnail_size ) : false; $image_sizes = function_exists( 'wp_get_attachment_image_sizes' ) ? wp_get_attachment_image_sizes( $thumbnail_id, $small_thumbnail_size ) : false;
} else { } else {
$image = wc_placeholder_img_src(); $image = wc_placeholder_img_src();
$image_srcset = $image_sizes = false; $image_srcset = false;
$image_sizes = false;
} }
if ( $image ) { if ( $image ) {
@ -1892,7 +1837,6 @@ if ( ! function_exists( 'woocommerce_order_details_table' ) ) {
* Displays order details in a table. * Displays order details in a table.
* *
* @param mixed $order_id Order ID. * @param mixed $order_id Order ID.
* @subpackage Orders
*/ */
function woocommerce_order_details_table( $order_id ) { function woocommerce_order_details_table( $order_id ) {
if ( ! $order_id ) { if ( ! $order_id ) {
@ -1929,7 +1873,6 @@ if ( ! function_exists( 'woocommerce_order_again_button' ) ) {
* Display an 'order again' button on the view order page. * Display an 'order again' button on the view order page.
* *
* @param object $order Order. * @param object $order Order.
* @subpackage Orders
*/ */
function woocommerce_order_again_button( $order ) { function woocommerce_order_again_button( $order ) {
if ( ! $order || ! $order->has_status( apply_filters( 'woocommerce_valid_order_statuses_for_order_again', array( 'completed' ) ) ) || ! is_user_logged_in() ) { if ( ! $order || ! $order->has_status( apply_filters( 'woocommerce_valid_order_statuses_for_order_again', array( 'completed' ) ) ) || ! is_user_logged_in() ) {
@ -1949,12 +1892,9 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) {
/** /**
* Outputs a checkout/address form field. * Outputs a checkout/address form field.
* *
* @subpackage Forms
*
* @param string $key Key. * @param string $key Key.
* @param mixed $args Arguments. * @param mixed $args Arguments.
* @param string $value (default: null). * @param string $value (default: null).
*
* @return string * @return string
*/ */
function woocommerce_form_field( $key, $args, $value = null ) { function woocommerce_form_field( $key, $args, $value = null ) {
@ -2031,8 +1971,7 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) {
$field_container = '<p class="form-row %1$s" id="%2$s" data-priority="' . esc_attr( $sort ) . '">%3$s</p>'; $field_container = '<p class="form-row %1$s" id="%2$s" data-priority="' . esc_attr( $sort ) . '">%3$s</p>';
switch ( $args['type'] ) { switch ( $args['type'] ) {
case 'country' : case 'country':
$countries = 'shipping_country' === $key ? WC()->countries->get_shipping_countries() : WC()->countries->get_allowed_countries(); $countries = 'shipping_country' === $key ? WC()->countries->get_shipping_countries() : WC()->countries->get_allowed_countries();
if ( 1 === count( $countries ) ) { if ( 1 === count( $countries ) ) {
@ -2056,7 +1995,7 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) {
} }
break; break;
case 'state' : case 'state':
/* Get country this state field is representing */ /* Get country this state field is representing */
$for_country = isset( $args['country'] ) ? $args['country'] : WC()->checkout->get_value( 'billing_state' === $key ? 'billing_country' : 'shipping_country' ); $for_country = isset( $args['country'] ) ? $args['country'] : WC()->checkout->get_value( 'billing_state' === $key ? 'billing_country' : 'shipping_country' );
$states = WC()->countries->get_states( $for_country ); $states = WC()->countries->get_states( $for_country );
@ -2085,30 +2024,27 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) {
} }
break; break;
case 'textarea' : case 'textarea':
$field .= '<textarea name="' . esc_attr( $key ) . '" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" id="' . esc_attr( $args['id'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" ' . ( empty( $args['custom_attributes']['rows'] ) ? ' rows="2"' : '' ) . ( empty( $args['custom_attributes']['cols'] ) ? ' cols="5"' : '' ) . implode( ' ', $custom_attributes ) . '>' . esc_textarea( $value ) . '</textarea>'; $field .= '<textarea name="' . esc_attr( $key ) . '" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" id="' . esc_attr( $args['id'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" ' . ( empty( $args['custom_attributes']['rows'] ) ? ' rows="2"' : '' ) . ( empty( $args['custom_attributes']['cols'] ) ? ' cols="5"' : '' ) . implode( ' ', $custom_attributes ) . '>' . esc_textarea( $value ) . '</textarea>';
break; break;
case 'checkbox' : case 'checkbox':
$field = '<label class="checkbox ' . implode( ' ', $args['label_class'] ) . '" ' . implode( ' ', $custom_attributes ) . '> $field = '<label class="checkbox ' . implode( ' ', $args['label_class'] ) . '" ' . implode( ' ', $custom_attributes ) . '>
<input type="' . esc_attr( $args['type'] ) . '" class="input-checkbox ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" value="1" ' . checked( $value, 1, false ) . ' /> ' <input type="' . esc_attr( $args['type'] ) . '" class="input-checkbox ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" value="1" ' . checked( $value, 1, false ) . ' /> '
. $args['label'] . $required . '</label>'; . $args['label'] . $required . '</label>';
break; break;
case 'password' : case 'password':
case 'text' : case 'text':
case 'email' : case 'email':
case 'tel' : case 'tel':
case 'number' : case 'number':
$field .= '<input type="' . esc_attr( $args['type'] ) . '" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />'; $field .= '<input type="' . esc_attr( $args['type'] ) . '" class="input-text ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />';
break; break;
case 'select' : case 'select':
$field = '';
$options = $field = ''; $options = '';
if ( ! empty( $args['options'] ) ) { if ( ! empty( $args['options'] ) ) {
foreach ( $args['options'] as $option_key => $option_text ) { foreach ( $args['options'] as $option_key => $option_text ) {
@ -2128,8 +2064,7 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) {
} }
break; break;
case 'radio' : case 'radio':
$label_id = current( array_keys( $args['options'] ) ); $label_id = current( array_keys( $args['options'] ) );
if ( ! empty( $args['options'] ) ) { if ( ! empty( $args['options'] ) ) {
@ -2145,7 +2080,7 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) {
if ( ! empty( $field ) ) { if ( ! empty( $field ) ) {
$field_html = ''; $field_html = '';
if ( $args['label'] && 'checkbox' != $args['type'] ) { if ( $args['label'] && 'checkbox' !== $args['type'] ) {
$field_html .= '<label for="' . esc_attr( $label_id ) . '" class="' . esc_attr( implode( ' ', $args['label_class'] ) ) . '">' . $args['label'] . $required . '</label>'; $field_html .= '<label for="' . esc_attr( $label_id ) . '" class="' . esc_attr( implode( ' ', $args['label_class'] ) ) . '">' . $args['label'] . $required . '</label>';
} }
@ -2181,11 +2116,10 @@ if ( ! function_exists( 'get_product_search_form' ) ) {
* *
* The default searchform uses html5. * The default searchform uses html5.
* *
* @subpackage Forms
* @param bool $echo (default: true). * @param bool $echo (default: true).
* @return string * @return string
*/ */
function get_product_search_form( $echo = true ) { function get_product_search_form( $echo = true ) {
global $product_search_form_index; global $product_search_form_index;
ob_start(); ob_start();
@ -2263,7 +2197,7 @@ if ( ! function_exists( 'wc_dropdown_variation_attribute_options' ) ) {
'options' => false, 'options' => false,
'attribute' => false, 'attribute' => false,
'product' => false, 'product' => false,
'selected' => false, 'selected' => false,
'name' => '', 'name' => '',
'id' => '', 'id' => '',
'class' => '', 'class' => '',
@ -2290,10 +2224,12 @@ if ( ! function_exists( 'wc_dropdown_variation_attribute_options' ) ) {
if ( ! empty( $options ) ) { if ( ! empty( $options ) ) {
if ( $product && taxonomy_exists( $attribute ) ) { if ( $product && taxonomy_exists( $attribute ) ) {
// Get terms if this is a taxonomy - ordered. We need the names too. // Get terms if this is a taxonomy - ordered. We need the names too.
$terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) ); $terms = wc_get_product_terms( $product->get_id(), $attribute, array(
'fields' => 'all',
) );
foreach ( $terms as $term ) { foreach ( $terms as $term ) {
if ( in_array( $term->slug, $options ) ) { if ( in_array( $term->slug, $options, true ) ) {
$html .= '<option value="' . esc_attr( $term->slug ) . '" ' . selected( sanitize_title( $args['selected'] ), $term->slug, false ) . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) ) . '</option>'; $html .= '<option value="' . esc_attr( $term->slug ) . '" ' . selected( sanitize_title( $args['selected'] ), $term->slug, false ) . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) ) . '</option>';
} }
} }
@ -2360,7 +2296,11 @@ if ( ! function_exists( 'woocommerce_account_orders' ) ) {
*/ */
function woocommerce_account_orders( $current_page ) { function woocommerce_account_orders( $current_page ) {
$current_page = empty( $current_page ) ? 1 : absint( $current_page ); $current_page = empty( $current_page ) ? 1 : absint( $current_page );
$customer_orders = wc_get_orders( apply_filters( 'woocommerce_my_account_my_orders_query', array( 'customer' => get_current_user_id(), 'page' => $current_page, 'paginate' => true ) ) ); $customer_orders = wc_get_orders( apply_filters( 'woocommerce_my_account_my_orders_query', array(
'customer' => get_current_user_id(),
'page' => $current_page,
'paginate' => true,
) ) );
wc_get_template( wc_get_template(
'myaccount/orders.php', 'myaccount/orders.php',
@ -2504,10 +2444,10 @@ if ( ! function_exists( 'wc_display_item_meta' ) ) {
$html = ''; $html = '';
$args = wp_parse_args( $args, array( $args = wp_parse_args( $args, array(
'before' => '<ul class="wc-item-meta"><li>', 'before' => '<ul class="wc-item-meta"><li>',
'after' => '</li></ul>', 'after' => '</li></ul>',
'separator' => '</li><li>', 'separator' => '</li><li>',
'echo' => true, 'echo' => true,
'autop' => false, 'autop' => false,
) ); ) );
foreach ( $item->get_formatted_meta_data() as $meta_id => $meta ) { foreach ( $item->get_formatted_meta_data() as $meta_id => $meta ) {
@ -2549,7 +2489,9 @@ if ( ! function_exists( 'wc_display_item_downloads' ) ) {
'show_url' => false, 'show_url' => false,
) ); ) );
if ( is_object( $item ) && $item->is_type( 'line_item' ) && ( $downloads = $item->get_item_downloads() ) ) { $downloads = is_object( $item ) && $item->is_type( 'line_item' ) ? $item->get_item_downloads() : array();
if ( $downloads ) {
$i = 0; $i = 0;
foreach ( $downloads as $file ) { foreach ( $downloads as $file ) {
$i ++; $i ++;
@ -2557,6 +2499,7 @@ if ( ! function_exists( 'wc_display_item_downloads' ) ) {
if ( $args['show_url'] ) { if ( $args['show_url'] ) {
$strings[] = '<strong class="wc-item-download-label">' . esc_html( $file['name'] ) . ':</strong> ' . esc_html( $file['download_url'] ); $strings[] = '<strong class="wc-item-download-label">' . esc_html( $file['name'] ) . ':</strong> ' . esc_html( $file['download_url'] );
} else { } else {
/* translators: %d: downloads count */
$prefix = count( $downloads ) > 1 ? sprintf( __( 'Download %d', 'woocommerce' ), $i ) : __( 'Download', 'woocommerce' ); $prefix = count( $downloads ) > 1 ? sprintf( __( 'Download %d', 'woocommerce' ), $i ) : __( 'Download', 'woocommerce' );
$strings[] = '<strong class="wc-item-download-label">' . $prefix . ':</strong> <a href="' . esc_url( $file['download_url'] ) . '" target="_blank">' . esc_html( $file['name'] ) . '</a>'; $strings[] = '<strong class="wc-item-download-label">' . $prefix . ':</strong> <a href="' . esc_url( $file['download_url'] ) . '" target="_blank">' . esc_html( $file['name'] ) . '</a>';
} }

View File

@ -50,21 +50,22 @@ function wc_update_200_file_paths() {
*/ */
function wc_update_200_permalinks() { function wc_update_200_permalinks() {
// Setup default permalinks if shop page is defined. // Setup default permalinks if shop page is defined.
$permalinks = get_option( 'woocommerce_permalinks' ); $permalinks = get_option( 'woocommerce_permalinks' );
$shop_page_id = wc_get_page_id( 'shop' ); $shop_page_id = wc_get_page_id( 'shop' );
if ( empty( $permalinks ) && $shop_page_id > 0 ) { if ( empty( $permalinks ) && $shop_page_id > 0 ) {
$base_slug = $shop_page_id > 0 && get_post( $shop_page_id ) ? get_page_uri( $shop_page_id ) : 'shop'; $base_slug = $shop_page_id > 0 && get_post( $shop_page_id ) ? get_page_uri( $shop_page_id ) : 'shop';
$category_base = get_option( 'woocommerce_prepend_shop_page_to_urls' ) == 'yes' ? trailingslashit( $base_slug ) : ''; $category_base = get_option( 'woocommerce_prepend_shop_page_to_urls' ) == 'yes' ? trailingslashit( $base_slug ) : '';
$category_slug = get_option( 'woocommerce_product_category_slug' ) ? get_option( 'woocommerce_product_category_slug' ) : _x( 'product-category', 'slug', 'woocommerce' ); $category_slug = get_option( 'woocommerce_product_category_slug' ) ? get_option( 'woocommerce_product_category_slug' ) : _x( 'product-category', 'slug', 'woocommerce' );
$tag_slug = get_option( 'woocommerce_product_tag_slug' ) ? get_option( 'woocommerce_product_tag_slug' ) : _x( 'product-tag', 'slug', 'woocommerce' ); $tag_slug = get_option( 'woocommerce_product_tag_slug' ) ? get_option( 'woocommerce_product_tag_slug' ) : _x( 'product-tag', 'slug', 'woocommerce' );
if ( 'yes' == get_option( 'woocommerce_prepend_shop_page_to_products' ) ) { if ( 'yes' == get_option( 'woocommerce_prepend_shop_page_to_products' ) ) {
$product_base = trailingslashit( $base_slug ); $product_base = trailingslashit( $base_slug );
} else { } 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 ); $product_base = trailingslashit( $product_slug );
} else { } else {
$product_base = trailingslashit( _x( 'product', 'slug', 'woocommerce' ) ); $product_base = trailingslashit( _x( 'product', 'slug', 'woocommerce' ) );
@ -76,10 +77,10 @@ function wc_update_200_permalinks() {
} }
$permalinks = array( $permalinks = array(
'product_base' => untrailingslashit( $product_base ), 'product_base' => untrailingslashit( $product_base ),
'category_base' => untrailingslashit( $category_base . $category_slug ), 'category_base' => untrailingslashit( $category_base . $category_slug ),
'attribute_base' => untrailingslashit( $category_base ), 'attribute_base' => untrailingslashit( $category_base ),
'tag_base' => untrailingslashit( $category_base . $tag_slug ), 'tag_base' => untrailingslashit( $category_base . $tag_slug ),
); );
update_option( 'woocommerce_permalinks', $permalinks ); update_option( 'woocommerce_permalinks', $permalinks );
@ -119,7 +120,7 @@ function wc_update_200_taxrates() {
global $wpdb; global $wpdb;
// Update tax rates. // Update tax rates.
$loop = 0; $loop = 0;
$tax_rates = get_option( 'woocommerce_tax_rates' ); $tax_rates = get_option( 'woocommerce_tax_rates' );
if ( $tax_rates ) { if ( $tax_rates ) {
@ -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 * @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. // 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'. // Reverse with UPDATE `wpwc_postmeta` SET meta_key = '_order_items' WHERE meta_key = '_order_items_old'.
$order_item_rows = $wpdb->get_results( " $order_item_rows = $wpdb->get_results(
SELECT meta_value, post_id FROM {$wpdb->postmeta} "SELECT meta_value, post_id FROM {$wpdb->postmeta} WHERE meta_key = '_order_items'"
WHERE meta_key = '_order_items' );
" );
foreach ( $order_item_rows as $order_item_row ) { foreach ( $order_item_rows as $order_item_row ) {
@ -231,21 +231,24 @@ function wc_update_200_line_items() {
foreach ( $order_items as $order_item ) { foreach ( $order_items as $order_item ) {
if ( ! isset( $order_item['line_total'] ) && isset( $order_item['taxrate'] ) && isset( $order_item['cost'] ) ) { if ( ! isset( $order_item['line_total'] ) && isset( $order_item['taxrate'] ) && isset( $order_item['cost'] ) ) {
$order_item['line_tax'] = number_format( ( $order_item['cost'] * $order_item['qty'] ) * ( $order_item['taxrate'] / 100 ), 2, '.', '' ); $order_item['line_tax'] = number_format( ( $order_item['cost'] * $order_item['qty'] ) * ( $order_item['taxrate'] / 100 ), 2, '.', '' );
$order_item['line_total'] = $order_item['cost'] * $order_item['qty']; $order_item['line_total'] = $order_item['cost'] * $order_item['qty'];
$order_item['line_subtotal_tax'] = $order_item['line_tax']; $order_item['line_subtotal_tax'] = $order_item['line_tax'];
$order_item['line_subtotal'] = $order_item['line_total']; $order_item['line_subtotal'] = $order_item['line_total'];
} }
$order_item['line_tax'] = isset( $order_item['line_tax'] ) ? $order_item['line_tax'] : 0; $order_item['line_tax'] = isset( $order_item['line_tax'] ) ? $order_item['line_tax'] : 0;
$order_item['line_total'] = isset( $order_item['line_total'] ) ? $order_item['line_total'] : 0; $order_item['line_total'] = isset( $order_item['line_total'] ) ? $order_item['line_total'] : 0;
$order_item['line_subtotal_tax'] = isset( $order_item['line_subtotal_tax'] ) ? $order_item['line_subtotal_tax'] : 0; $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; $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_name' => $order_item['name'], $order_item_row->post_id,
'order_item_type' => 'line_item', array(
) ); 'order_item_name' => $order_item['name'],
'order_item_type' => 'line_item',
)
);
// Add line item meta. // Add line item meta.
if ( $item_id ) { if ( $item_id ) {
@ -274,19 +277,25 @@ function wc_update_200_line_items() {
// Insert meta rows at once. // Insert meta rows at once.
if ( count( $meta_rows ) > 0 ) { if ( count( $meta_rows ) > 0 ) {
$wpdb->query( $wpdb->prepare( " $wpdb->query(
INSERT INTO {$wpdb->prefix}woocommerce_order_itemmeta ( order_item_id, meta_key, meta_value ) $wpdb->prepare(
VALUES " . implode( ',', $meta_rows ) . '; "INSERT INTO {$wpdb->prefix}woocommerce_order_itemmeta ( order_item_id, meta_key, meta_value )
', $order_item_row->post_id ) ); VALUES " . implode( ',', $meta_rows ) . ';', // @codingStandardsIgnoreLine
$order_item_row->post_id
)
);
} }
// Delete from DB (rename). // Delete from DB (rename).
$wpdb->query( $wpdb->prepare( " $wpdb->query(
UPDATE {$wpdb->postmeta} $wpdb->prepare(
SET meta_key = '_order_items_old' "UPDATE {$wpdb->postmeta}
WHERE meta_key = '_order_items' SET meta_key = '_order_items_old'
AND post_id = %d WHERE meta_key = '_order_items'
", $order_item_row->post_id ) ); AND post_id = %d",
$order_item_row->post_id
)
);
} }
unset( $meta_rows, $item_id, $order_item ); 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. // 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'. // Reverse with UPDATE `wpwc_postmeta` SET meta_key = '_order_taxes' WHERE meta_key = '_order_taxes_old'.
$order_tax_rows = $wpdb->get_results( " $order_tax_rows = $wpdb->get_results(
SELECT meta_value, post_id FROM {$wpdb->postmeta} "SELECT meta_value, post_id FROM {$wpdb->postmeta}
WHERE meta_key = '_order_taxes' WHERE meta_key = '_order_taxes'"
" ); );
foreach ( $order_tax_rows as $order_tax_row ) { foreach ( $order_tax_rows as $order_tax_row ) {
@ -311,10 +320,12 @@ function wc_update_200_line_items() {
continue; continue;
} }
$item_id = wc_add_order_item( $order_tax_row->post_id, array( $item_id = wc_add_order_item(
'order_item_name' => $order_tax['label'], $order_tax_row->post_id, array(
'order_item_type' => 'tax', 'order_item_name' => $order_tax['label'],
) ); 'order_item_type' => 'tax',
)
);
// Add line item meta. // Add line item meta.
if ( $item_id ) { if ( $item_id ) {
@ -324,12 +335,15 @@ function wc_update_200_line_items() {
} }
// Delete from DB (rename). // Delete from DB (rename).
$wpdb->query( $wpdb->prepare( " $wpdb->query(
UPDATE {$wpdb->postmeta} $wpdb->prepare(
SET meta_key = '_order_taxes_old' "UPDATE {$wpdb->postmeta}
WHERE meta_key = '_order_taxes' SET meta_key = '_order_taxes_old'
AND post_id = %d WHERE meta_key = '_order_taxes'
", $order_tax_row->post_id ) ); AND post_id = %d",
$order_tax_row->post_id
)
);
unset( $tax_amount ); unset( $tax_amount );
} }
@ -347,11 +361,13 @@ function wc_update_200_images() {
// cleaning up afterwards like nice people do. // cleaning up afterwards like nice people do.
foreach ( array( 'catalog', 'single', 'thumbnail' ) as $value ) { foreach ( array( 'catalog', 'single', 'thumbnail' ) as $value ) {
$old_settings = array_filter( array( $old_settings = array_filter(
'width' => get_option( 'woocommerce_' . $value . '_image_width' ), array(
'height' => get_option( 'woocommerce_' . $value . '_image_height' ), 'width' => get_option( 'woocommerce_' . $value . '_image_width' ),
'crop' => get_option( 'woocommerce_' . $value . '_image_crop' ), '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 ) ) { 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() { function wc_update_220_order_status() {
global $wpdb; global $wpdb;
$wpdb->query( " $wpdb->query(
UPDATE {$wpdb->posts} as posts "UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id 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->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_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' WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish' AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status' AND tax.taxonomy = 'shop_order_status'
AND term.slug LIKE 'pending%'; AND term.slug LIKE 'pending%';"
"
); );
$wpdb->query( " $wpdb->query(
UPDATE {$wpdb->posts} as posts "UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id 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->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_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' WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish' AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status' AND tax.taxonomy = 'shop_order_status'
AND term.slug LIKE 'processing%'; AND term.slug LIKE 'processing%';"
"
); );
$wpdb->query( " $wpdb->query(
UPDATE {$wpdb->posts} as posts "UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id 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->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_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' WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish' AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status' AND tax.taxonomy = 'shop_order_status'
AND term.slug LIKE 'on-hold%'; AND term.slug LIKE 'on-hold%';"
"
); );
$wpdb->query( " $wpdb->query(
UPDATE {$wpdb->posts} as posts "UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id 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->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_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' WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish' AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status' AND tax.taxonomy = 'shop_order_status'
AND term.slug LIKE 'completed%'; AND term.slug LIKE 'completed%';"
"
); );
$wpdb->query( " $wpdb->query(
UPDATE {$wpdb->posts} as posts "UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id 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->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_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' WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish' AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status' AND tax.taxonomy = 'shop_order_status'
AND term.slug LIKE 'cancelled%'; AND term.slug LIKE 'cancelled%';"
"
); );
$wpdb->query( " $wpdb->query(
UPDATE {$wpdb->posts} as posts "UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id 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->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_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' WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish' AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status' AND tax.taxonomy = 'shop_order_status'
AND term.slug LIKE 'refunded%'; AND term.slug LIKE 'refunded%';"
"
); );
$wpdb->query( " $wpdb->query(
UPDATE {$wpdb->posts} as posts "UPDATE {$wpdb->posts} as posts
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID = rel.object_id 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->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_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' WHERE posts.post_type = 'shop_order'
AND posts.post_status = 'publish' AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status' 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() { function wc_update_220_variations() {
global $wpdb; global $wpdb;
// Update variations which manage stock. // Update variations which manage stock.
$update_variations = $wpdb->get_results( " $update_variations = $wpdb->get_results(
SELECT DISTINCT posts.ID AS variation_id, posts.post_parent AS variation_parent FROM {$wpdb->posts} as posts "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 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' 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' WHERE posts.post_type = 'product_variation'
AND postmeta.meta_value IS NOT NULL AND postmeta.meta_value IS NOT NULL
AND postmeta.meta_value != '' AND postmeta.meta_value != ''
AND postmeta2.meta_value IS NULL AND postmeta2.meta_value IS NULL"
" ); );
foreach ( $update_variations as $variation ) { foreach ( $update_variations as $variation ) {
$parent_backorders = get_post_meta( $variation->variation_parent, '_backorders', true ); $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; $has_classes = count( WC()->shipping->get_shipping_classes() ) > 0;
$cost_key = $has_classes ? 'no_class_cost' : 'cost'; $cost_key = $has_classes ? 'no_class_cost' : 'cost';
$min_fee = $shipping_method->get_option( 'minimum_fee' ); $min_fee = $shipping_method->get_option( 'minimum_fee' );
$math_cost_strings = array( 'cost' => array(), 'no_class_cost' => array() ); $math_cost_strings = array(
$math_cost_strings[ $cost_key ][] = $shipping_method->get_option( 'cost' ); '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; $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']; $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 ) { foreach ( $flat_rates as $shipping_class => $rate ) {
$rate_key = 'class_cost_' . $shipping_class; $rate_key = 'class_cost_' . $shipping_class;
if ( $rate['cost'] || $rate['fee'] ) { if ( $rate['cost'] || $rate['fee'] ) {
@ -798,7 +814,7 @@ function wc_update_240_api_keys() {
// Get user data. // Get user data.
foreach ( $api_users as $_user ) { foreach ( $api_users as $_user ) {
$user = get_userdata( $_user->user_id ); $user = get_userdata( $_user->user_id );
$apps_keys[] = array( $apps_keys[] = array(
'user_id' => $user->ID, 'user_id' => $user->ID,
'permissions' => $user->woocommerce_api_key_permissions, 'permissions' => $user->woocommerce_api_key_permissions,
@ -835,6 +851,33 @@ function wc_update_240_api_keys() {
} }
/** /**
<<<<<<< HEAD
=======
* Update webhooks for 2.4
*
* @return void
*/
function wc_update_240_webhooks() {
/**
* Webhooks.
* Make sure order.update webhooks get the woocommerce_order_edit_status hook.
*/
$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' );
}
}
/**
>>>>>>> master
* Update refunds for 2.4 * Update refunds for 2.4
* *
* @return void * @return void
@ -845,11 +888,13 @@ function wc_update_240_refunds() {
* Refunds for full refunded orders. * Refunds for full refunded orders.
* Update fully refunded orders to ensure they have a refund line item so reports add up. * 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(
'posts_per_page' => -1, array(
'post_type' => 'shop_order', 'posts_per_page' => -1,
'post_status' => array( 'wc-refunded' ), 'post_type' => 'shop_order',
) ); 'post_status' => array( 'wc-refunded' ),
)
);
// Ensure emails are disabled during this update routine. // Ensure emails are disabled during this update routine.
remove_all_actions( 'woocommerce_order_status_refunded_notification' ); remove_all_actions( 'woocommerce_order_status_refunded_notification' );
@ -859,22 +904,27 @@ function wc_update_240_refunds() {
foreach ( $refunded_orders as $refunded_order ) { foreach ( $refunded_orders as $refunded_order ) {
$order_total = get_post_meta( $refunded_order->ID, '_order_total', true ); $order_total = get_post_meta( $refunded_order->ID, '_order_total', true );
$refunded_total = $wpdb->get_var( $wpdb->prepare( " $refunded_total = $wpdb->get_var(
SELECT SUM( postmeta.meta_value ) $wpdb->prepare(
FROM $wpdb->postmeta AS postmeta "SELECT SUM( postmeta.meta_value )
INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d ) FROM $wpdb->postmeta AS postmeta
WHERE postmeta.meta_key = '_refund_amount' INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d )
AND postmeta.post_id = posts.ID WHERE postmeta.meta_key = '_refund_amount'
", $refunded_order->ID ) ); AND postmeta.post_id = posts.ID",
$refunded_order->ID
)
);
if ( $order_total > $refunded_total ) { if ( $order_total > $refunded_total ) {
wc_create_refund( array( wc_create_refund(
'amount' => $order_total - $refunded_total, array(
'reason' => __( 'Order fully refunded', 'woocommerce' ), 'amount' => $order_total - $refunded_total,
'order_id' => $refunded_order->ID, 'reason' => __( 'Order fully refunded', 'woocommerce' ),
'line_items' => array(), 'order_id' => $refunded_order->ID,
'date' => $refunded_order->post_modified, 'line_items' => array(),
) ); 'date' => $refunded_order->post_modified,
)
);
} }
} }
@ -899,13 +949,13 @@ function wc_update_241_variations() {
global $wpdb; global $wpdb;
// Select variations that don't have any _stock_status implemented on WooCommerce 2.2. // Select variations that don't have any _stock_status implemented on WooCommerce 2.2.
$update_variations = $wpdb->get_results( " $update_variations = $wpdb->get_results(
SELECT DISTINCT posts.ID AS variation_id, posts.post_parent AS variation_parent "SELECT DISTINCT posts.ID AS variation_id, posts.post_parent AS variation_parent
FROM {$wpdb->posts} as posts FROM {$wpdb->posts} as posts
LEFT OUTER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id AND postmeta.meta_key = '_stock_status' 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' WHERE posts.post_type = 'product_variation'
AND postmeta.meta_value IS NULL AND postmeta.meta_value IS NULL"
" ); );
foreach ( $update_variations as $variation ) { foreach ( $update_variations as $variation ) {
// Get the parent _stock_status. // Get the parent _stock_status.
@ -1043,11 +1093,13 @@ function wc_update_260_zone_methods() {
// Move data. // Move data.
foreach ( $old_methods as $old_method ) { foreach ( $old_methods as $old_method ) {
$wpdb->insert( $wpdb->prefix . 'woocommerce_shipping_zone_methods', array( $wpdb->insert(
'zone_id' => $old_method->zone_id, $wpdb->prefix . 'woocommerce_shipping_zone_methods', array(
'method_id' => $old_method->shipping_method_type, 'zone_id' => $old_method->zone_id,
'method_order' => $old_method->shipping_method_order, 'method_id' => $old_method->shipping_method_type,
) ); 'method_order' => $old_method->shipping_method_order,
)
);
$new_instance_id = $wpdb->insert_id; $new_instance_id = $wpdb->insert_id;
@ -1108,13 +1160,13 @@ function wc_update_260_refunds() {
/** /**
* Refund item qty should be negative. * Refund item qty should be negative.
*/ */
$wpdb->query( " $wpdb->query(
UPDATE {$wpdb->prefix}woocommerce_order_itemmeta as item_meta "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->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 LEFT JOIN {$wpdb->posts} as posts ON items.order_id = posts.ID
SET item_meta.meta_value = item_meta.meta_value * -1 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'"
" ); );
} }
/** /**
@ -1127,6 +1179,33 @@ function wc_update_260_db_version() {
} }
/** /**
<<<<<<< HEAD
=======
* Update webhooks for 3.0
*
* @return void
*/
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(
'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' );
}
}
/**
>>>>>>> master
* Add an index to the field comment_type to improve the response time of the query * Add an index to the field comment_type to improve the response time of the query
* used by WC_Comments::wp_count_comments() to get the number of comments by type. * used by WC_Comments::wp_count_comments() to get the number of comments by type.
*/ */
@ -1153,12 +1232,14 @@ function wc_update_300_grouped_products() {
foreach ( $parents as $parent_id ) { foreach ( $parents as $parent_id ) {
$parent = wc_get_product( $parent_id ); $parent = wc_get_product( $parent_id );
if ( $parent && $parent->is_type( 'grouped' ) ) { if ( $parent && $parent->is_type( 'grouped' ) ) {
$children_ids = get_posts( array( $children_ids = get_posts(
'post_parent' => $parent_id, array(
'posts_per_page' => -1, 'post_parent' => $parent_id,
'post_type' => 'product', 'posts_per_page' => -1,
'fields' => 'ids', 'post_type' => 'product',
) ); 'fields' => 'ids',
)
);
update_post_meta( $parent_id, '_children', $children_ids ); update_post_meta( $parent_id, '_children', $children_ids );
// Update children to remove the parent. // Update children to remove the parent.
@ -1197,39 +1278,57 @@ function wc_update_300_product_visibility() {
WC_Install::create_terms(); 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 ) ); $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 ) ); $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 ) ); $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 ) ); $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 ) ); $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 ) ); $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 ) ); $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 ) ); $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 ) ); $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 ) );
} }
} }
@ -1329,12 +1428,10 @@ function wc_update_320_mexican_states() {
foreach ( $mx_states as $old => $new ) { foreach ( $mx_states as $old => $new ) {
$wpdb->query( $wpdb->query(
$wpdb->prepare( $wpdb->prepare(
" "UPDATE $wpdb->postmeta
UPDATE $wpdb->postmeta SET meta_value = %s
SET meta_value = %s WHERE meta_key IN ( '_billing_state', '_shipping_state' )
WHERE meta_key IN ( '_billing_state', '_shipping_state' ) AND meta_value = %s",
AND meta_value = %s
",
$new, $old $new, $old
) )
); );
@ -1422,6 +1519,33 @@ function wc_update_330_webhooks() {
} }
unregister_post_type( 'shop_webhook' ); unregister_post_type( 'shop_webhook' );
/**
* 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' );
}
} }
/** /**

View File

@ -148,7 +148,19 @@ function wc_update_new_customer_past_orders( $customer_id ) {
if ( ! empty( $customer_orders ) ) { if ( ! empty( $customer_orders ) ) {
foreach ( $customer_orders as $order_id ) { foreach ( $customer_orders as $order_id ) {
update_post_meta( $order_id, '_customer_user', $customer->ID ); $order = wc_get_order( $order_id );
if ( ! $order ) {
continue;
}
$order->set_customer_id( $customer->ID );
$order->save();
if ( $order->has_downloadable_item() ) {
$data_store = WC_Data_Store::load( 'customer-download' );
$data_store->delete_by_order_id( $order->get_id() );
wc_downloadable_product_permissions( $order->get_id(), true );
}
do_action( 'woocommerce_update_new_customer_past_order', $order_id, $customer ); do_action( 'woocommerce_update_new_customer_past_order', $order_id, $customer );

View File

@ -264,7 +264,7 @@ class WC_Widget_Layered_Nav extends WC_Widget {
continue; continue;
} }
echo '<option value="' . esc_attr( $term->slug ) . '" ' . selected( $option_is_set, true, false ) . '>' . esc_html( $term->name ) . '</option>'; echo '<option value="' . esc_attr( urldecode( $term->slug ) ) . '" ' . selected( $option_is_set, true, false ) . '>' . esc_html( $term->name ) . '</option>';
} }
echo '</select>'; echo '</select>';

View File

@ -10,6 +10,8 @@
"license": "GPL-3.0+", "license": "GPL-3.0+",
"main": "Gruntfile.js", "main": "Gruntfile.js",
"scripts": { "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": "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: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" "test:single": "cross-env NODE_CONFIG_DIR='./tests/e2e-tests/config' BABEL_ENV=commonjs mocha --compilers js:babel-register"
@ -45,7 +47,7 @@
"istanbul": "^1.0.0-alpha", "istanbul": "^1.0.0-alpha",
"mocha": "^3.0.2", "mocha": "^3.0.2",
"stylelint": "~8.2.0", "stylelint": "~8.2.0",
"wc-e2e-page-objects": "0.4.0" "wc-e2e-page-objects": "0.5.0"
}, },
"engines": { "engines": {
"node": ">=6.9.4", "node": ">=6.9.4",

View File

@ -11,14 +11,25 @@
<exclude-pattern>includes/gateways/simplify-commerce/includes/</exclude-pattern> <exclude-pattern>includes/gateways/simplify-commerce/includes/</exclude-pattern>
<exclude-pattern>includes/libraries/</exclude-pattern> <exclude-pattern>includes/libraries/</exclude-pattern>
<exclude-pattern>includes/api/legacy/</exclude-pattern> <exclude-pattern>includes/api/legacy/</exclude-pattern>
<exclude-pattern>*/node_modules/*</exclude-pattern>
<exclude-pattern>*/vendor/*</exclude-pattern>
<!-- Configs -->
<config name="minimum_supported_wp_version" value="4.7" />
<config name="testVersion" value="5.2-"/>
<!-- Rules -->
<rule ref="PHPCompatibility"/> <rule ref="PHPCompatibility"/>
<rule ref="WordPress"> <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.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>
<rule ref="WordPress.VIP.ValidatedSanitizedInput"> <rule ref="WordPress.VIP.ValidatedSanitizedInput">
<properties> <properties>
<property name="customSanitizingFunctions" type="array" value="wc_clean,wc_sanitize_tooltip,wc_format_decimal,wc_stock_amount" /> <property name="customSanitizingFunctions" type="array" value="wc_clean,wc_sanitize_tooltip,wc_format_decimal,wc_stock_amount" />
@ -28,5 +39,13 @@
<properties> <properties>
<property name="customEscapingFunctions" type="array" value="wc_help_tip,wc_sanitize_tooltip" /> <property name="customEscapingFunctions" type="array" value="wc_help_tip,wc_sanitize_tooltip" />
</properties> </properties>
</rule> </rule>
<rule ref="WordPress.WP.I18n">
<properties>
<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> </ruleset>

View File

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

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
if [[ $TRAVIS_PHP_VERSION == '7.1' ]]; then if [[ ${RUN_PHPCS} == 1 ]]; then
CHANGED_FILES=`git diff --name-only --diff-filter=ACMR $TRAVIS_COMMIT_RANGE | grep \\\\.php | awk '{print}' ORS=' '` CHANGED_FILES=`git diff --name-only --diff-filter=ACMR $TRAVIS_COMMIT_RANGE | grep \\\\.php | awk '{print}' ORS=' '`
IGNORE="tests/cli/,apigen/,includes/gateways/simplify-commerce/includes/,includes/libraries/,includes/api/legacy/" IGNORE="tests/cli/,apigen/,includes/gateways/simplify-commerce/includes/,includes/libraries/,includes/api/legacy/"

View File

@ -3,24 +3,16 @@
if [ $1 == 'before' ]; then 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
# Remove Xdebug from PHP runtime for all PHP version except 7.1 to speed up builds. # 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. # 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 if [[ ${RUN_CODE_COVERAGE} != 1 ]]; then
phpenv config-rm xdebug.ini phpenv config-rm xdebug.ini
fi fi
if [[ ${RUN_PHPCS} == 1 ]]; then
composer install
fi
fi fi
if [ $1 == 'after' ]; then if [ $1 == 'after' ]; then

View File

@ -12,7 +12,8 @@ let manager;
let driver; let driver;
test.describe( 'Cart page', function() { test.describe( 'Cart page', function() {
test.before( 'open browser', function() { // open browser
test.before( function() {
this.timeout( config.get( 'startBrowserTimeoutMs' ) ); this.timeout( config.get( 'startBrowserTimeoutMs' ) );
manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } ); manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } );
@ -93,7 +94,7 @@ test.describe( 'Cart page', function() {
); );
} ); } );
test.it( 'should go to the checkout page when "Proceed to Chcekout" is clicked', () => { test.it( 'should go to the checkout page when "Proceed to Checkout" is clicked', () => {
const cartPage = new CartPage( driver, { url: manager.getPageUrl( '/cart' ) } ); const cartPage = new CartPage( driver, { url: manager.getPageUrl( '/cart' ) } );
const checkoutPage = cartPage.checkout(); const checkoutPage = cartPage.checkout();
@ -104,7 +105,8 @@ test.describe( 'Cart page', function() {
); );
} ); } );
test.after( 'quit browser', () => { // quit browser
test.after( () => {
manager.quitBrowser(); manager.quitBrowser();
} ); } );
} ); } );

View File

@ -26,7 +26,8 @@ let manager;
let driver; let driver;
test.describe( 'Checkout Page', function() { test.describe( 'Checkout Page', function() {
test.before( 'open browser', function() { // open browser
test.before( function() {
this.timeout( config.get( 'startBrowserTimeoutMs' ) ); this.timeout( config.get( 'startBrowserTimeoutMs' ) );
manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } ); manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } );
@ -148,7 +149,8 @@ test.describe( 'Checkout Page', function() {
); );
} ); } );
test.after( 'quit browser', () => { // quit browser
test.after( () => {
manager.quitBrowser(); manager.quitBrowser();
} ); } );
} ); } );

View File

@ -16,7 +16,8 @@ let manager;
let driver; let driver;
test.describe( 'Single Product Page', function() { test.describe( 'Single Product Page', function() {
test.before( 'open browser', function() { // open browser
test.before( function() {
this.timeout( config.get( 'startBrowserTimeoutMs' ) ); this.timeout( config.get( 'startBrowserTimeoutMs' ) );
manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } ); manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } );
@ -52,7 +53,8 @@ test.describe( 'Single Product Page', function() {
assert.eventually.equal( cartPage.hasItem( 'Hoodie - Green' ), true ); assert.eventually.equal( cartPage.hasItem( 'Hoodie - Green' ), true );
} ); } );
test.after( 'quit browser', () => { // quit browser
test.after( () => {
manager.quitBrowser(); manager.quitBrowser();
} ); } );
} ); } );

View File

@ -12,7 +12,8 @@ let manager;
let driver; let driver;
test.describe( 'Add New Coupon Page', function() { test.describe( 'Add New Coupon Page', function() {
test.before( 'open browser', function() { // open browser
test.before( function() {
this.timeout( config.get( 'startBrowserTimeoutMs' ) ); this.timeout( config.get( 'startBrowserTimeoutMs' ) );
manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } ); manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } );
@ -45,7 +46,8 @@ test.describe( 'Add New Coupon Page', function() {
assert.eventually.ok( couponPage.hasNotice( 'Coupon updated.' ) ); assert.eventually.ok( couponPage.hasNotice( 'Coupon updated.' ) );
} ); } );
test.after( 'quit browser', () => { // quit browser
test.after( () => {
manager.quitBrowser(); manager.quitBrowser();
} ); } );
} ); } );

View File

@ -12,7 +12,8 @@ let manager;
let driver; let driver;
test.describe( 'Add New Order Page', function() { test.describe( 'Add New Order Page', function() {
test.before( 'open browser', function() { // open browser
test.before( function() {
this.timeout( config.get( 'startBrowserTimeoutMs' ) ); this.timeout( config.get( 'startBrowserTimeoutMs' ) );
manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } ); manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } );
@ -46,7 +47,8 @@ test.describe( 'Add New Order Page', function() {
assert.eventually.ok( orderNotes.hasNote( 'Order status changed from Pending payment to Processing.' ) ); assert.eventually.ok( orderNotes.hasNote( 'Order status changed from Pending payment to Processing.' ) );
} ); } );
test.after( 'quit browser', () => { // quit browser
test.after( () => {
manager.quitBrowser(); manager.quitBrowser();
} ); } );
} ); } );

View File

@ -13,7 +13,8 @@ let manager;
let driver; let driver;
test.describe( 'Add New Product Page', function() { test.describe( 'Add New Product Page', function() {
test.before( 'open browser', function() { // open browser
test.before( function() {
this.timeout( config.get( 'startBrowserTimeoutMs' ) ); this.timeout( config.get( 'startBrowserTimeoutMs' ) );
manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } ); manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } );
@ -24,7 +25,8 @@ test.describe( 'Add New Product Page', function() {
this.timeout( config.get( 'mochaTimeoutMs' ) ); this.timeout( config.get( 'mochaTimeoutMs' ) );
test.before( 'login', () => { // login
test.before( () => {
const wpLogin = new WPLogin( driver, { url: manager.getPageUrl( '/wp-login.php' ) } ); const wpLogin = new WPLogin( driver, { url: manager.getPageUrl( '/wp-login.php' ) } );
wpLogin.login( config.get( 'users.admin.username' ), config.get( 'users.admin.password' ) ); wpLogin.login( config.get( 'users.admin.username' ), config.get( 'users.admin.password' ) );
} ); } );
@ -121,7 +123,8 @@ test.describe( 'Add New Product Page', function() {
assert.eventually.ok( product.hasNotice( '1 product moved to the Trash.' ) ); assert.eventually.ok( product.hasNotice( '1 product moved to the Trash.' ) );
} ); } );
test.after( 'quit browser', () => { // quit browser
test.after( () => {
manager.quitBrowser(); manager.quitBrowser();
} ); } );
} ); } );

View File

@ -13,7 +13,8 @@ let manager;
let driver; let driver;
test.describe( 'WooCommerce General Settings', function() { test.describe( 'WooCommerce General Settings', function() {
test.before( 'open browser', function() { // open browser
test.before( function() {
this.timeout( config.get( 'startBrowserTimeoutMs' ) ); this.timeout( config.get( 'startBrowserTimeoutMs' ) );
manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } ); manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } );
@ -24,7 +25,8 @@ test.describe( 'WooCommerce General Settings', function() {
this.timeout( config.get( 'mochaTimeoutMs' ) ); this.timeout( config.get( 'mochaTimeoutMs' ) );
test.before( 'login', () => { // login
test.before( () => {
const wpLogin = new WPLogin( driver, { url: manager.getPageUrl( '/wp-login.php' ) } ); const wpLogin = new WPLogin( driver, { url: manager.getPageUrl( '/wp-login.php' ) } );
wpLogin.login( config.get( 'users.admin.username' ), config.get( 'users.admin.password' ) ); wpLogin.login( config.get( 'users.admin.username' ), config.get( 'users.admin.password' ) );
} ); } );
@ -64,7 +66,8 @@ test.describe( 'WooCommerce General Settings', function() {
assert.eventually.ok( settings.hasNotice( 'Your settings have been saved.' ) ); assert.eventually.ok( settings.hasNotice( 'Your settings have been saved.' ) );
} ); } );
test.after( 'quit browser', () => { // quit browser
test.after( () => {
manager.quitBrowser(); manager.quitBrowser();
} ); } );
} ); } );

View File

@ -13,7 +13,8 @@ let manager;
let driver; let driver;
test.describe( 'WooCommerce Products > Downloadable Products Settings', function() { test.describe( 'WooCommerce Products > Downloadable Products Settings', function() {
test.before( 'open browser', function() { // open browser
test.before( function() {
this.timeout( config.get( 'startBrowserTimeoutMs' ) ); this.timeout( config.get( 'startBrowserTimeoutMs' ) );
manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } ); manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } );
@ -24,7 +25,8 @@ test.describe( 'WooCommerce Products > Downloadable Products Settings', function
this.timeout( config.get( 'mochaTimeoutMs' ) ); this.timeout( config.get( 'mochaTimeoutMs' ) );
test.before( 'login', () => { // login
test.before( () => {
const wpLogin = new WPLogin( driver, { url: manager.getPageUrl( '/wp-login.php' ) } ); const wpLogin = new WPLogin( driver, { url: manager.getPageUrl( '/wp-login.php' ) } );
wpLogin.login( config.get( 'users.admin.username' ), config.get( 'users.admin.password' ) ); wpLogin.login( config.get( 'users.admin.username' ), config.get( 'users.admin.password' ) );
} ); } );
@ -49,7 +51,8 @@ test.describe( 'WooCommerce Products > Downloadable Products Settings', function
assert.eventually.ok( settings.hasNotice( 'Your settings have been saved.' ) ); assert.eventually.ok( settings.hasNotice( 'Your settings have been saved.' ) );
} ); } );
test.after( 'quit browser', () => { // quit browser
test.after( () => {
manager.quitBrowser(); manager.quitBrowser();
} ); } );
} ); } );

View File

@ -13,7 +13,8 @@ let manager;
let driver; let driver;
test.describe( 'WooCommerce Tax Settings', function() { test.describe( 'WooCommerce Tax Settings', function() {
test.before( 'open browser', function() { // open browser
test.before( function() {
this.timeout( config.get( 'startBrowserTimeoutMs' ) ); this.timeout( config.get( 'startBrowserTimeoutMs' ) );
manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } ); manager = new WebDriverManager( 'chrome', { baseUrl: config.get( 'url' ) } );
@ -24,7 +25,8 @@ test.describe( 'WooCommerce Tax Settings', function() {
this.timeout( config.get( 'mochaTimeoutMs' ) ); this.timeout( config.get( 'mochaTimeoutMs' ) );
test.before( 'login', () => { // login
test.before( () => {
const wpLogin = new WPLogin( driver, { url: manager.getPageUrl( '/wp-login.php' ) } ); const wpLogin = new WPLogin( driver, { url: manager.getPageUrl( '/wp-login.php' ) } );
wpLogin.login( config.get( 'users.admin.username' ), config.get( 'users.admin.password' ) ); wpLogin.login( config.get( 'users.admin.username' ), config.get( 'users.admin.password' ) );
} ); } );
@ -93,7 +95,8 @@ test.describe( 'WooCommerce Tax Settings', function() {
assert.eventually.ifError( settings.hasSubTab( 'Fancy rates' ) ); assert.eventually.ifError( settings.hasSubTab( 'Fancy rates' ) );
} ); } );
test.after( 'quit browser', () => { // quit browser
test.after( () => {
manager.quitBrowser(); manager.quitBrowser();
} ); } );
} ); } );

View File

@ -81,6 +81,21 @@ class WC_Unit_Test_Case extends WP_UnitTestCase {
$this->assertInstanceOf( 'WP_Error', $actual, $message ); $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. * Backport assertNotFalse to PHPUnit 3.6.12 which only runs in PHP 5.2.
* *

View File

@ -16,15 +16,15 @@ class WC_Helper_Order {
$order = wc_get_order( $order_id ); $order = wc_get_order( $order_id );
// Delete all products in the order // Delete all products in the order.
foreach ( $order->get_items() as $item ) : foreach ( $order->get_items() as $item ) {
WC_Helper_Product::delete_product( $item['product_id'] ); WC_Helper_Product::delete_product( $item['product_id'] );
endforeach; }
WC_Helper_Shipping::delete_simple_flat_rate(); WC_Helper_Shipping::delete_simple_flat_rate();
// Delete the order post // Delete the order post.
wp_delete_post( $order_id, true ); $order->delete( true );
} }
/** /**

View File

@ -267,12 +267,13 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case {
/** /**
* Tests updating an order. * Tests updating an order.
*
* @since 3.0.0 * @since 3.0.0
*/ */
public function test_update_order() { public function test_update_order() {
wp_set_current_user( $this->user ); wp_set_current_user( $this->user );
$order = WC_Helper_Order::create_order(); $order = WC_Helper_Order::create_order();
$request = new WP_REST_Request( 'POST', '/wc/v2/orders/' . $order->get_id() ); $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() );
$request->set_body_params( array( $request->set_body_params( array(
'payment_method' => 'test-update', 'payment_method' => 'test-update',
'billing' => array( 'billing' => array(
@ -288,17 +289,56 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case {
$this->assertEquals( 'Fish', $data['billing']['first_name'] ); $this->assertEquals( 'Fish', $data['billing']['first_name'] );
$this->assertEquals( 'Face', $data['billing']['last_name'] ); $this->assertEquals( 'Face', $data['billing']['last_name'] );
wp_delete_post( $order->get_id(), true ); WC_Helper_Order::delete_order( $order->get_id() );
}
/**
* Tests updating an order and removing items.
*
* @since 3.0.0
*/
public function test_update_order_remove_items() {
wp_set_current_user( $this->user );
$order = WC_Helper_Order::create_order();
$fee = new WC_Order_Item_Fee();
$fee->set_props( array(
'name' => 'Some Fee',
'tax_status' => 'taxable',
'total' => '100',
'tax_class' => '',
) );
$order->add_item( $fee );
$order->save();
$request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() );
$fee_data = current( $order->get_items( 'fee' ) );
$request->set_body_params( array(
'fee_lines' => array(
array(
'id' => $fee_data->get_id(),
'name' => null,
),
),
) );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$this->assertEquals( 200, $response->get_status() );
$this->assertTrue( empty( $data['fee_lines'] ) );
WC_Helper_Order::delete_order( $order->get_id() );
} }
/** /**
* Tests updating an order without the correct permissions. * Tests updating an order without the correct permissions.
*
* @since 3.0.0 * @since 3.0.0
*/ */
public function test_update_order_without_permission() { public function test_update_order_without_permission() {
wp_set_current_user( 0 ); wp_set_current_user( 0 );
$order = WC_Helper_Order::create_order(); $order = WC_Helper_Order::create_order();
$request = new WP_REST_Request( 'POST', '/wc/v2/orders/' . $order->get_id() ); $request = new WP_REST_Request( 'PUT', '/wc/v2/orders/' . $order->get_id() );
$request->set_body_params( array( $request->set_body_params( array(
'payment_method' => 'test-update', 'payment_method' => 'test-update',
'billing' => array( 'billing' => array(
@ -308,6 +348,7 @@ class WC_Tests_API_Orders extends WC_REST_Unit_Test_Case {
) ); ) );
$response = $this->server->dispatch( $request ); $response = $this->server->dispatch( $request );
$this->assertEquals( 401, $response->get_status() ); $this->assertEquals( 401, $response->get_status() );
WC_Helper_Order::delete_order( $order->get_id() );
} }
/** /**

View File

@ -69,11 +69,41 @@ class WC_Tests_Customer_Functions extends WC_Unit_Test_Case {
$order2 = new WC_Order; $order2 = new WC_Order;
$order2->save(); $order2->save();
// Test download permissions
$prod_download = new WC_Product_Download;
$prod_download->set_file( plugin_dir_url( __FILE__ ) . '/assets/images/help.png' );
$prod_download->set_id( 'download' );
$product = new WC_Product_Simple;
$product->set_downloadable( 'yes' );
$product->set_downloads( array( $prod_download ) );
$product->save();
$order3 = new WC_Order;
$item = new WC_Order_Item_Product();
$item->set_props( array(
'product' => $product,
'quantity' => 1,
) );
$order3->set_billing_email( 'test@example.com' );
$order3->set_status( 'completed' );
$order3->add_item( $item );
$order3->save();
$downloads = wc_get_customer_available_downloads( $customer_id );
$this->assertEquals( 0, count( $downloads ) );
// Link orders that haven't been linked. // Link orders that haven't been linked.
$linked = wc_update_new_customer_past_orders( $customer_id ); $linked = wc_update_new_customer_past_orders( $customer_id );
$this->assertEquals( 1, $linked ); $this->assertEquals( 2, $linked );
$order1 = wc_get_order( $order1->get_id() ); $order1 = wc_get_order( $order1->get_id() );
$this->assertEquals( $customer_id, $order1->get_customer_id() ); $this->assertEquals( $customer_id, $order1->get_customer_id() );
$order3 = wc_get_order( $order3->get_id() );
$this->assertEquals( $customer_id, $order3->get_customer_id() );
// Test download permissions.
$downloads = wc_get_customer_available_downloads( $customer_id );
$this->assertEquals( 1, count( $downloads ) );
// Don't link linked orders again. // Don't link linked orders again.
$linked = wc_update_new_customer_past_orders( $customer_id ); $linked = wc_update_new_customer_past_orders( $customer_id );

View File

@ -1656,6 +1656,21 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case {
$this->assertEquals( 4, $object->get_remaining_refund_items() ); $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. * Test apply_coupon and remove_coupon with a fixed discount coupon.
* @since 3.2.0 * @since 3.2.0

View File

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

View File

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