Merge remote-tracking branch 'woothemes/master'

This commit is contained in:
Job 2016-06-13 15:31:46 +02:00
commit c6b08297e6
25 changed files with 270 additions and 166 deletions

View File

@ -1,5 +1,19 @@
## EXPLANATION OF THE ISSUE
<!-- What happens, under which versions, under what conditions, when, and what were you expecting instead. -->
## STEPS TO REPRODUCE THE ISSUE
<!-- 1. List steps to reproduce your issue so we can replicate. -->
## SYSTEM STATUS REPORT
```
Grab the system status report from WooCommerce > System Status and paste it here.
```
<!--
PLEASE NOTE:
BEFORE POSTING YOUR ISSUE
- These comments won't show up when you submit the issue.
- Try to add as much detail as possible. Be specific!
- GitHub issues ARE NOT FOR SUPPORT! If you have questions, use the either:
@ -8,22 +22,8 @@ PLEASE NOTE:
- If you're requesting a new feature, explain why you'd like it to be added.
- Search this repository (top of the page) for the issue and it has not been fixed or reported already.
And before logging BUGS, ensure you:
Before logging BUGS, ensure you:
- Use the latest stable release of WooCommerce.
- Disabled all plugins to ensure it's a core bug and not a plugin issue.
- Switched to Twenty Twelve theme to ensure it's a core bug and not a theme issue.
-->
## EXPLANATION OF THE ISSUE
What happens, under which versions, under what conditions, when, and what were you expecting instead.
## STEPS TO REPRODUCE THE ISSUE
1. List steps to reproduce your issue so we can replicate.
## SYSTEM STATUS REPORT
```
Grab the system status report from WooCommerce > System Status and paste it here.
```

View File

@ -90,7 +90,6 @@
$save_button.on( 'click', { view: this }, this.onSubmit );
$( document.body ).on( 'click', '.add_shipping_method:not(.disabled)', { view: this }, this.onAddShippingMethod );
$( document.body ).on( 'click', '.wc-shipping-zone-add', { view: this }, this.onAddNewRow );
$( document.body ).on( 'click', '.wc-shipping-zone-save-changes', { view: this }, this.onSubmit );
$( document.body ).on( 'wc_backbone_modal_response', this.onAddShippingMethodSubmitted );
$( document.body ).on( 'change', '.wc-shipping-zone-method-selector select', this.onChangeShippingMethodSelector );
},

File diff suppressed because one or more lines are too long

View File

@ -30,7 +30,6 @@ class WC_Admin_Notices {
private static $core_notices = array(
'install' => 'install_notice',
'update' => 'update_notice',
'updating' => 'updating_notice',
'template_files' => 'template_file_check_notice',
'theme_support' => 'theme_check_notice',
'legacy_shipping' => 'legacy_shipping_notice',
@ -190,15 +189,13 @@ class WC_Admin_Notices {
* If we need to update, include a message with the update button.
*/
public static function update_notice() {
include( 'views/html-notice-update.php' );
}
/**
* If we are updating, show progress.
*/
public static function updating_notice() {
if ( version_compare( get_option( 'woocommerce_db_version' ), WC_VERSION, '<' ) ) {
$updater = new WC_Background_Updater();
if ( ! $updater->is_updating() ) {
include( 'views/html-notice-update.php' );
} else {
include( 'views/html-notice-updating.php' );
}
} else {
include( 'views/html-notice-updated.php' );
}

View File

@ -167,8 +167,6 @@ class WC_Admin_Permalink_Settings {
return;
}
global $wpdb;
// We need to save the options ourselves; settings api does not trigger save for the permalinks page.
if ( isset( $_POST['permalink_structure'] ) ) {
$permalinks = get_option( 'woocommerce_permalinks' );

View File

@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
<div id="message" class="updated woocommerce-message wc-connect">
<a class="woocommerce-message-close notice-dismiss" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wc-hide-notice', 'updating' ), 'woocommerce_hide_notices_nonce', '_wc_notice_nonce' ) ); ?>"><?php _e( 'Dismiss', 'woocommerce' ); ?></a>
<a class="woocommerce-message-close notice-dismiss" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wc-hide-notice', 'update', remove_query_arg( 'do_update_woocommerce' ) ), 'woocommerce_hide_notices_nonce', '_wc_notice_nonce' ) ); ?>"><?php _e( 'Dismiss', 'woocommerce' ); ?></a>
<p><?php _e( 'WooCommerce data update complete. Thank you for updating to the latest version!', 'woocommerce' ); ?></p>
</div>

View File

@ -502,10 +502,12 @@ class WC_REST_Products_Controller extends WC_REST_Posts_Controller {
continue;
}
$post_data = get_post( $variation->get_variation_id() );
$variations[] = array(
'id' => $variation->get_variation_id(),
'date_created' => wc_rest_prepare_date_response( $variation->get_post_data()->post_date_gmt ),
'date_modified' => wc_rest_prepare_date_response( $variation->get_post_data()->post_modified_gmt ),
'date_created' => wc_rest_prepare_date_response( $post_data->post_date_gmt ),
'date_modified' => wc_rest_prepare_date_response( $post_data->post_modified_gmt ),
'permalink' => $variation->get_permalink(),
'sku' => $variation->get_sku(),
'price' => $variation->get_price(),

View File

@ -348,13 +348,16 @@ class WC_API_Products extends WC_API_Resource {
$variation = $product->get_child( $child_id );
if ( ! $variation->exists() )
if ( ! $variation->exists() ) {
continue;
}
$post_data = get_post( $variation->get_variation_id() );
$variations[] = array(
'id' => $variation->get_variation_id(),
'created_at' => $this->server->format_datetime( $variation->get_post_data()->post_date_gmt ),
'updated_at' => $this->server->format_datetime( $variation->get_post_data()->post_modified_gmt ),
'created_at' => $this->server->format_datetime( $post_data->post_date_gmt ),
'updated_at' => $this->server->format_datetime( $post_data->post_modified_gmt ),
'downloadable' => $variation->is_downloadable(),
'virtual' => $variation->is_virtual(),
'permalink' => $variation->get_permalink(),

View File

@ -159,6 +159,8 @@ class WC_API_Customers extends WC_API_Resource {
ORDER BY posts.ID DESC
" );
$roles = array_values( $customer->roles );
$customer_data = array(
'id' => $customer->ID,
'created_at' => $this->server->format_datetime( $customer->user_registered ),
@ -166,7 +168,7 @@ class WC_API_Customers extends WC_API_Resource {
'first_name' => $customer->first_name,
'last_name' => $customer->last_name,
'username' => $customer->user_login,
'role' => $customer->roles[0],
'role' => $roles[0],
'last_order_id' => is_object( $last_order ) ? $last_order->id : null,
'last_order_date' => is_object( $last_order ) ? $this->server->format_datetime( $last_order->post_date_gmt ) : null,
'orders_count' => wc_get_customer_order_count( $customer->ID ),

View File

@ -740,10 +740,12 @@ class WC_API_Products extends WC_API_Resource {
continue;
}
$post_data = get_post( $variation->get_variation_id() );
$variations[] = array(
'id' => $variation->get_variation_id(),
'created_at' => $this->server->format_datetime( $variation->get_post_data()->post_date_gmt ),
'updated_at' => $this->server->format_datetime( $variation->get_post_data()->post_modified_gmt ),
'created_at' => $this->server->format_datetime( $post_data->post_date_gmt ),
'updated_at' => $this->server->format_datetime( $post_data->post_modified_gmt ),
'downloadable' => $variation->is_downloadable(),
'virtual' => $variation->is_virtual(),
'permalink' => $variation->get_permalink(),
@ -1834,10 +1836,10 @@ class WC_API_Products extends WC_API_Resource {
}
/**
* Get product image as attachment
* Sets product image as attachment and returns the attachment ID.
*
* @since 2.2
* @param integer $upload
* @param array $upload
* @param int $id
* @return int
*/

View File

@ -159,6 +159,8 @@ class WC_API_Customers extends WC_API_Resource {
ORDER BY posts.ID DESC
" );
$roles = array_values( $customer->roles );
$customer_data = array(
'id' => $customer->ID,
'created_at' => $this->server->format_datetime( $customer->user_registered ),
@ -167,7 +169,7 @@ class WC_API_Customers extends WC_API_Resource {
'first_name' => $customer->first_name,
'last_name' => $customer->last_name,
'username' => $customer->user_login,
'role' => $customer->roles[0],
'role' => $roles[0],
'last_order_id' => is_object( $last_order ) ? $last_order->id : null,
'last_order_date' => is_object( $last_order ) ? $this->server->format_datetime( $last_order->post_date_gmt ) : null,
'orders_count' => wc_get_customer_order_count( $customer->ID ),

View File

@ -1199,10 +1199,12 @@ class WC_API_Products extends WC_API_Resource {
continue;
}
$post_data = get_post( $variation->get_variation_id() );
$variations[] = array(
'id' => $variation->get_variation_id(),
'created_at' => $this->server->format_datetime( $variation->get_post_data()->post_date_gmt ),
'updated_at' => $this->server->format_datetime( $variation->get_post_data()->post_modified_gmt ),
'created_at' => $this->server->format_datetime( $post_data->post_date_gmt ),
'updated_at' => $this->server->format_datetime( $post_data->post_modified_gmt ),
'downloadable' => $variation->is_downloadable(),
'virtual' => $variation->is_virtual(),
'permalink' => $variation->get_permalink(),
@ -2395,7 +2397,7 @@ class WC_API_Products extends WC_API_Resource {
* Sets product image as attachment and returns the attachment ID.
*
* @since 2.2
* @param integer $upload
* @param array $upload
* @param int $id
* @return int
*/

View File

@ -40,8 +40,6 @@ class WC_Background_Updater extends WP_Background_Process {
* Updater will still run via cron job if this fails for any reason.
*/
public function dispatch() {
WC_Admin_Notices::add_notice( 'updating' );
$dispatched = parent::dispatch();
if ( is_wp_error( $dispatched ) ) {
@ -50,6 +48,15 @@ class WC_Background_Updater extends WP_Background_Process {
}
}
/**
* Schedule event
*/
protected function schedule_event() {
if ( ! wp_next_scheduled( $this->cron_hook_identifier ) ) {
wp_schedule_event( time() + 10, $this->cron_interval_identifier, $this->cron_hook_identifier );
}
}
/**
* Error shown when the updater cannot dispatch.
*/
@ -57,6 +64,14 @@ class WC_Background_Updater extends WP_Background_Process {
echo '<div class="error"><p>' . __( 'Unable to dispatch WooCommerce updater:', 'woocommerce' ) . ' ' . esc_html( $this->error ) . '</p></div>';
}
/**
* Is the updater running?
* @return boolean
*/
public function is_updating() {
return false === $this->is_queue_empty();
}
/**
* Task
*
@ -96,7 +111,6 @@ class WC_Background_Updater extends WP_Background_Process {
*/
protected function complete() {
$logger = new WC_Logger();
$logger->add( 'wc_db_updates', 'Data update complete' );
WC_Install::update_db_version();
parent::complete();

View File

@ -114,7 +114,7 @@ class WC_Install {
public static function install_actions() {
if ( ! empty( $_GET['do_update_woocommerce'] ) ) {
self::update();
WC_Admin_Notices::remove_notice( 'update' );
WC_Admin_Notices::add_notice( 'update' );
}
}

View File

@ -90,7 +90,7 @@ class WC_Shipping_Zones {
$wc_shipping = WC_Shipping::instance();
$allowed_classes = $wc_shipping->get_shipping_method_class_names();
if ( in_array( $raw_shipping_method->method_id, array_keys( $allowed_classes ) ) ) {
if ( ! empty( $raw_shipping_method ) && in_array( $raw_shipping_method->method_id, array_keys( $allowed_classes ) ) ) {
$class_name = $allowed_classes[ $raw_shipping_method->method_id ];
if ( is_object( $class_name ) ) {
$class_name = get_class( $class_name );

View File

@ -267,9 +267,6 @@ class WC_Shortcodes {
ob_start();
// Reset loop/columns globals when starting a new loop
$woocommerce_loop['loop'] = $woocommerce_loop['column'] = '';
if ( $product_categories ) {
woocommerce_product_loop_start();

View File

@ -291,8 +291,14 @@ class WC_Tax {
if ( $postcode_ranges ) {
$matches = wc_postcode_location_matcher( $postcode, $postcode_ranges, 'tax_rate_id', 'location_code' );
$postcode_search = array_unique( array_merge( $postcode_search, array_values( $matches ) ) );
if ( ! empty( $matches ) ) {
foreach ( $matches as $matched_postcodes ) {
$postcode_search = array_merge( $postcode_search, $matched_postcodes );
}
}
}
$postcode_search = array_unique( $postcode_search );
/**
* Location matching criteria - ORed

View File

@ -2057,10 +2057,10 @@ class WC_CLI_Product extends WC_CLI_Command {
}
/**
* Get product image as attachment
* Sets product image as attachment and returns the attachment ID.
*
* @since 2.5.0
* @param int $upload
* @param array $upload
* @param int $id
* @return int
*/

View File

@ -34,6 +34,7 @@ class WC_Email_Customer_On_Hold_Order extends WC_Email {
// Triggers for this email
add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'trigger' ) );
add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $this, 'trigger' ) );
// Call parent constructor
parent::__construct();

View File

@ -1,25 +1,54 @@
<?php
/**
* WP Async Request
*
* @package WP-Background-Processing
*/
if ( ! class_exists( 'WP_Async_Request' ) ) {
/**
* Abstract WP_Async_Request class.
*
* @abstract
*/
abstract class WP_Async_Request {
/**
* Prefix
*
* (default value: 'wp')
*
* @var string
* @access protected
*/
protected $prefix = 'wp';
/**
* Action
*
* (default value: 'async_request')
*
* @var string
* @access protected
*/
protected $action = 'async_request';
/**
* @var string
* Identifier
*
* @var mixed
* @access protected
*/
protected $identifier;
/**
* Data
*
* (default value: array())
*
* @var array
* @access protected
*/
protected $data = array();
@ -36,7 +65,7 @@ if ( ! class_exists( 'WP_Async_Request' ) ) {
/**
* Set data used during the request
*
* @param array $data
* @param array $data Data.
*
* @return $this
*/

View File

@ -1,27 +1,53 @@
<?php
/**
* WP Background Process
*
* @package WP-Background-Processing
*/
if ( ! class_exists( 'WP_Background_Process' ) ) {
/**
* Abstract WP_Background_Process class.
*
* @abstract
* @extends WP_Async_Request
*/
abstract class WP_Background_Process extends WP_Async_Request {
/**
* @var
* Action
*
* (default value: 'background_process')
*
* @var string
* @access protected
*/
protected $action = 'background_process';
/**
* Start time of current process
* Start time of current process.
*
* (default value: 0)
*
* @var int
* @access protected
*/
protected $start_time = 0;
/**
* @var string
* Cron_hook_identifier
*
* @var mixed
* @access protected
*/
protected $cron_hook_identifier;
/**
* @var string
* Cron_interval_identifier
*
* @var mixed
* @access protected
*/
protected $cron_interval_identifier;
@ -41,20 +67,21 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
/**
* Dispatch
*
* @return array|WP_Error
* @access public
* @return void
*/
public function dispatch() {
// Schedule the cron healthcheck
// Schedule the cron healthcheck.
$this->schedule_event();
// Perform remote post
// Perform remote post.
return parent::dispatch();
}
/**
* Push to queue
*
* @param mixed $data
* @param mixed $data Data.
*
* @return $this
*/
@ -82,8 +109,8 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
/**
* Update queue
*
* @param string $key
* @param array $data
* @param string $key Key.
* @param array $data Data.
*
* @return $this
*/
@ -98,7 +125,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
/**
* Delete queue
*
* @param string $key
* @param string $key Key.
*
* @return $this
*/
@ -114,7 +141,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
* Generates a unique key based on microtime. Queue items are
* given a unique key so that they can be merged upon save.
*
* @param int $length
* @param int $length Length.
*
* @return string
*/
@ -133,12 +160,12 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
*/
public function maybe_handle() {
if ( $this->is_process_running() ) {
// Background process already running
// Background process already running.
wp_die();
}
if ( $this->is_queue_empty() ) {
// No data to process
// No data to process.
wp_die();
}
@ -184,7 +211,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
*/
protected function is_process_running() {
if ( get_site_transient( $this->identifier . '_process_lock' ) ) {
// Process already running
// Process already running.
return true;
}
@ -199,7 +226,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
* defined in the time_exceeded() method.
*/
protected function lock_process() {
$this->start_time = time(); // Set start time of current process
$this->start_time = time(); // Set start time of current process.
$lock_duration = ( property_exists( $this, 'queue_lock_time' ) ) ? $this->queue_lock_time : 60; // 1 minute
$lock_duration = apply_filters( $this->identifier . '_queue_lock_time', $lock_duration );
@ -279,12 +306,12 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
}
if ( $this->time_exceeded() || $this->memory_exceeded() ) {
// Batch limits reached
// Batch limits reached.
break;
}
}
// Update or delete current batch
// Update or delete current batch.
if ( ! empty( $batch->data ) ) {
$this->update( $batch->key, $batch->data );
} else {
@ -294,7 +321,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
$this->unlock_process();
// Start next batch or complete process
// Start next batch or complete process.
if ( ! $this->is_queue_empty() ) {
$this->dispatch();
} else {
@ -333,12 +360,12 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
if ( function_exists( 'ini_get' ) ) {
$memory_limit = ini_get( 'memory_limit' );
} else {
// Sensible default
// Sensible default.
$memory_limit = '128M';
}
if ( ! $memory_limit || -1 == $memory_limit ) {
// Unlimited, set to 32GB
if ( ! $memory_limit || -1 === $memory_limit ) {
// Unlimited, set to 32GB.
$memory_limit = '32000M';
}
@ -346,7 +373,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
}
/**
* Time exceeded
* Time exceeded.
*
* Ensures the batch never exceeds a sensible time limit.
* A timeout limit of 30s is common on shared hosting.
@ -365,21 +392,21 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
}
/**
* Complete
* Complete.
*
* Override if applicable, but ensure that the below actions are
* performed, or, call parent::complete().
*/
protected function complete() {
// Unschedule the cron healthcheck
// Unschedule the cron healthcheck.
$this->clear_scheduled_event();
}
/**
* Schedule cron healthcheck
*
* @param $schedules
*
* @access public
* @param mixed $schedules Schedules.
* @return mixed
*/
public function schedule_cron_healthcheck( $schedules ) {
@ -406,12 +433,12 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
*/
public function handle_cron_healthcheck() {
if ( $this->is_process_running() ) {
// Background process already running
// Background process already running.
exit;
}
if ( $this->is_queue_empty() ) {
// No data to process
// No data to process.
$this->clear_scheduled_event();
exit;
}
@ -441,6 +468,23 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
}
}
/**
* Cancel Process
*
* Stop processing queue items, clear cronjob and delete batch.
*
*/
public function cancel_process() {
if ( ! $this->is_queue_empty() ) {
$batch = $this->get_batch();
$this->delete( $batch->key );
wp_clear_scheduled_hook( $this->cron_hook_identifier );
}
}
/**
* Task
*
@ -449,7 +493,7 @@ if ( ! class_exists( 'WP_Background_Process' ) ) {
* in the next pass through. Or, return false to remove the
* item from the queue.
*
* @param mixed $item Queue item to iterate over
* @param mixed $item Queue item to iterate over.
*
* @return mixed
*/

View File

@ -206,6 +206,9 @@ class WC_Shortcode_Checkout {
// Empty awaiting payment session
unset( WC()->session->order_awaiting_payment );
// Empty current cart
wc_empty_cart();
wc_get_template( 'checkout/thankyou.php', array( 'order' => $order ) );
}

View File

@ -1249,19 +1249,18 @@ function wc_get_wildcard_postcodes( $postcode ) {
* @since 2.6.0
* @param string $postcode Postcode you want to match against stored postcodes
* @param array $objects Array of postcode objects from Database
* @param string $object_compare_key DB column name for the ID.
* @param string $object_id_key DB column name for the ID.
* @param string $object_compare_key DB column name for the value.
* @param string $object_id_key
* @return array Array of matching object ID and values.
* @return array Array of matching object ID and matching values.
*/
function wc_postcode_location_matcher( $postcode, $objects, $object_id_key, $object_compare_key ) {
$postcode = wc_normalize_postcode( $postcode );
$wildcard_postcodes = array_map( 'wc_clean', wc_get_wildcard_postcodes( $postcode ) );
$postcodes = array_map( 'wc_normalize_postcode', wp_list_pluck( $objects, $object_compare_key, $object_id_key ) );
$matches = array();
foreach ( $postcodes as $object_id => $compare_against ) {
$compare = $postcode;
foreach ( $objects as $object ) {
$object_id = $object->$object_id_key;
$compare_against = $object->$object_compare_key;
// Handle postcodes containing ranges.
if ( strstr( $compare_against, '...' ) ) {
@ -1275,18 +1274,22 @@ function wc_postcode_location_matcher( $postcode, $objects, $object_id_key, $obj
// If the postcode is non-numeric, make it numeric.
if ( ! is_numeric( $min ) || ! is_numeric( $max ) ) {
$compare = wc_make_numeric_postcode( $compare );
$compare = wc_make_numeric_postcode( $postcode );
$min = str_pad( wc_make_numeric_postcode( $min ), strlen( $compare ), '0' );
$max = str_pad( wc_make_numeric_postcode( $max ), strlen( $compare ), '0' );
} else {
$compare = $postcode;
}
if ( $compare >= $min && $compare <= $max ) {
$matches[ $object_id ] = $compare_against;
$matches[ $object_id ] = isset( $matches[ $object_id ] ) ? $matches[ $object_id ]: array();
$matches[ $object_id ][] = $compare_against;
}
// Wildcard and standard comparison.
} elseif ( in_array( $compare_against, $wildcard_postcodes ) ) {
$matches[ $object_id ] = $compare_against;
$matches[ $object_id ] = isset( $matches[ $object_id ] ) ? $matches[ $object_id ]: array();
$matches[ $object_id ][] = $compare_against;
}
}

View File

@ -32,7 +32,7 @@ function wc_sanitize_taxonomy_name( $taxonomy ) {
* Cannot use wc_clean because it sometimes strips % chars and breaks the user's setting.
*
* @since 2.6.0
* @param string $taxonomy
* @param string $value
* @return string
*/
function wc_sanitize_permalink( $value ) {

View File

@ -95,7 +95,7 @@ do_action( 'woocommerce_before_add_to_cart_form' ); ?>
<?php do_action( 'woocommerce_before_add_to_cart_button' ); ?>
<button type="submit" class="single_add_to_cart_button button alt"><?php echo $product->single_add_to_cart_text(); ?></button>
<button type="submit" class="single_add_to_cart_button button alt"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></button>
<?php do_action( 'woocommerce_after_add_to_cart_button' ); ?>