Resolving conflicts with migration branch
This commit is contained in:
commit
62607a918c
|
@ -1,4 +1,5 @@
|
|||
/.* export-ignore
|
||||
bin export-ignore
|
||||
CODE_OF_CONDUCT.md export-ignore
|
||||
CHANGELOG.txt export-ignore
|
||||
composer.* export-ignore
|
||||
|
@ -9,3 +10,4 @@ phpcs.xml export-ignore
|
|||
phpunit.* export-ignore
|
||||
README.md export-ignore
|
||||
tests export-ignore
|
||||
renovate.json export-ignore
|
||||
|
|
|
@ -37,7 +37,10 @@ matrix:
|
|||
- name: "E2E tests"
|
||||
env: RUN_E2E=1
|
||||
script:
|
||||
- npm install
|
||||
- npm run build
|
||||
- docker-compose up -d
|
||||
- travis_retry bash tests/bin/run-e2e-CI.sh
|
||||
- name: "Unit tests code coverage"
|
||||
php: 7.3
|
||||
env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1
|
||||
|
@ -49,6 +52,8 @@ matrix:
|
|||
allow_failures:
|
||||
- php: 7.3
|
||||
env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1
|
||||
- php: 7.2
|
||||
env: WP_VERSION=latest WP_MULTISITE=0 RUN_E2E=1
|
||||
|
||||
before_script:
|
||||
- export PATH="$HOME/.composer/vendor/bin:$PATH"
|
||||
|
@ -71,7 +76,6 @@ before_script:
|
|||
script:
|
||||
- bash tests/bin/phpunit.sh
|
||||
- bash tests/bin/phpcs.sh
|
||||
- travis_retry bash tests/bin/run-e2e-CI.sh
|
||||
|
||||
after_script:
|
||||
- bash tests/bin/travis.sh after
|
||||
|
|
|
@ -229,7 +229,6 @@ module.exports = function( grunt ) {
|
|||
files: {
|
||||
src: [
|
||||
'**/*.php', // Include all files
|
||||
'!includes/libraries/**', // Exclude libraries/
|
||||
'!node_modules/**', // Exclude node_modules/
|
||||
'!tests/**', // Exclude tests/
|
||||
'!vendor/**', // Exclude vendor/
|
||||
|
|
|
@ -2,20 +2,20 @@
|
|||
* WooCommerce CSS Variables
|
||||
*/
|
||||
|
||||
$woocommerce: #a46497;
|
||||
$green: #7ad03a;
|
||||
$red: #a00;
|
||||
$orange: #ffba00;
|
||||
$blue: #2ea2cc;
|
||||
$woocommerce: #a46497 !default;
|
||||
$green: #7ad03a !default;
|
||||
$red: #a00 !default;
|
||||
$orange: #ffba00 !default;
|
||||
$blue: #2ea2cc !default;
|
||||
|
||||
$primary: #a46497; // Primary color for buttons (alt)
|
||||
$primarytext: desaturate(lighten($primary, 50%), 18%); // Text on primary color bg
|
||||
$primary: #a46497 !default; // Primary color for buttons (alt)
|
||||
$primarytext: desaturate(lighten($primary, 50%), 18%) !default; // Text on primary color bg
|
||||
|
||||
$secondary: desaturate(lighten($primary, 40%), 21%); // Secondary buttons
|
||||
$secondarytext: desaturate(darken($secondary, 60%), 21%); // Text on secondary color bg
|
||||
$secondary: desaturate(lighten($primary, 40%), 21%) !default; // Secondary buttons
|
||||
$secondarytext: desaturate(darken($secondary, 60%), 21%) !default; // Text on secondary color bg
|
||||
|
||||
$highlight: adjust-hue($primary, 150deg); // Prices, In stock labels, sales flash
|
||||
$highlightext: desaturate(lighten($highlight, 50%), 18%); // Text on highlight color bg
|
||||
$highlight: adjust-hue($primary, 150deg) !default; // Prices, In stock labels, sales flash
|
||||
$highlightext: desaturate(lighten($highlight, 50%), 18%) !default; // Text on highlight color bg
|
||||
|
||||
$contentbg: #fff; // Content BG - Tabs (active state)
|
||||
$subtext: #767676; // small, breadcrumbs etc
|
||||
$contentbg: #fff !default; // Content BG - Tabs (active state)
|
||||
$subtext: #767676 !default; // small, breadcrumbs etc
|
||||
|
|
|
@ -579,6 +579,7 @@
|
|||
}
|
||||
|
||||
#variable_product_options {
|
||||
|
||||
.form-row select {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
@ -636,6 +637,14 @@ mark.amount {
|
|||
}
|
||||
}
|
||||
|
||||
.branch-5-3 {
|
||||
|
||||
.woocommerce-help-tip {
|
||||
font-size: 1.2em;
|
||||
cursor: help;
|
||||
}
|
||||
}
|
||||
|
||||
h2 .woocommerce-help-tip {
|
||||
margin-top: -5px;
|
||||
margin-left: 0.25em;
|
||||
|
@ -2158,6 +2167,22 @@ ul.wc_coupon_list_block {
|
|||
}
|
||||
}
|
||||
|
||||
.branch-5-3 {
|
||||
|
||||
.widefat {
|
||||
|
||||
.column-wc_actions {
|
||||
|
||||
a.button {
|
||||
|
||||
&::after {
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.post-type-shop_order {
|
||||
|
||||
.tablenav .one-page .displaying-num {
|
||||
|
@ -3035,7 +3060,6 @@ table.wc_input_table {
|
|||
vertical-align: middle;
|
||||
|
||||
input {
|
||||
width: auto;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
@ -4099,6 +4123,84 @@ img.help_tip {
|
|||
}
|
||||
}
|
||||
|
||||
.branch-5-3 {
|
||||
|
||||
.woocommerce {
|
||||
|
||||
h2.wc-table-list-header {
|
||||
margin: 1em 0 0.35em 0;
|
||||
}
|
||||
|
||||
input + .subsubsub {
|
||||
margin: 8px 0 0;
|
||||
}
|
||||
|
||||
table.form-table {
|
||||
|
||||
// Give regular settings inputs a standard width and padding.
|
||||
textarea,
|
||||
input[type="text"],
|
||||
input[type="email"],
|
||||
input[type="number"],
|
||||
input[type="password"],
|
||||
input[type="datetime"],
|
||||
input[type="datetime-local"],
|
||||
input[type="date"],
|
||||
input[type="time"],
|
||||
input[type="week"],
|
||||
input[type="url"],
|
||||
input[type="tel"],
|
||||
input.regular-input {
|
||||
padding: 0 8px;
|
||||
|
||||
@media only screen and (max-width: 782px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
|
||||
@media only screen and (max-width: 782px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
th label {
|
||||
|
||||
img.help_tip,
|
||||
.woocommerce-help-tip {
|
||||
margin: -7px -24px 0 0;
|
||||
|
||||
@media only screen and (max-width: 782px) {
|
||||
right: auto;
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.forminp-color {
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.colorpickpreview {
|
||||
padding: 0;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
|
||||
font-size: 16px;
|
||||
border-radius: 4px;
|
||||
margin-right: 3px;
|
||||
|
||||
@media only screen and (max-width: 782px) {
|
||||
float: left;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce #tabs-wrap table a.remove {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
@ -4545,7 +4647,6 @@ img.help_tip {
|
|||
|
||||
.woocommerce_options_panel .checkbox,
|
||||
.woocommerce_variable_attributes .checkbox {
|
||||
width: auto;
|
||||
margin: 4px 0 !important;
|
||||
vertical-align: middle;
|
||||
float: left;
|
||||
|
@ -6593,6 +6694,180 @@ table.bar_chart {
|
|||
min-width: 400px !important;
|
||||
}
|
||||
|
||||
.branch-5-3 {
|
||||
|
||||
.select2-results {
|
||||
|
||||
.select2-results__option,
|
||||
.select2-results__group {
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.select2-dropdown {
|
||||
border-color: #007cba;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
background: #fff;
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
|
||||
.select2-dropdown--below {
|
||||
box-shadow: 0 0 0 1px #007cba, 0 2px 1px rgba(0, 0, 0, 0.1);
|
||||
|
||||
&::after {
|
||||
top: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
.select2-dropdown--above {
|
||||
box-shadow: 0 0 0 1px #007cba, 0 -2px 1px rgba(0, 0, 0, 0.1);
|
||||
|
||||
&::after {
|
||||
bottom: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
.select2-container {
|
||||
|
||||
@media only screen and (max-width: 782px) {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.select2-selection--single {
|
||||
height: 30px;
|
||||
border-color: #7e8993;
|
||||
|
||||
@media only screen and (max-width: 782px) {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.select2-selection__rendered {
|
||||
line-height: 28px;
|
||||
|
||||
@media only screen and (max-width: 782px) {
|
||||
line-height: 38px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #007cba;
|
||||
}
|
||||
}
|
||||
|
||||
.select2-selection__arrow {
|
||||
right: 1px;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
background: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E") no-repeat right 5px top 55%;
|
||||
background-size: 16px 16px;
|
||||
|
||||
@media only screen and (max-width: 782px) {
|
||||
height: 38px;
|
||||
}
|
||||
|
||||
b {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.select2-container--focus .select2-selection--single,
|
||||
&.select2-container--open .select2-selection--single,
|
||||
&.select2-container--open .select2-selection--multiple {
|
||||
border-color: #007cba;
|
||||
box-shadow: 0 0 0 1px #007cba;
|
||||
}
|
||||
|
||||
.select2-selection--multiple {
|
||||
min-height: 30px;
|
||||
border-color: #7e8993;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.select2-search--inline .select2-search__field {
|
||||
padding: 0 0 0 3px;
|
||||
min-height: 28px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.woocommerce table.form-table .select2-container {
|
||||
|
||||
@media only screen and (max-width: 782px) {
|
||||
min-width: 100% !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select2 colors for built-in admin color themes.
|
||||
*/
|
||||
.branch-5-3 {
|
||||
|
||||
.admin-color {
|
||||
$wp_admin_colors: (
|
||||
blue: #096484,
|
||||
coffee: #c7a589,
|
||||
ectoplasm: #a3b745,
|
||||
midnight: #e14d43,
|
||||
ocean: #9ebaa0,
|
||||
sunrise: #dd823b,
|
||||
light: #04a4cc
|
||||
);
|
||||
|
||||
@each $name, $color in $wp_admin_colors {
|
||||
|
||||
&-#{$name} {
|
||||
|
||||
.select2-dropdown {
|
||||
border-color: $color;
|
||||
}
|
||||
|
||||
.select2-dropdown--below {
|
||||
box-shadow: 0 0 0 1px $color, 0 2px 1px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.select2-dropdown--above {
|
||||
box-shadow: 0 0 0 1px $color, 0 -2px 1px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.select2-selection--single .select2-selection__rendered:hover {
|
||||
color: $color;
|
||||
}
|
||||
|
||||
.select2-container.select2-container--focus .select2-selection--single,
|
||||
.select2-container.select2-container--open .select2-selection--single,
|
||||
.select2-container.select2-container--open .select2-selection--multiple {
|
||||
border-color: $color;
|
||||
box-shadow: 0 0 0 1px $color;
|
||||
}
|
||||
|
||||
.select2-container--default .select2-results__option--highlighted[aria-selected],
|
||||
.select2-container--default .select2-results__option--highlighted[data-selected] {
|
||||
background-color: $color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.post-type-product .tablenav,
|
||||
.post-type-shop_order .tablenav {
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1159,6 +1159,14 @@ h3.jetpack-reasons {
|
|||
}
|
||||
}
|
||||
|
||||
.branch-5-3 {
|
||||
|
||||
.location-input {
|
||||
margin: 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.address-step {
|
||||
|
||||
.select2 {
|
||||
|
@ -1380,6 +1388,17 @@ p.jetpack-terms {
|
|||
}
|
||||
}
|
||||
|
||||
.branch-5-3 {
|
||||
|
||||
.wc-wizard-service-setting-stripe_create_account,
|
||||
.wc-wizard-service-setting-ppec_paypal_reroute_requests {
|
||||
|
||||
.payment-checkbox-input {
|
||||
margin-top: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wc-wizard-service-setting-stripe_email,
|
||||
.wc-wizard-service-setting-ppec_paypal_email {
|
||||
margin-top: 0.75em;
|
||||
|
|
|
@ -88,6 +88,18 @@
|
|||
event.data.variationForm.$form.find( '.single_add_to_cart_button' ).removeClass( 'wc-variation-selection-needed' ).addClass( 'disabled wc-variation-is-unavailable' );
|
||||
event.data.variationForm.$form.find( '.woocommerce-variation-add-to-cart' ).removeClass( 'woocommerce-variation-add-to-cart-enabled' ).addClass( 'woocommerce-variation-add-to-cart-disabled' );
|
||||
}
|
||||
|
||||
// If present, the media element library needs initialized on the variation description.
|
||||
if ( wp.mediaelement ) {
|
||||
event.data.variationForm.$form.find( '.wp-audio-shortcode, .wp-video-shortcode' )
|
||||
.not( '.mejs-container' )
|
||||
.filter(
|
||||
function () {
|
||||
return ! $( this ).parent().hasClass( 'mejs-mediaelement' );
|
||||
}
|
||||
)
|
||||
.mediaelementplayer( wp.mediaelement.settings );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -78,6 +78,11 @@ abstract class WC_Widget extends WP_Widget {
|
|||
* @return bool true if the widget is cached otherwise false
|
||||
*/
|
||||
public function get_cached_widget( $args ) {
|
||||
// Don't get cache if widget_id doesn't exists.
|
||||
if ( empty( $args['widget_id'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$cache = wp_cache_get( $this->get_widget_id_for_cache( $this->widget_id ), 'widget' );
|
||||
|
||||
if ( ! is_array( $cache ) ) {
|
||||
|
@ -100,6 +105,11 @@ abstract class WC_Widget extends WP_Widget {
|
|||
* @return string the content that was cached
|
||||
*/
|
||||
public function cache_widget( $args, $content ) {
|
||||
// Don't set any cache if widget_id doesn't exist.
|
||||
if ( empty( $args['widget_id'] ) ) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
$cache = wp_cache_get( $this->get_widget_id_for_cache( $this->widget_id ), 'widget' );
|
||||
|
||||
if ( ! is_array( $cache ) ) {
|
||||
|
|
|
@ -488,7 +488,7 @@ class WC_Admin_Addons {
|
|||
$back_admin_path = add_query_arg( array() );
|
||||
return array(
|
||||
'wccom-site' => site_url(),
|
||||
'wccom-back' => esc_url( $back_admin_path ),
|
||||
'wccom-back' => rawurlencode( $back_admin_path ),
|
||||
'wccom-woo-version' => WC_VERSION,
|
||||
'wccom-connect-nonce' => wp_create_nonce( 'connect' ),
|
||||
);
|
||||
|
|
|
@ -95,7 +95,7 @@ class WC_Admin_API_Keys {
|
|||
private static function table_list_output() {
|
||||
global $wpdb, $keys_table_list;
|
||||
|
||||
echo '<h2>' . esc_html__( 'REST API', 'woocommerce' ) . ' <a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=keys&create-key=1' ) ) . '" class="add-new-h2">' . esc_html__( 'Add key', 'woocommerce' ) . '</a></h2>';
|
||||
echo '<h2 class="wc-table-list-header">' . esc_html__( 'REST API', 'woocommerce' ) . ' <a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=keys&create-key=1' ) ) . '" class="add-new-h2">' . esc_html__( 'Add key', 'woocommerce' ) . '</a></h2>';
|
||||
|
||||
// Get the API keys count.
|
||||
$count = $wpdb->get_var( "SELECT COUNT(key_id) FROM {$wpdb->prefix}woocommerce_api_keys WHERE 1 = 1;" );
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate product functionality
|
||||
*
|
||||
* @author WooCommerce
|
||||
* @category Admin
|
||||
* @package WooCommerce/Admin
|
||||
* @version 3.0.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( class_exists( 'WC_Admin_Duplicate_Product', false ) ) {
|
||||
return new WC_Admin_Duplicate_Product();
|
||||
}
|
||||
|
@ -87,13 +85,11 @@ class WC_Admin_Duplicate_Product {
|
|||
return;
|
||||
}
|
||||
|
||||
if ( isset( $_GET['post'] ) ) {
|
||||
$notify_url = wp_nonce_url( admin_url( 'edit.php?post_type=product&action=duplicate_product&post=' . absint( $_GET['post'] ) ), 'woocommerce-duplicate-product_' . $_GET['post'] );
|
||||
$notify_url = wp_nonce_url( admin_url( 'edit.php?post_type=product&action=duplicate_product&post=' . absint( $post->ID ) ), 'woocommerce-duplicate-product_' . $post->ID );
|
||||
?>
|
||||
<div id="duplicate-action"><a class="submitduplicate duplication" href="<?php echo esc_url( $notify_url ); ?>"><?php esc_html_e( 'Copy to a new draft', 'woocommerce' ); ?></a></div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate a product action.
|
||||
|
@ -111,7 +107,7 @@ class WC_Admin_Duplicate_Product {
|
|||
|
||||
if ( false === $product ) {
|
||||
/* translators: %s: product id */
|
||||
wp_die( sprintf( esc_html__( 'Product creation failed, could not find original product: %s', 'woocommerce' ), $product_id ) );
|
||||
wp_die( sprintf( esc_html__( 'Product creation failed, could not find original product: %s', 'woocommerce' ), esc_html( $product_id ) ) );
|
||||
}
|
||||
|
||||
$duplicate = $this->product_duplicate( $product );
|
||||
|
@ -120,7 +116,7 @@ class WC_Admin_Duplicate_Product {
|
|||
do_action( 'woocommerce_product_duplicate', $duplicate, $product );
|
||||
wc_do_deprecated_action( 'woocommerce_duplicate_product', array( $duplicate->get_id(), $this->get_product_to_duplicate( $product_id ) ), '3.0', 'Use woocommerce_product_duplicate action instead.' );
|
||||
|
||||
// Redirect to the edit screen for the new draft page
|
||||
// Redirect to the edit screen for the new draft page.
|
||||
wp_redirect( admin_url( 'post.php?action=edit&post=' . $duplicate->get_id() ) );
|
||||
exit;
|
||||
}
|
||||
|
@ -128,15 +124,20 @@ class WC_Admin_Duplicate_Product {
|
|||
/**
|
||||
* Function to create the duplicate of the product.
|
||||
*
|
||||
* @param WC_Product $product
|
||||
* @return WC_Product
|
||||
* @param WC_Product $product The product to duplicate.
|
||||
* @return WC_Product The duplicate.
|
||||
*/
|
||||
public function product_duplicate( $product ) {
|
||||
// Filter to allow us to unset/remove data we don't want to copy to the duplicate. @since 2.6
|
||||
/**
|
||||
* Filter to allow us to unset/remove data we don't want to copy to the duplicate.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
$meta_to_exclude = array_filter( apply_filters( 'woocommerce_duplicate_product_exclude_meta', array() ) );
|
||||
|
||||
$duplicate = clone $product;
|
||||
$duplicate->set_id( 0 );
|
||||
/* translators: %s contains the name of the original product. */
|
||||
$duplicate->set_name( sprintf( esc_html__( '%s (Copy)', 'woocommerce' ), $duplicate->get_name() ) );
|
||||
$duplicate->set_total_sales( 0 );
|
||||
if ( '' !== $product->get_sku( 'edit' ) ) {
|
||||
|
@ -153,7 +154,11 @@ class WC_Admin_Duplicate_Product {
|
|||
$duplicate->delete_meta_data( $meta_key );
|
||||
}
|
||||
|
||||
// This action can be used to modify the object further before it is created - it will be passed by reference. @since 3.0
|
||||
/**
|
||||
* This action can be used to modify the object further before it is created - it will be passed by reference.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
do_action( 'woocommerce_product_duplicate_before_save', $duplicate, $product );
|
||||
|
||||
// Save parent product.
|
||||
|
@ -168,6 +173,12 @@ class WC_Admin_Duplicate_Product {
|
|||
$child_duplicate->set_id( 0 );
|
||||
$child_duplicate->set_date_created( null );
|
||||
|
||||
// If we wait and let the insertion generate the slug, we will see extreme performance degradation
|
||||
// in the case where a product is used as a template. Every time the template is duplicated, each
|
||||
// variation will query every consecutive slug until it finds an empty one. To avoid this, we can
|
||||
// optimize the generation ourselves, avoiding the issue altogether.
|
||||
$this->generate_unique_slug( $child_duplicate );
|
||||
|
||||
if ( '' !== $child->get_sku( 'edit' ) ) {
|
||||
$child_duplicate->set_sku( wc_product_generate_unique_sku( 0, $child->get_sku( 'edit' ) ) );
|
||||
}
|
||||
|
@ -176,7 +187,11 @@ class WC_Admin_Duplicate_Product {
|
|||
$child_duplicate->delete_meta_data( $meta_key );
|
||||
}
|
||||
|
||||
// This action can be used to modify the object further before it is created - it will be passed by reference. @since 3.0
|
||||
/**
|
||||
* This action can be used to modify the object further before it is created - it will be passed by reference.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
do_action( 'woocommerce_product_duplicate_before_save', $child_duplicate, $child );
|
||||
|
||||
$child_duplicate->save();
|
||||
|
@ -193,7 +208,7 @@ class WC_Admin_Duplicate_Product {
|
|||
* Get a product from the database to duplicate.
|
||||
*
|
||||
* @deprecated 3.0.0
|
||||
* @param mixed $id
|
||||
* @param mixed $id The ID of the product to duplicate.
|
||||
* @return object|bool
|
||||
* @see duplicate_product
|
||||
*/
|
||||
|
@ -215,6 +230,44 @@ class WC_Admin_Duplicate_Product {
|
|||
|
||||
return $post;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a unique slug for a given product. We do this so that we can override the
|
||||
* behavior of wp_unique_post_slug(). The normal slug generation will run single
|
||||
* select queries on every non-unique slug, resulting in very bad performance.
|
||||
*
|
||||
* @param WC_Product $product The product to generate a slug for.
|
||||
* @since 3.9.0
|
||||
*/
|
||||
private function generate_unique_slug( $product ) {
|
||||
global $wpdb;
|
||||
|
||||
// We want to remove the suffix from the slug so that we can find the maximum suffix using this root slug.
|
||||
// This will allow us to find the next-highest suffix that is unique. While this does not support gap
|
||||
// filling, this shouldn't matter for our use-case.
|
||||
$root_slug = preg_replace( '/-[0-9]+$/', '', $product->get_slug() );
|
||||
|
||||
$results = $wpdb->get_results(
|
||||
$wpdb->prepare( "SELECT post_name FROM $wpdb->posts WHERE post_name LIKE %s AND post_type IN ( 'product', 'product_variation' )", $root_slug . '%' )
|
||||
);
|
||||
|
||||
// The slug is already unique!
|
||||
if ( empty( $results ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the maximum suffix so we can ensure uniqueness.
|
||||
$max_suffix = 1;
|
||||
foreach ( $results as $result ) {
|
||||
// Pull a numerical suffix off the slug after the last hyphen.
|
||||
$suffix = intval( substr( $result->post_name, strrpos( $result->post_name, '-' ) + 1 ) );
|
||||
if ( $suffix > $max_suffix ) {
|
||||
$max_suffix = $suffix;
|
||||
}
|
||||
}
|
||||
|
||||
$product->set_slug( $root_slug . '-' . ( $max_suffix + 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
return new WC_Admin_Duplicate_Product();
|
||||
|
|
|
@ -706,7 +706,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
|
|||
} elseif ( $description && in_array( $value['type'], array( 'checkbox' ), true ) ) {
|
||||
$description = wp_kses_post( $description );
|
||||
} elseif ( $description ) {
|
||||
$description = '<span class="description">' . wp_kses_post( $description ) . '</span>';
|
||||
$description = '<p class="description">' . wp_kses_post( $description ) . '</p>';
|
||||
}
|
||||
|
||||
if ( $tooltip_html && in_array( $value['type'], array( 'checkbox' ), true ) ) {
|
||||
|
|
|
@ -580,7 +580,7 @@ class WC_Admin_Setup_Wizard {
|
|||
printf(
|
||||
wp_kses(
|
||||
/* translators: %1$s: usage tracking help link */
|
||||
__( 'Learn more about how usage tracking works, and how you\'ll be helping <a href="%1$s" target="_blank">here</a>.', 'woocommerce' ),
|
||||
__( 'Learn more about how usage tracking works, and how you\'ll be helping in our <a href="%1$s" target="_blank">usage tracking documentation</a>.', 'woocommerce' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
|
@ -700,7 +700,7 @@ class WC_Admin_Setup_Wizard {
|
|||
public function run_deferred_actions() {
|
||||
$this->close_http_connection();
|
||||
foreach ( $this->deferred_actions as $action ) {
|
||||
call_user_func_array( $action['func'], $action['args'] );
|
||||
$action['func']( ...$action['args'] );
|
||||
|
||||
// Clear the background installation flag if this is a plugin.
|
||||
if (
|
||||
|
|
|
@ -267,7 +267,7 @@ class WC_Admin_Webhooks {
|
|||
private static function table_list_output() {
|
||||
global $webhooks_table_list;
|
||||
|
||||
echo '<h2>' . esc_html__( 'Webhooks', 'woocommerce' ) . ' <a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=webhooks&edit-webhook=0' ) ) . '" class="add-new-h2">' . esc_html__( 'Add webhook', 'woocommerce' ) . '</a></h2>';
|
||||
echo '<h2 class="wc-table-list-header">' . esc_html__( 'Webhooks', 'woocommerce' ) . ' <a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=advanced§ion=webhooks&edit-webhook=0' ) ) . '" class="add-new-h2">' . esc_html__( 'Add webhook', 'woocommerce' ) . '</a></h2>';
|
||||
|
||||
// Get the webhooks count.
|
||||
$data_store = WC_Data_Store::load( 'webhook' );
|
||||
|
|
|
@ -128,7 +128,7 @@ class WC_Settings_Tax extends WC_Settings_Page {
|
|||
}
|
||||
|
||||
// Invalidate caches.
|
||||
WC_Cache_Helper::incr_cache_prefix( 'taxes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'taxes' );
|
||||
WC_Cache_Helper::get_transient_version( 'shipping', true );
|
||||
// phpcs:enable WordPress.Security.NonceVerification.NoNonceVerification
|
||||
}
|
||||
|
|
|
@ -64,7 +64,13 @@ $exporter = new WC_Product_CSV_Exporter();
|
|||
<td>
|
||||
<select id="woocommerce-exporter-category" class="woocommerce-exporter-category wc-enhanced-select" style="width:100%;" multiple data-placeholder="<?php esc_attr_e( 'Export all categories', 'woocommerce' ); ?>">
|
||||
<?php
|
||||
foreach ( get_categories( array( 'taxonomy' => 'product_cat' ) ) as $category ) {
|
||||
$categories = get_categories(
|
||||
array(
|
||||
'taxonomy' => 'product_cat',
|
||||
'hide_empty' => false,
|
||||
)
|
||||
);
|
||||
foreach ( $categories as $category ) {
|
||||
echo '<option value="' . esc_attr( $category->slug ) . '">' . esc_html( $category->name ) . '</option>';
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -74,7 +74,7 @@ class WC_AJAX {
|
|||
public static function do_wc_ajax() {
|
||||
global $wp_query;
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
if ( ! empty( $_GET['wc-ajax'] ) ) {
|
||||
$wp_query->set( 'wc-ajax', sanitize_text_field( wp_unslash( $_GET['wc-ajax'] ) ) );
|
||||
}
|
||||
|
@ -396,7 +396,7 @@ class WC_AJAX {
|
|||
public static function add_to_cart() {
|
||||
ob_start();
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||
if ( ! isset( $_POST['product_id'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
@ -444,7 +444,7 @@ class WC_AJAX {
|
|||
public static function remove_from_cart() {
|
||||
ob_start();
|
||||
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
$cart_item_key = wc_clean( isset( $_POST['cart_item_key'] ) ? wp_unslash( $_POST['cart_item_key'] ) : '' );
|
||||
|
||||
if ( $cart_item_key && false !== WC()->cart->remove_cart_item( $cart_item_key ) ) {
|
||||
|
@ -469,7 +469,7 @@ class WC_AJAX {
|
|||
public static function get_variation() {
|
||||
ob_start();
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||
if ( empty( $_POST['product_id'] ) ) {
|
||||
wp_die();
|
||||
}
|
||||
|
@ -1144,7 +1144,7 @@ class WC_AJAX {
|
|||
$order->set_billing_email( $user_email_arg );
|
||||
}
|
||||
|
||||
$result = $order->apply_coupon( wc_format_coupon_code( wp_unslash( $_POST['coupon'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$result = $order->apply_coupon( wc_format_coupon_code( wp_unslash( $_POST['coupon'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
throw new Exception( html_entity_decode( wp_strip_all_tags( $result->get_error_message() ) ) );
|
||||
|
@ -1196,7 +1196,7 @@ class WC_AJAX {
|
|||
throw new Exception( __( 'Invalid coupon', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
$order->remove_coupon( wc_format_coupon_code( wp_unslash( $_POST['coupon'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$order->remove_coupon( wc_format_coupon_code( wp_unslash( $_POST['coupon'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$order->calculate_taxes( $calculate_tax_args );
|
||||
$order->calculate_totals( false );
|
||||
|
||||
|
@ -1717,7 +1717,7 @@ class WC_AJAX {
|
|||
* Ajax request handling for categories ordering.
|
||||
*/
|
||||
public static function term_ordering() {
|
||||
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||
if ( ! current_user_can( 'edit_products' ) || empty( $_POST['id'] ) ) {
|
||||
wp_die( -1 );
|
||||
}
|
||||
|
@ -1750,7 +1750,7 @@ class WC_AJAX {
|
|||
public static function product_ordering() {
|
||||
global $wpdb;
|
||||
|
||||
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||
if ( ! current_user_can( 'edit_products' ) || empty( $_POST['id'] ) ) {
|
||||
wp_die( -1 );
|
||||
}
|
||||
|
@ -1792,6 +1792,8 @@ class WC_AJAX {
|
|||
|
||||
$wpdb->update( $wpdb->posts, array( 'menu_order' => $menu_orders[ $sorting_id ] ), array( 'ID' => $sorting_id ) );
|
||||
|
||||
WC_Post_Data::delete_product_query_transients();
|
||||
|
||||
do_action( 'woocommerce_after_product_ordering', $sorting_id, $menu_orders );
|
||||
wp_send_json( $menu_orders );
|
||||
// phpcs:enable
|
||||
|
@ -2536,7 +2538,7 @@ class WC_AJAX {
|
|||
* Handle submissions from assets/js/settings-views-html-settings-tax.js Backbone model.
|
||||
*/
|
||||
public static function tax_rates_save_changes() {
|
||||
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||
if ( ! isset( $_POST['wc_tax_nonce'], $_POST['changes'] ) ) {
|
||||
wp_send_json_error( 'missing_fields' );
|
||||
wp_die();
|
||||
|
@ -2603,7 +2605,7 @@ class WC_AJAX {
|
|||
}
|
||||
}
|
||||
|
||||
WC_Cache_Helper::incr_cache_prefix( 'taxes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'taxes' );
|
||||
WC_Cache_Helper::get_transient_version( 'shipping', true );
|
||||
|
||||
wp_send_json_success(
|
||||
|
|
|
@ -94,7 +94,7 @@ class WC_Cache_Helper {
|
|||
$prefix = wp_cache_get( 'wc_' . $group . '_cache_prefix', $group );
|
||||
|
||||
if ( false === $prefix ) {
|
||||
$prefix = 1;
|
||||
$prefix = microtime();
|
||||
wp_cache_set( 'wc_' . $group . '_cache_prefix', $prefix, $group );
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,18 @@ class WC_Cache_Helper {
|
|||
* @param string $group Group of cache to clear.
|
||||
*/
|
||||
public static function incr_cache_prefix( $group ) {
|
||||
wp_cache_incr( 'wc_' . $group . '_cache_prefix', 1, $group );
|
||||
wc_deprecated_function( 'WC_Cache_Helper::incr_cache_prefix', '3.9.0', 'WC_Cache_Helper::invalidate_cache_group' );
|
||||
self::invalidate_cache_group( $group );
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate cache group.
|
||||
*
|
||||
* @param string $group Group of cache to clear.
|
||||
* @since 3.9.0
|
||||
*/
|
||||
public static function invalidate_cache_group( $group ) {
|
||||
wp_cache_set( 'wc_' . $group . '_cache_prefix', microtime(), $group );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -203,7 +203,8 @@ class WC_Data_Store {
|
|||
public function __call( $method, $parameters ) {
|
||||
if ( is_callable( array( $this->instance, $method ) ) ) {
|
||||
$object = array_shift( $parameters );
|
||||
return call_user_func_array( array( $this->instance, $method ), array_merge( array( &$object ), $parameters ) );
|
||||
$parameters = array_merge( array( &$object ), $parameters );
|
||||
return $this->instance->$method( ...$parameters );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,8 +118,10 @@ class WC_Emails {
|
|||
/**
|
||||
* Queues transactional email so it's not sent in current request if enabled,
|
||||
* otherwise falls back to send now.
|
||||
*
|
||||
* @param mixed ...$args Optional arguments.
|
||||
*/
|
||||
public static function queue_transactional_email() {
|
||||
public static function queue_transactional_email( ...$args ) {
|
||||
if ( is_a( self::$background_emailer, 'WC_Background_Emailer' ) ) {
|
||||
self::$background_emailer->push_to_queue(
|
||||
array(
|
||||
|
@ -128,7 +130,7 @@ class WC_Emails {
|
|||
)
|
||||
);
|
||||
} else {
|
||||
call_user_func_array( array( __CLASS__, 'send_transactional_email' ), func_get_args() ); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsUsage.InParameterList
|
||||
self::send_transactional_email( ...$args );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ class WC_Order extends WC_Abstract_Order {
|
|||
$this->set_transaction_id( $transaction_id );
|
||||
}
|
||||
if ( ! $this->get_date_paid( 'edit' ) ) {
|
||||
$this->set_date_paid( current_time( 'timestamp', true ) );
|
||||
$this->set_date_paid( time() );
|
||||
}
|
||||
$this->set_status( apply_filters( 'woocommerce_payment_complete_order_status', $this->needs_processing() ? 'processing' : 'completed', $this->get_id(), $this ) );
|
||||
$this->save();
|
||||
|
@ -292,11 +292,11 @@ class WC_Order extends WC_Abstract_Order {
|
|||
|
||||
if ( $this->has_status( $payment_completed_status ) ) {
|
||||
// If payment complete status is reached, set paid now.
|
||||
$this->set_date_paid( current_time( 'timestamp', true ) );
|
||||
$this->set_date_paid( time() );
|
||||
|
||||
} elseif ( 'processing' === $payment_completed_status && $this->has_status( 'completed' ) ) {
|
||||
// If payment complete status was processing, but we've passed that and still have no date, set it now.
|
||||
$this->set_date_paid( current_time( 'timestamp', true ) );
|
||||
$this->set_date_paid( time() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +310,7 @@ class WC_Order extends WC_Abstract_Order {
|
|||
*/
|
||||
protected function maybe_set_date_completed() {
|
||||
if ( $this->has_status( 'completed' ) ) {
|
||||
$this->set_date_completed( current_time( 'timestamp', true ) );
|
||||
$this->set_date_completed( time() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -371,6 +371,21 @@ class WC_Order extends WC_Abstract_Order {
|
|||
|
||||
do_action( 'woocommerce_order_status_' . $status_transition['from'] . '_to_' . $status_transition['to'], $this->get_id(), $this );
|
||||
do_action( 'woocommerce_order_status_changed', $this->get_id(), $status_transition['from'], $status_transition['to'], $this );
|
||||
|
||||
// Work out if this was for a payment, and trigger a payment_status hook instead.
|
||||
if (
|
||||
in_array( $status_transition['from'], apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'failed' ) ), true )
|
||||
&& in_array( $status_transition['to'], wc_get_is_paid_statuses(), true )
|
||||
) {
|
||||
/**
|
||||
* Fires when the order progresses from a pending payment status to a paid one.
|
||||
*
|
||||
* @since 3.9.0
|
||||
* @param int Order ID
|
||||
* @param WC_Order Order object
|
||||
*/
|
||||
do_action( 'woocommerce_order_payment_status_changed', $this->get_id(), $this );
|
||||
}
|
||||
} else {
|
||||
/* translators: %s: new order status */
|
||||
$transition_note = sprintf( __( 'Order status set to %s.', 'woocommerce' ), wc_get_order_status_name( $status_transition['to'] ) );
|
||||
|
|
|
@ -462,7 +462,7 @@ class WC_Post_Data {
|
|||
* @param string $meta_value 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::invalidate_cache_group( 'object_' . $object_id );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -302,7 +302,7 @@ class WC_Session_Handler extends WC_Session {
|
|||
$wpdb->query( $wpdb->prepare( "DELETE FROM $this->_table WHERE session_expiry < %d", time() ) ); // @codingStandardsIgnoreLine.
|
||||
|
||||
if ( class_exists( 'WC_Cache_Helper' ) ) {
|
||||
WC_Cache_Helper::incr_cache_prefix( WC_SESSION_CACHE_GROUP );
|
||||
WC_Cache_Helper::invalidate_cache_group( WC_SESSION_CACHE_GROUP );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ class WC_Structured_Data {
|
|||
add_action( 'woocommerce_before_main_content', array( $this, 'generate_website_data' ), 30 );
|
||||
add_action( 'woocommerce_breadcrumb', array( $this, 'generate_breadcrumblist_data' ), 10 );
|
||||
add_action( 'woocommerce_single_product_summary', array( $this, 'generate_product_data' ), 60 );
|
||||
add_action( 'woocommerce_review_meta', array( $this, 'generate_review_data' ), 20 );
|
||||
add_action( 'woocommerce_email_order_details', array( $this, 'generate_order_data' ), 20, 3 );
|
||||
|
||||
// Output structured data.
|
||||
|
@ -279,38 +278,41 @@ class WC_Structured_Data {
|
|||
'reviewCount' => $product->get_review_count(),
|
||||
);
|
||||
|
||||
// Markup most recent rating/review.
|
||||
// Markup 5 most recent rating/review.
|
||||
$comments = get_comments(
|
||||
array(
|
||||
'number' => 1,
|
||||
'number' => 5,
|
||||
'post_id' => $product->get_id(),
|
||||
'status' => 'approve',
|
||||
'post_status' => 'publish',
|
||||
'post_type' => 'product',
|
||||
'parent' => 0,
|
||||
'meta_key' => 'rating',
|
||||
'orderby' => 'meta_value_num',
|
||||
'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
|
||||
array(
|
||||
'key' => 'rating',
|
||||
'type' => 'NUMERIC',
|
||||
'compare' => '>',
|
||||
'value' => 0,
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
if ( $comments ) {
|
||||
$markup['review'] = array();
|
||||
foreach ( $comments as $comment ) {
|
||||
$rating = get_comment_meta( $comment->comment_ID, 'rating', true );
|
||||
|
||||
if ( ! $rating ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$markup['review'] = array(
|
||||
$markup['review'][] = array(
|
||||
'@type' => 'Review',
|
||||
'reviewRating' => array(
|
||||
'@type' => 'Rating',
|
||||
'ratingValue' => $rating,
|
||||
'ratingValue' => get_comment_meta( $comment->comment_ID, 'rating', true ),
|
||||
),
|
||||
'author' => array(
|
||||
'@type' => 'Person',
|
||||
'name' => get_comment_author( $comment->comment_ID ),
|
||||
'name' => get_comment_author( $comment ),
|
||||
),
|
||||
'reviewBody' => get_comment_text( $comment ),
|
||||
'datePublished' => get_comment_date( 'c', $comment ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -907,7 +907,7 @@ class WC_Tax {
|
|||
}
|
||||
|
||||
wp_cache_delete( 'tax-rate-classes', 'taxes' );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'taxes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'taxes' );
|
||||
|
||||
return (bool) $delete;
|
||||
}
|
||||
|
@ -1025,7 +1025,7 @@ class WC_Tax {
|
|||
|
||||
$tax_rate_id = $wpdb->insert_id;
|
||||
|
||||
WC_Cache_Helper::incr_cache_prefix( 'taxes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'taxes' );
|
||||
|
||||
do_action( 'woocommerce_tax_rate_added', $tax_rate_id, $tax_rate );
|
||||
|
||||
|
@ -1082,7 +1082,7 @@ class WC_Tax {
|
|||
)
|
||||
);
|
||||
|
||||
WC_Cache_Helper::incr_cache_prefix( 'taxes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'taxes' );
|
||||
|
||||
do_action( 'woocommerce_tax_rate_updated', $tax_rate_id, $tax_rate );
|
||||
}
|
||||
|
@ -1101,7 +1101,7 @@ class WC_Tax {
|
|||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE tax_rate_id = %d;", $tax_rate_id ) );
|
||||
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %d;", $tax_rate_id ) );
|
||||
|
||||
WC_Cache_Helper::incr_cache_prefix( 'taxes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'taxes' );
|
||||
|
||||
do_action( 'woocommerce_tax_rate_deleted', $tax_rate_id );
|
||||
}
|
||||
|
@ -1176,7 +1176,7 @@ class WC_Tax {
|
|||
$wpdb->query( "INSERT INTO {$wpdb->prefix}woocommerce_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES $sql;" ); // @codingStandardsIgnoreLine.
|
||||
}
|
||||
|
||||
WC_Cache_Helper::incr_cache_prefix( 'taxes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'taxes' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -528,8 +528,25 @@ class WC_Tracker {
|
|||
$gross_total = 0;
|
||||
}
|
||||
|
||||
$processing_gross_total = $wpdb->get_var(
|
||||
"
|
||||
SELECT
|
||||
SUM( order_meta.meta_value ) AS 'gross_total'
|
||||
FROM {$wpdb->prefix}posts AS orders
|
||||
LEFT JOIN {$wpdb->prefix}postmeta AS order_meta ON order_meta.post_id = orders.ID
|
||||
WHERE order_meta.meta_key = '_order_total'
|
||||
AND orders.post_status = 'wc-processing'
|
||||
GROUP BY order_meta.meta_key
|
||||
"
|
||||
);
|
||||
|
||||
if ( is_null( $processing_gross_total ) ) {
|
||||
$processing_gross_total = 0;
|
||||
}
|
||||
|
||||
return array(
|
||||
'gross' => $gross_total,
|
||||
'processing_gross' => $processing_gross_total,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -559,7 +576,25 @@ class WC_Tracker {
|
|||
);
|
||||
}
|
||||
|
||||
return $min_max;
|
||||
$processing_min_max = $wpdb->get_row(
|
||||
"
|
||||
SELECT
|
||||
MIN( post_date_gmt ) as 'processing_first', MAX( post_date_gmt ) as 'processing_last'
|
||||
FROM {$wpdb->prefix}posts
|
||||
WHERE post_type = 'shop_order'
|
||||
AND post_status = 'wc-processing'
|
||||
",
|
||||
ARRAY_A
|
||||
);
|
||||
|
||||
if ( is_null( $processing_min_max ) ) {
|
||||
$processing_min_max = array(
|
||||
'processing_first' => '-',
|
||||
'processing_last' => '-',
|
||||
);
|
||||
}
|
||||
|
||||
return array_merge( $min_max, $processing_min_max );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -473,7 +473,7 @@ final class WooCommerce {
|
|||
* @since 3.3.0
|
||||
*/
|
||||
private function theme_support_includes() {
|
||||
if ( wc_is_active_theme( array( 'twentynineteen', 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' ) ) ) {
|
||||
if ( wc_is_active_theme( array( 'twentytwenty', 'twentynineteen', 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' ) ) ) {
|
||||
switch ( get_template() ) {
|
||||
case 'twentyten':
|
||||
include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-ten.php';
|
||||
|
@ -502,6 +502,9 @@ final class WooCommerce {
|
|||
case 'twentynineteen':
|
||||
include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-nineteen.php';
|
||||
break;
|
||||
case 'twentytwenty':
|
||||
include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-twenty.php';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -842,10 +842,10 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
|
|||
wc_delete_product_transients( $product->get_id() );
|
||||
if ( $product->get_parent_id( 'edit' ) ) {
|
||||
wc_delete_product_transients( $product->get_parent_id( 'edit' ) );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'product_' . $product->get_parent_id( 'edit' ) );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'product_' . $product->get_parent_id( 'edit' ) );
|
||||
}
|
||||
WC_Cache_Helper::invalidate_attribute_count( array_keys( $product->get_attributes() ) );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'product_' . $product->get_id() );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'product_' . $product->get_id() );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -35,7 +35,7 @@ class WC_Shipping_Zone_Data_Store extends WC_Data_Store_WP implements WC_Shippin
|
|||
$zone->save_meta_data();
|
||||
$this->save_locations( $zone );
|
||||
$zone->apply_changes();
|
||||
WC_Cache_Helper::incr_cache_prefix( 'shipping_zones' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'shipping_zones' );
|
||||
WC_Cache_Helper::get_transient_version( 'shipping', true );
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ class WC_Shipping_Zone_Data_Store extends WC_Data_Store_WP implements WC_Shippin
|
|||
$zone->save_meta_data();
|
||||
$this->save_locations( $zone );
|
||||
$zone->apply_changes();
|
||||
WC_Cache_Helper::incr_cache_prefix( 'shipping_zones' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'shipping_zones' );
|
||||
WC_Cache_Helper::get_transient_version( 'shipping', true );
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ class WC_Shipping_Zone_Data_Store extends WC_Data_Store_WP implements WC_Shippin
|
|||
|
||||
$zone->set_id( null );
|
||||
|
||||
WC_Cache_Helper::incr_cache_prefix( 'shipping_zones' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'shipping_zones' );
|
||||
WC_Cache_Helper::get_transient_version( 'shipping', true );
|
||||
|
||||
do_action( 'woocommerce_delete_shipping_zone', $zone_id );
|
||||
|
|
|
@ -60,7 +60,7 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
|
|||
$webhook->apply_changes();
|
||||
|
||||
$this->delete_transients( $webhook->get_status( 'edit' ) );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'webhooks' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'webhooks' );
|
||||
do_action( 'woocommerce_new_webhook', $webhook_id, $webhook );
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
|
|||
$this->delete_transients( 'all' );
|
||||
}
|
||||
wp_cache_delete( $webhook->get_id(), 'webhooks' );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'webhooks' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'webhooks' );
|
||||
|
||||
if ( 'active' === $webhook->get_status() && ( $trigger || $webhook->get_pending_delivery() ) ) {
|
||||
$webhook->deliver_ping();
|
||||
|
@ -184,7 +184,7 @@ class WC_Webhook_Data_Store implements WC_Webhook_Data_Store_Interface {
|
|||
); // WPCS: cache ok, DB call ok.
|
||||
|
||||
$this->delete_transients( 'all' );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'webhooks' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'webhooks' );
|
||||
do_action( 'woocommerce_webhook_deleted', $webhook->get_id(), $webhook );
|
||||
}
|
||||
|
||||
|
|
|
@ -261,7 +261,7 @@ class WC_Email extends WC_Settings_API {
|
|||
*/
|
||||
public function handle_multipart( $mailer ) {
|
||||
if ( $this->sending && 'multipart' === $this->get_email_type() ) {
|
||||
$mailer->AltBody = wordwrap( // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
|
||||
$mailer->AltBody = wordwrap( // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
preg_replace( $this->plain_search, $this->plain_replace, wp_strip_all_tags( $this->get_content_plain() ) )
|
||||
);
|
||||
$this->sending = false;
|
||||
|
@ -634,7 +634,7 @@ class WC_Email extends WC_Settings_API {
|
|||
$message = apply_filters( 'woocommerce_mail_content', $this->style_inline( $message ) );
|
||||
$mail_callback = apply_filters( 'woocommerce_mail_callback', 'wp_mail', $this );
|
||||
$mail_callback_params = apply_filters( 'woocommerce_mail_callback_params', array( $to, $subject, $message, $headers, $attachments ), $this );
|
||||
$return = call_user_func_array( $mail_callback, $mail_callback_params );
|
||||
$return = $mail_callback( ...$mail_callback_params );
|
||||
|
||||
remove_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
|
||||
remove_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
|
||||
|
|
|
@ -2023,7 +2023,7 @@ class WC_API_Products extends WC_API_Resource {
|
|||
|
||||
// Clear transients
|
||||
delete_transient( 'wc_attribute_taxonomies' );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' );
|
||||
|
||||
$this->server->send_status( 201 );
|
||||
|
||||
|
@ -2109,7 +2109,7 @@ class WC_API_Products extends WC_API_Resource {
|
|||
|
||||
// Clear transients
|
||||
delete_transient( 'wc_attribute_taxonomies' );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' );
|
||||
|
||||
return $this->get_product_attribute( $id );
|
||||
} catch ( WC_API_Exception $e ) {
|
||||
|
@ -2171,7 +2171,7 @@ class WC_API_Products extends WC_API_Resource {
|
|||
|
||||
// Clear transients
|
||||
delete_transient( 'wc_attribute_taxonomies' );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' );
|
||||
|
||||
return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), 'product_attribute' ) );
|
||||
} catch ( WC_API_Exception $e ) {
|
||||
|
|
|
@ -2577,7 +2577,7 @@ class WC_API_Products extends WC_API_Resource {
|
|||
// Clear transients.
|
||||
wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' );
|
||||
delete_transient( 'wc_attribute_taxonomies' );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' );
|
||||
|
||||
$this->server->send_status( 201 );
|
||||
|
||||
|
@ -2664,7 +2664,7 @@ class WC_API_Products extends WC_API_Resource {
|
|||
// Clear transients.
|
||||
wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' );
|
||||
delete_transient( 'wc_attribute_taxonomies' );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' );
|
||||
|
||||
return $this->get_product_attribute( $id );
|
||||
} catch ( WC_API_Exception $e ) {
|
||||
|
@ -2727,7 +2727,7 @@ class WC_API_Products extends WC_API_Resource {
|
|||
// Clear transients.
|
||||
wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' );
|
||||
delete_transient( 'wc_attribute_taxonomies' );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' );
|
||||
|
||||
return array( 'message' => sprintf( __( 'Deleted %s', 'woocommerce' ), 'product_attribute' ) );
|
||||
} catch ( WC_API_Exception $e ) {
|
||||
|
|
|
@ -107,7 +107,7 @@ abstract class ActionScheduler_Abstract_ListTable extends WP_List_Table {
|
|||
* `_x` with some default (the package name)
|
||||
*/
|
||||
protected function translate( $text, $context = '' ) {
|
||||
return _x( $text, $context, $this->package );
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -462,7 +462,7 @@ abstract class ActionScheduler_Abstract_ListTable extends WP_List_Table {
|
|||
echo '</select>';
|
||||
}
|
||||
|
||||
submit_button( $this->translate( 'Filter' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) );
|
||||
submit_button( __( 'Filter', 'woocommerce' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) );
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
|
@ -561,7 +561,8 @@ abstract class ActionScheduler_Abstract_ListTable extends WP_List_Table {
|
|||
protected function display_header() {
|
||||
echo '<h1 class="wp-heading-inline">' . esc_attr( $this->table_header ) . '</h1>';
|
||||
if ( $this->get_request_search_query() ) {
|
||||
echo '<span class="subtitle">' . esc_attr( $this->translate( sprintf( 'Search results for "%s"', $this->get_request_search_query() ) ) ) . '</span>';
|
||||
/* translators: %s: search query */
|
||||
echo '<span class="subtitle">' . esc_attr( sprintf( __( 'Search results for "%s"', 'woocommerce' ), $this->get_request_search_query() ) ) . '</span>';
|
||||
}
|
||||
echo '<hr class="wp-header-end">';
|
||||
}
|
||||
|
@ -651,6 +652,6 @@ abstract class ActionScheduler_Abstract_ListTable extends WP_List_Table {
|
|||
* Get the text to display in the search box on the list table.
|
||||
*/
|
||||
protected function get_search_box_placeholder() {
|
||||
return $this->translate( 'Search' );
|
||||
return __( 'Search', 'woocommerce' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class ActionScheduler_InvalidActionException extends \InvalidArgumentException i
|
|||
*/
|
||||
public static function from_decoding_args( $action_id ) {
|
||||
$message = sprintf(
|
||||
__( 'Action [%s] has invalid arguments. It cannot be JSON decoded to an array.', 'action-scheduler' ),
|
||||
__( 'Action [%s] has invalid arguments. It cannot be JSON decoded to an array.', 'woocommerce' ),
|
||||
$action_id
|
||||
);
|
||||
|
||||
|
|
|
@ -86,20 +86,20 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|||
$this->logger = $logger;
|
||||
$this->runner = $runner;
|
||||
|
||||
$this->table_header = __( 'Scheduled Actions', 'action-scheduler' );
|
||||
$this->table_header = __( 'Scheduled Actions', 'woocommerce' );
|
||||
|
||||
$this->bulk_actions = array(
|
||||
'delete' => __( 'Delete', 'action-scheduler' ),
|
||||
'delete' => __( 'Delete', 'woocommerce' ),
|
||||
);
|
||||
|
||||
$this->columns = array(
|
||||
'hook' => __( 'Hook', 'action-scheduler' ),
|
||||
'status' => __( 'Status', 'action-scheduler' ),
|
||||
'args' => __( 'Arguments', 'action-scheduler' ),
|
||||
'group' => __( 'Group', 'action-scheduler' ),
|
||||
'recurrence' => __( 'Recurrence', 'action-scheduler' ),
|
||||
'schedule' => __( 'Scheduled Date', 'action-scheduler' ),
|
||||
'log_entries' => __( 'Log', 'action-scheduler' ),
|
||||
'hook' => __( 'Hook', 'woocommerce' ),
|
||||
'status' => __( 'Status', 'woocommerce' ),
|
||||
'args' => __( 'Arguments', 'woocommerce' ),
|
||||
'group' => __( 'Group', 'woocommerce' ),
|
||||
'recurrence' => __( 'Recurrence', 'woocommerce' ),
|
||||
'schedule' => __( 'Scheduled Date', 'woocommerce' ),
|
||||
'log_entries' => __( 'Log', 'woocommerce' ),
|
||||
);
|
||||
|
||||
$this->sort_by = array(
|
||||
|
@ -119,19 +119,19 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|||
if ( empty( $request_status ) ) {
|
||||
$this->sort_by[] = 'status';
|
||||
} elseif ( in_array( $request_status, array( 'in-progress', 'failed' ) ) ) {
|
||||
$this->columns += array( 'claim_id' => __( 'Claim ID', 'action-scheduler' ) );
|
||||
$this->columns += array( 'claim_id' => __( 'Claim ID', 'woocommerce' ) );
|
||||
$this->sort_by[] = 'claim_id';
|
||||
}
|
||||
|
||||
$this->row_actions = array(
|
||||
'hook' => array(
|
||||
'run' => array(
|
||||
'name' => __( 'Run', 'action-scheduler' ),
|
||||
'desc' => __( 'Process the action now as if it were run as part of a queue', 'action-scheduler' ),
|
||||
'name' => __( 'Run', 'woocommerce' ),
|
||||
'desc' => __( 'Process the action now as if it were run as part of a queue', 'woocommerce' ),
|
||||
),
|
||||
'cancel' => array(
|
||||
'name' => __( 'Cancel', 'action-scheduler' ),
|
||||
'desc' => __( 'Cancel the action now to avoid it being run in future', 'action-scheduler' ),
|
||||
'name' => __( 'Cancel', 'woocommerce' ),
|
||||
'desc' => __( 'Cancel the action now to avoid it being run in future', 'woocommerce' ),
|
||||
'class' => 'cancel trash',
|
||||
),
|
||||
),
|
||||
|
@ -140,31 +140,31 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|||
self::$time_periods = array(
|
||||
array(
|
||||
'seconds' => YEAR_IN_SECONDS,
|
||||
'names' => _n_noop( '%s year', '%s years', 'action-scheduler' ),
|
||||
'names' => _n_noop( '%s year', '%s years', 'woocommerce' ),
|
||||
),
|
||||
array(
|
||||
'seconds' => MONTH_IN_SECONDS,
|
||||
'names' => _n_noop( '%s month', '%s months', 'action-scheduler' ),
|
||||
'names' => _n_noop( '%s month', '%s months', 'woocommerce' ),
|
||||
),
|
||||
array(
|
||||
'seconds' => WEEK_IN_SECONDS,
|
||||
'names' => _n_noop( '%s week', '%s weeks', 'action-scheduler' ),
|
||||
'names' => _n_noop( '%s week', '%s weeks', 'woocommerce' ),
|
||||
),
|
||||
array(
|
||||
'seconds' => DAY_IN_SECONDS,
|
||||
'names' => _n_noop( '%s day', '%s days', 'action-scheduler' ),
|
||||
'names' => _n_noop( '%s day', '%s days', 'woocommerce' ),
|
||||
),
|
||||
array(
|
||||
'seconds' => HOUR_IN_SECONDS,
|
||||
'names' => _n_noop( '%s hour', '%s hours', 'action-scheduler' ),
|
||||
'names' => _n_noop( '%s hour', '%s hours', 'woocommerce' ),
|
||||
),
|
||||
array(
|
||||
'seconds' => MINUTE_IN_SECONDS,
|
||||
'names' => _n_noop( '%s minute', '%s minutes', 'action-scheduler' ),
|
||||
'names' => _n_noop( '%s minute', '%s minutes', 'woocommerce' ),
|
||||
),
|
||||
array(
|
||||
'seconds' => 1,
|
||||
'names' => _n_noop( '%s second', '%s seconds', 'action-scheduler' ),
|
||||
'names' => _n_noop( '%s second', '%s seconds', 'woocommerce' ),
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -191,7 +191,7 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|||
private static function human_interval( $interval, $periods_to_include = 2 ) {
|
||||
|
||||
if ( $interval <= 0 ) {
|
||||
return __( 'Now!', 'action-scheduler' );
|
||||
return __( 'Now!', 'woocommerce' );
|
||||
}
|
||||
|
||||
$output = '';
|
||||
|
@ -204,7 +204,7 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|||
if ( ! empty( $output ) ) {
|
||||
$output .= ' ';
|
||||
}
|
||||
$output .= sprintf( _n( self::$time_periods[ $time_period_index ]['names'][0], self::$time_periods[ $time_period_index ]['names'][1], $periods_in_interval, 'action-scheduler' ), $periods_in_interval );
|
||||
$output .= sprintf( _n( self::$time_periods[ $time_period_index ]['names'][0], self::$time_periods[ $time_period_index ]['names'][1], $periods_in_interval, 'woocommerce' ), $periods_in_interval );
|
||||
$seconds_remaining -= $periods_in_interval * self::$time_periods[ $time_period_index ]['seconds'];
|
||||
$periods_included++;
|
||||
}
|
||||
|
@ -224,15 +224,15 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|||
$recurrence = $action->get_schedule();
|
||||
if ( $recurrence->is_recurring() ) {
|
||||
if ( method_exists( $recurrence, 'interval_in_seconds' ) ) {
|
||||
return sprintf( __( 'Every %s', 'action-scheduler' ), self::human_interval( $recurrence->interval_in_seconds() ) );
|
||||
return sprintf( __( 'Every %s', 'woocommerce' ), self::human_interval( $recurrence->interval_in_seconds() ) );
|
||||
}
|
||||
|
||||
if ( method_exists( $recurrence, 'get_recurrence' ) ) {
|
||||
return sprintf( __( 'Cron %s', 'action-scheduler' ), $recurrence->get_recurrence() );
|
||||
return sprintf( __( 'Cron %s', 'woocommerce' ), $recurrence->get_recurrence() );
|
||||
}
|
||||
}
|
||||
|
||||
return __( 'Non-repeating', 'action-scheduler' );
|
||||
return __( 'Non-repeating', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -318,7 +318,7 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|||
if ( $this->store->get_claim_count() >= $this->runner->get_allowed_concurrent_batches() ) {
|
||||
$this->admin_notices[] = array(
|
||||
'class' => 'updated',
|
||||
'message' => sprintf( __( 'Maximum simultaneous batches already in progress (%s queues). No actions will be processed until the current batches are complete.', 'action-scheduler' ), $this->store->get_claim_count() ),
|
||||
'message' => sprintf( __( 'Maximum simultaneous batches already in progress (%s queues). No actions will be processed until the current batches are complete.', 'woocommerce' ), $this->store->get_claim_count() ),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -333,18 +333,18 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|||
$class = 'updated';
|
||||
switch ( $notification['row_action_type'] ) {
|
||||
case 'run' :
|
||||
$action_message_html = sprintf( __( 'Successfully executed action: %s', 'action-scheduler' ), $action_hook_html );
|
||||
$action_message_html = sprintf( __( 'Successfully executed action: %s', 'woocommerce' ), $action_hook_html );
|
||||
break;
|
||||
case 'cancel' :
|
||||
$action_message_html = sprintf( __( 'Successfully canceled action: %s', 'action-scheduler' ), $action_hook_html );
|
||||
$action_message_html = sprintf( __( 'Successfully canceled action: %s', 'woocommerce' ), $action_hook_html );
|
||||
break;
|
||||
default :
|
||||
$action_message_html = sprintf( __( 'Successfully processed change for action: %s', 'action-scheduler' ), $action_hook_html );
|
||||
$action_message_html = sprintf( __( 'Successfully processed change for action: %s', 'woocommerce' ), $action_hook_html );
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$class = 'error';
|
||||
$action_message_html = sprintf( __( 'Could not process change for action: "%s" (ID: %d). Error: %s', 'action-scheduler' ), $action_hook_html, esc_html( $notification['action_id'] ), esc_html( $notification['error_message'] ) );
|
||||
$action_message_html = sprintf( __( 'Could not process change for action: "%s" (ID: %d). Error: %s', 'woocommerce' ), $action_hook_html, esc_html( $notification['action_id'] ), esc_html( $notification['error_message'] ) );
|
||||
}
|
||||
|
||||
$action_message_html = apply_filters( 'action_scheduler_admin_notice_html', $action_message_html, $action, $notification );
|
||||
|
@ -389,9 +389,9 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|||
$schedule_display_string .= '<br/>';
|
||||
|
||||
if ( gmdate( 'U' ) > $next_timestamp ) {
|
||||
$schedule_display_string .= sprintf( __( ' (%s ago)', 'action-scheduler' ), self::human_interval( gmdate( 'U' ) - $next_timestamp ) );
|
||||
$schedule_display_string .= sprintf( __( ' (%s ago)', 'woocommerce' ), self::human_interval( gmdate( 'U' ) - $next_timestamp ) );
|
||||
} else {
|
||||
$schedule_display_string .= sprintf( __( ' (%s)', 'action-scheduler' ), self::human_interval( $next_timestamp - gmdate( 'U' ) ) );
|
||||
$schedule_display_string .= sprintf( __( ' (%s)', 'woocommerce' ), self::human_interval( $next_timestamp - gmdate( 'U' ) ) );
|
||||
}
|
||||
|
||||
return $schedule_display_string;
|
||||
|
@ -528,6 +528,6 @@ class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
|
|||
* Get the text to display in the search box on the list table.
|
||||
*/
|
||||
protected function get_search_box_button_text() {
|
||||
return __( 'Search hook, args and claim ID', 'action-scheduler' );
|
||||
return __( 'Search hook, args and claim ID', 'woocommerce' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,44 +59,44 @@ abstract class ActionScheduler_Logger {
|
|||
}
|
||||
|
||||
public function log_stored_action( $action_id ) {
|
||||
$this->log( $action_id, __( 'action created', 'action-scheduler' ) );
|
||||
$this->log( $action_id, __( 'action created', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
public function log_canceled_action( $action_id ) {
|
||||
$this->log( $action_id, __( 'action canceled', 'action-scheduler' ) );
|
||||
$this->log( $action_id, __( 'action canceled', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
public function log_started_action( $action_id ) {
|
||||
$this->log( $action_id, __( 'action started', 'action-scheduler' ) );
|
||||
$this->log( $action_id, __( 'action started', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
public function log_completed_action( $action_id ) {
|
||||
$this->log( $action_id, __( 'action complete', 'action-scheduler' ) );
|
||||
$this->log( $action_id, __( 'action complete', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
public function log_failed_action( $action_id, Exception $exception ) {
|
||||
$this->log( $action_id, sprintf( __( 'action failed: %s', 'action-scheduler' ), $exception->getMessage() ) );
|
||||
$this->log( $action_id, sprintf( __( 'action failed: %s', 'woocommerce' ), $exception->getMessage() ) );
|
||||
}
|
||||
|
||||
public function log_timed_out_action( $action_id, $timeout ) {
|
||||
$this->log( $action_id, sprintf( __( 'action timed out after %s seconds', 'action-scheduler' ), $timeout ) );
|
||||
$this->log( $action_id, sprintf( __( 'action timed out after %s seconds', 'woocommerce' ), $timeout ) );
|
||||
}
|
||||
|
||||
public function log_unexpected_shutdown( $action_id, $error ) {
|
||||
if ( ! empty( $error ) ) {
|
||||
$this->log( $action_id, sprintf( __( 'unexpected shutdown: PHP Fatal error %s in %s on line %s', 'action-scheduler' ), $error['message'], $error['file'], $error['line'] ) );
|
||||
$this->log( $action_id, sprintf( __( 'unexpected shutdown: PHP Fatal error %s in %s on line %s', 'woocommerce' ), $error['message'], $error['file'], $error['line'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
public function log_reset_action( $action_id ) {
|
||||
$this->log( $action_id, __( 'action reset', 'action_scheduler' ) );
|
||||
$this->log( $action_id, __( 'action reset', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
public function log_ignored_action( $action_id ) {
|
||||
$this->log( $action_id, __( 'action ignored', 'action-scheduler' ) );
|
||||
$this->log( $action_id, __( 'action ignored', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
public function log_failed_fetch_action( $action_id ) {
|
||||
$this->log( $action_id, __( 'There was a failure fetching this action', 'action-scheduler' ) );
|
||||
$this->log( $action_id, __( 'There was a failure fetching this action', 'woocommerce' ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ class ActionScheduler_QueueRunner extends ActionScheduler_Abstract_QueueRunner {
|
|||
public function add_wp_cron_schedule( $schedules ) {
|
||||
$schedules['every_minute'] = array(
|
||||
'interval' => 60, // in seconds
|
||||
'display' => __( 'Every minute' ),
|
||||
'display' => __( 'Every minute', 'woocommerce' ),
|
||||
);
|
||||
|
||||
return $schedules;
|
||||
|
|
|
@ -149,7 +149,7 @@ abstract class ActionScheduler_Store {
|
|||
protected function get_scheduled_date_string( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) {
|
||||
$next = null === $scheduled_date ? $action->get_schedule()->next() : $scheduled_date;
|
||||
if ( ! $next ) {
|
||||
throw new InvalidArgumentException( __( 'Invalid schedule. Cannot save action.', 'action-scheduler' ) );
|
||||
throw new InvalidArgumentException( __( 'Invalid schedule. Cannot save action.', 'woocommerce' ) );
|
||||
}
|
||||
$next->setTimezone( new DateTimeZone( 'UTC' ) );
|
||||
|
||||
|
@ -166,7 +166,7 @@ abstract class ActionScheduler_Store {
|
|||
protected function get_scheduled_date_string_local( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) {
|
||||
$next = null === $scheduled_date ? $action->get_schedule()->next() : $scheduled_date;
|
||||
if ( ! $next ) {
|
||||
throw new InvalidArgumentException( __( 'Invalid schedule. Cannot save action.', 'action-scheduler' ) );
|
||||
throw new InvalidArgumentException( __( 'Invalid schedule. Cannot save action.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
ActionScheduler_TimezoneHelper::set_local_timezone( $next );
|
||||
|
@ -178,11 +178,11 @@ abstract class ActionScheduler_Store {
|
|||
*/
|
||||
public function get_status_labels() {
|
||||
return array(
|
||||
self::STATUS_COMPLETE => __( 'Complete', 'action-scheduler' ),
|
||||
self::STATUS_PENDING => __( 'Pending', 'action-scheduler' ),
|
||||
self::STATUS_RUNNING => __( 'In-progress', 'action-scheduler' ),
|
||||
self::STATUS_FAILED => __( 'Failed', 'action-scheduler' ),
|
||||
self::STATUS_CANCELED => __( 'Canceled', 'action-scheduler' ),
|
||||
self::STATUS_COMPLETE => __( 'Complete', 'woocommerce' ),
|
||||
self::STATUS_PENDING => __( 'Pending', 'woocommerce' ),
|
||||
self::STATUS_RUNNING => __( 'In-progress', 'woocommerce' ),
|
||||
self::STATUS_FAILED => __( 'Failed', 'woocommerce' ),
|
||||
self::STATUS_CANCELED => __( 'Canceled', 'woocommerce' ),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
|
|||
public function __construct( ActionScheduler_Store $store = null, ActionScheduler_FatalErrorMonitor $monitor = null, ActionScheduler_QueueCleaner $cleaner = null ) {
|
||||
if ( ! ( defined( 'WP_CLI' ) && WP_CLI ) ) {
|
||||
/* translators: %s php class name */
|
||||
throw new Exception( sprintf( __( 'The %s class can only be run within WP CLI.', 'action-scheduler' ), __CLASS__ ) );
|
||||
throw new Exception( sprintf( __( 'The %s class can only be run within WP CLI.', 'woocommerce' ), __CLASS__ ) );
|
||||
}
|
||||
|
||||
parent::__construct( $store, $monitor, $cleaner );
|
||||
|
@ -56,9 +56,9 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
|
|||
$too_many = $claim_count >= $this->get_allowed_concurrent_batches();
|
||||
if ( $too_many ) {
|
||||
if ( $force ) {
|
||||
WP_CLI::warning( __( 'There are too many concurrent batches, but the run is forced to continue.', 'action-scheduler' ) );
|
||||
WP_CLI::warning( __( 'There are too many concurrent batches, but the run is forced to continue.', 'woocommerce' ) );
|
||||
} else {
|
||||
WP_CLI::error( __( 'There are too many concurrent batches.', 'action-scheduler' ) );
|
||||
WP_CLI::error( __( 'There are too many concurrent batches.', 'woocommerce' ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
|
|||
protected function setup_progress_bar() {
|
||||
$count = count( $this->actions );
|
||||
$this->progress_bar = \WP_CLI\Utils\make_progress_bar(
|
||||
sprintf( _n( 'Running %d action', 'Running %d actions', $count, 'action-scheduler' ), number_format_i18n( $count ) ),
|
||||
sprintf( _n( 'Running %d action', 'Running %d actions', $count, 'woocommerce' ), number_format_i18n( $count ) ),
|
||||
$count
|
||||
);
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
|
|||
foreach ( $this->actions as $action_id ) {
|
||||
// Error if we lost the claim.
|
||||
if ( ! in_array( $action_id, $this->store->find_actions_by_claim_id( $this->claim->get_id() ) ) ) {
|
||||
WP_CLI::warning( __( 'The claim has been lost. Aborting current batch.', 'action-scheduler' ) );
|
||||
WP_CLI::warning( __( 'The claim has been lost. Aborting current batch.', 'woocommerce' ) );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
|
|||
*/
|
||||
public function before_execute( $action_id ) {
|
||||
/* translators: %s refers to the action ID */
|
||||
WP_CLI::log( sprintf( __( 'Started processing action %s', 'action-scheduler' ), $action_id ) );
|
||||
WP_CLI::log( sprintf( __( 'Started processing action %s', 'woocommerce' ), $action_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,7 +149,7 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
|
|||
$action = $this->store->fetch_action( $action_id );
|
||||
}
|
||||
/* translators: %s refers to the action ID */
|
||||
WP_CLI::log( sprintf( __( 'Completed processing action %s with hook: %s', 'action-scheduler' ), $action_id, $action->get_hook() ) );
|
||||
WP_CLI::log( sprintf( __( 'Completed processing action %s with hook: %s', 'woocommerce' ), $action_id, $action->get_hook() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,7 +164,7 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
|
|||
public function action_failed( $action_id, $exception ) {
|
||||
WP_CLI::error(
|
||||
/* translators: %1$s refers to the action ID, %2$s refers to the Exception message */
|
||||
sprintf( __( 'Error processing action %1$s: %2$s', 'action-scheduler' ), $action_id, $exception->getMessage() ),
|
||||
sprintf( __( 'Error processing action %1$s: %2$s', 'woocommerce' ), $action_id, $exception->getMessage() ),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
@ -176,11 +176,12 @@ class ActionScheduler_WPCLI_QueueRunner extends ActionScheduler_Abstract_QueueRu
|
|||
*/
|
||||
protected function stop_the_insanity( $sleep_time = 0 ) {
|
||||
if ( 0 < $sleep_time ) {
|
||||
WP_CLI::warning( sprintf( 'Stopped the insanity for %d %s', $sleep_time, _n( 'second', 'seconds', $sleep_time ) ) );
|
||||
/* translators: 1: sleep time 2: time unit */
|
||||
WP_CLI::warning( sprintf( __( 'Stopped the insanity for %$1d %$2s', 'woocommerce' ), $sleep_time, _n( 'second', 'seconds', $sleep_time, 'woocommerce' ) ) );
|
||||
sleep( $sleep_time );
|
||||
}
|
||||
|
||||
WP_CLI::warning( __( 'Attempting to reduce used memory...', 'action-scheduler' ) );
|
||||
WP_CLI::warning( __( 'Attempting to reduce used memory...', 'woocommerce' ) );
|
||||
|
||||
/**
|
||||
* @var $wpdb \wpdb
|
||||
|
|
|
@ -84,7 +84,7 @@ class ActionScheduler_WPCLI_Scheduler_command extends WP_CLI_Command {
|
|||
WP_CLI::log(
|
||||
sprintf(
|
||||
/* translators: %d refers to how many scheduled taks were found to run */
|
||||
_n( 'Found %d scheduled task', 'Found %d scheduled tasks', $total, 'action-scheduler' ),
|
||||
_n( 'Found %d scheduled task', 'Found %d scheduled tasks', $total, 'woocommerce' ),
|
||||
number_format_i18n( $total )
|
||||
)
|
||||
);
|
||||
|
@ -101,7 +101,7 @@ class ActionScheduler_WPCLI_Scheduler_command extends WP_CLI_Command {
|
|||
WP_CLI::log(
|
||||
sprintf(
|
||||
/* translators: %d refers to the total number of batches executed */
|
||||
_n( '%d batch executed.', '%d batches executed.', $batches_completed, 'action-scheduler' ),
|
||||
_n( '%d batch executed.', '%d batches executed.', $batches_completed, 'woocommerce' ),
|
||||
number_format_i18n( $batches_completed )
|
||||
)
|
||||
);
|
||||
|
@ -120,7 +120,7 @@ class ActionScheduler_WPCLI_Scheduler_command extends WP_CLI_Command {
|
|||
WP_CLI::error(
|
||||
sprintf(
|
||||
/* translators: %s refers to the exception error message. */
|
||||
__( 'There was an error running the action scheduler: %s', 'action-scheduler' ),
|
||||
__( 'There was an error running the action scheduler: %s', 'woocommerce' ),
|
||||
$e->getMessage()
|
||||
)
|
||||
);
|
||||
|
@ -137,7 +137,7 @@ class ActionScheduler_WPCLI_Scheduler_command extends WP_CLI_Command {
|
|||
WP_CLI::success(
|
||||
sprintf(
|
||||
/* translators: %d refers to the total number of taskes completed */
|
||||
_n( '%d scheduled task completed.', '%d scheduled tasks completed.', $actions_completed, 'action-scheduler' ),
|
||||
_n( '%d scheduled task completed.', '%d scheduled tasks completed.', $actions_completed, 'woocommerce' ),
|
||||
number_format_i18n( $actions_completed )
|
||||
)
|
||||
);
|
||||
|
|
|
@ -97,14 +97,14 @@ class ActionScheduler_wcSystemStatus {
|
|||
<table class="wc_status_table widefat" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="5" data-export-label="Action Scheduler"><h2><?php esc_html_e( 'Action Scheduler', 'action-scheduler' ); ?><?php echo wc_help_tip( esc_html__( 'This section shows scheduled action counts.', 'action-scheduler' ) ); ?></h2></th>
|
||||
<th colspan="5" data-export-label="Action Scheduler"><h2><?php esc_html_e( 'Action Scheduler', 'woocommerce' ); ?><?php echo wc_help_tip( esc_html__( 'This section shows scheduled action counts.', 'woocommerce' ) ); ?></h2></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><?php esc_html_e( 'Action Status', 'action-scheduler' ); ?></strong></td>
|
||||
<td><strong><?php esc_html_e( 'Action Status', 'woocommerce' ); ?></strong></td>
|
||||
<td class="help"> </td>
|
||||
<td><strong><?php esc_html_e( 'Count', 'action-scheduler' ); ?></strong></td>
|
||||
<td><strong><?php esc_html_e( 'Oldest Scheduled Date', 'action-scheduler' ); ?></strong></td>
|
||||
<td><strong><?php esc_html_e( 'Newest Scheduled Date', 'action-scheduler' ); ?></strong></td>
|
||||
<td><strong><?php esc_html_e( 'Count', 'woocommerce' ); ?></strong></td>
|
||||
<td><strong><?php esc_html_e( 'Oldest Scheduled Date', 'woocommerce' ); ?></strong></td>
|
||||
<td><strong><?php esc_html_e( 'Newest Scheduled Date', 'woocommerce' ); ?></strong></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
|
|
@ -30,7 +30,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|||
do_action( 'action_scheduler_stored_action', $post_id );
|
||||
return $post_id;
|
||||
} catch ( Exception $e ) {
|
||||
throw new RuntimeException( sprintf( __('Error saving action: %s', 'action-scheduler'), $e->getMessage() ), 0 );
|
||||
throw new RuntimeException( sprintf( __('Error saving action: %s', 'woocommerce'), $e->getMessage() ), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|||
remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
|
||||
|
||||
if ( is_wp_error($post_id) || empty($post_id) ) {
|
||||
throw new RuntimeException(__('Unable to save action.', 'action-scheduler'));
|
||||
throw new RuntimeException(__('Unable to save action.', 'woocommerce'));
|
||||
}
|
||||
return $post_id;
|
||||
}
|
||||
|
@ -275,7 +275,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|||
protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) {
|
||||
|
||||
if ( ! in_array( $select_or_count, array( 'select', 'count' ) ) ) {
|
||||
throw new InvalidArgumentException(__('Invalid schedule. Cannot save action.', 'action-scheduler'));
|
||||
throw new InvalidArgumentException(__('Invalid schedule. Cannot save action.', 'woocommerce'));
|
||||
}
|
||||
|
||||
$query = wp_parse_args( $query, array(
|
||||
|
@ -448,7 +448,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|||
public function cancel_action( $action_id ) {
|
||||
$post = get_post($action_id);
|
||||
if ( empty($post) || ($post->post_type != self::POST_TYPE) ) {
|
||||
throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
|
||||
throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'woocommerce'), $action_id));
|
||||
}
|
||||
do_action( 'action_scheduler_canceled_action', $action_id );
|
||||
add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
|
||||
|
@ -459,7 +459,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|||
public function delete_action( $action_id ) {
|
||||
$post = get_post($action_id);
|
||||
if ( empty($post) || ($post->post_type != self::POST_TYPE) ) {
|
||||
throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
|
||||
throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'woocommerce'), $action_id));
|
||||
}
|
||||
do_action( 'action_scheduler_deleted_action', $action_id );
|
||||
wp_delete_post($action_id, TRUE);
|
||||
|
@ -485,7 +485,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|||
public function get_date_gmt( $action_id ) {
|
||||
$post = get_post($action_id);
|
||||
if ( empty($post) || ($post->post_type != self::POST_TYPE) ) {
|
||||
throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
|
||||
throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'woocommerce'), $action_id));
|
||||
}
|
||||
if ( $post->post_status == 'publish' ) {
|
||||
return as_get_datetime_object($post->post_modified_gmt);
|
||||
|
@ -597,7 +597,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|||
// Run the query and gather results.
|
||||
$rows_affected = $wpdb->query( $wpdb->prepare( "{$update} {$where} {$order}", $params ) );
|
||||
if ( $rows_affected === false ) {
|
||||
throw new RuntimeException( __( 'Unable to claim actions. Database error.', 'action-scheduler' ) );
|
||||
throw new RuntimeException( __( 'Unable to claim actions. Database error.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
return (int) $rows_affected;
|
||||
|
@ -617,7 +617,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|||
protected function get_actions_by_group( $group, $limit, DateTime $date ) {
|
||||
// Ensure the group exists before continuing.
|
||||
if ( ! term_exists( $group, self::GROUP_TAXONOMY )) {
|
||||
throw new InvalidArgumentException( sprintf( __( 'The group "%s" does not exist.', 'action-scheduler' ), $group ) );
|
||||
throw new InvalidArgumentException( sprintf( __( 'The group "%s" does not exist.', 'woocommerce' ), $group ) );
|
||||
}
|
||||
|
||||
// Set up a query for post IDs to use later.
|
||||
|
@ -678,7 +678,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|||
$sql = $wpdb->prepare( $sql, array( $claim->get_id() ) );
|
||||
$result = $wpdb->query($sql);
|
||||
if ( $result === false ) {
|
||||
throw new RuntimeException( sprintf( __('Unable to unlock claim %s. Database error.', 'action-scheduler'), $claim->get_id() ) );
|
||||
throw new RuntimeException( sprintf( __('Unable to unlock claim %s. Database error.', 'woocommerce'), $claim->get_id() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,7 +692,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|||
$sql = $wpdb->prepare( $sql, $action_id, self::POST_TYPE );
|
||||
$result = $wpdb->query($sql);
|
||||
if ( $result === false ) {
|
||||
throw new RuntimeException( sprintf( __('Unable to unlock claim on action %s. Database error.', 'action-scheduler'), $action_id ) );
|
||||
throw new RuntimeException( sprintf( __('Unable to unlock claim on action %s. Database error.', 'woocommerce'), $action_id ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -703,7 +703,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|||
$sql = $wpdb->prepare( $sql, self::STATUS_FAILED, $action_id, self::POST_TYPE );
|
||||
$result = $wpdb->query($sql);
|
||||
if ( $result === false ) {
|
||||
throw new RuntimeException( sprintf( __('Unable to mark failure on action %s. Database error.', 'action-scheduler'), $action_id ) );
|
||||
throw new RuntimeException( sprintf( __('Unable to mark failure on action %s. Database error.', 'woocommerce'), $action_id ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -727,7 +727,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|||
$status = $this->get_post_column( $action_id, 'post_status' );
|
||||
|
||||
if ( $status === null ) {
|
||||
throw new InvalidArgumentException( __( 'Invalid action ID. No status found.', 'action-scheduler' ) );
|
||||
throw new InvalidArgumentException( __( 'Invalid action ID. No status found.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
return $this->get_action_status_by_post_status( $status );
|
||||
|
@ -755,7 +755,7 @@ class ActionScheduler_wpPostStore extends ActionScheduler_Store {
|
|||
public function mark_complete( $action_id ) {
|
||||
$post = get_post($action_id);
|
||||
if ( empty($post) || ($post->post_type != self::POST_TYPE) ) {
|
||||
throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
|
||||
throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'woocommerce'), $action_id));
|
||||
}
|
||||
add_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10, 1 );
|
||||
add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
|
||||
|
|
|
@ -33,8 +33,8 @@ class ActionScheduler_wpPostStore_PostStatusRegistrar {
|
|||
*/
|
||||
protected function post_status_failed_labels() {
|
||||
$labels = array(
|
||||
'label' => _x( 'Failed', 'post' ),
|
||||
'label_count' => _n_noop( 'Failed <span class="count">(%s)</span>', 'Failed <span class="count">(%s)</span>' ),
|
||||
'label' => _x( 'Failed', 'post', 'woocommerce' ),
|
||||
'label_count' => _n_noop( 'Failed <span class="count">(%s)</span>', 'Failed <span class="count">(%s)</span>', 'woocommerce' ),
|
||||
);
|
||||
|
||||
return apply_filters( 'action_scheduler_post_status_failed_labels', $labels );
|
||||
|
@ -47,11 +47,10 @@ class ActionScheduler_wpPostStore_PostStatusRegistrar {
|
|||
*/
|
||||
protected function post_status_running_labels() {
|
||||
$labels = array(
|
||||
'label' => _x( 'In-Progress', 'post' ),
|
||||
'label_count' => _n_noop( 'In-Progress <span class="count">(%s)</span>', 'In-Progress <span class="count">(%s)</span>' ),
|
||||
'label' => _x( 'In-Progress', 'post', 'woocommerce' ),
|
||||
'label_count' => _n_noop( 'In-Progress <span class="count">(%s)</span>', 'In-Progress <span class="count">(%s)</span>', 'woocommerce' ),
|
||||
);
|
||||
|
||||
return apply_filters( 'action_scheduler_post_status_running_labels', $labels );
|
||||
}
|
||||
}
|
||||
|
|
@ -30,9 +30,9 @@ class ActionScheduler_wpPostStore_PostTypeRegistrar {
|
|||
'name' => __( 'Scheduled Actions', 'woocommerce' ),
|
||||
'singular_name' => __( 'Scheduled Action', 'woocommerce' ),
|
||||
'menu_name' => _x( 'Scheduled Actions', 'Admin menu name', 'woocommerce' ),
|
||||
'add_new' => __( 'Add', 'action-scheduler' ),
|
||||
'add_new' => __( 'Add', 'woocommerce' ),
|
||||
'add_new_item' => __( 'Add New Scheduled Action', 'woocommerce' ),
|
||||
'edit' => __( 'Edit', 'action-scheduler' ),
|
||||
'edit' => __( 'Edit', 'woocommerce' ),
|
||||
'edit_item' => __( 'Edit Scheduled Action', 'woocommerce' ),
|
||||
'new_item' => __( 'New Scheduled Action', 'woocommerce' ),
|
||||
'view' => __( 'View Action', 'woocommerce' ),
|
||||
|
|
|
@ -11,7 +11,7 @@ class ActionScheduler_wpPostStore_TaxonomyRegistrar {
|
|||
|
||||
protected function taxonomy_args() {
|
||||
$args = array(
|
||||
'label' => __('Action Group', 'action-scheduler'),
|
||||
'label' => __('Action Group', 'woocommerce'),
|
||||
'public' => false,
|
||||
'hierarchical' => false,
|
||||
'show_admin_column' => true,
|
||||
|
@ -23,4 +23,3 @@ class ActionScheduler_wpPostStore_TaxonomyRegistrar {
|
|||
return $args;
|
||||
}
|
||||
}
|
||||
|
|
@ -179,7 +179,7 @@ class WC_Shortcode_Products {
|
|||
'post_status' => 'publish',
|
||||
'ignore_sticky_posts' => true,
|
||||
'no_found_rows' => false === wc_string_to_bool( $this->attributes['paginate'] ),
|
||||
'orderby' => empty( $_GET['orderby'] ) ? $this->attributes['orderby'] : wc_clean( wp_unslash( $_GET['orderby'] ) ), // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification
|
||||
'orderby' => empty( $_GET['orderby'] ) ? $this->attributes['orderby'] : wc_clean( wp_unslash( $_GET['orderby'] ) ), // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
);
|
||||
|
||||
$orderby_value = explode( '-', $query_args['orderby'] );
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
/**
|
||||
* Twenty Twenty support.
|
||||
*
|
||||
* @since 3.8.1
|
||||
* @package WooCommerce/Classes
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* WC_Twenty_Twenty class.
|
||||
*/
|
||||
class WC_Twenty_Twenty {
|
||||
|
||||
/**
|
||||
* Theme init.
|
||||
*/
|
||||
public static function init() {
|
||||
|
||||
// Change WooCommerce wrappers.
|
||||
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10 );
|
||||
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10 );
|
||||
|
||||
add_action( 'woocommerce_before_main_content', array( __CLASS__, 'output_content_wrapper' ), 10 );
|
||||
add_action( 'woocommerce_after_main_content', array( __CLASS__, 'output_content_wrapper_end' ), 10 );
|
||||
|
||||
// This theme doesn't have a traditional sidebar.
|
||||
remove_action( 'woocommerce_sidebar', 'woocommerce_get_sidebar', 10 );
|
||||
|
||||
// Enqueue theme compatibility styles.
|
||||
add_filter( 'woocommerce_enqueue_styles', array( __CLASS__, 'enqueue_styles' ) );
|
||||
|
||||
// Register theme features.
|
||||
add_theme_support( 'wc-product-gallery-zoom' );
|
||||
add_theme_support( 'wc-product-gallery-lightbox' );
|
||||
add_theme_support( 'wc-product-gallery-slider' );
|
||||
add_theme_support(
|
||||
'woocommerce',
|
||||
array(
|
||||
'thumbnail_image_width' => 450,
|
||||
'single_image_width' => 600,
|
||||
)
|
||||
);
|
||||
|
||||
// Background color change.
|
||||
add_action( 'after_setup_theme', array( __CLASS__, 'set_white_background' ), 10 );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the Twenty Twenty wrapper.
|
||||
*/
|
||||
public static function output_content_wrapper() {
|
||||
echo '<section id="primary" class="content-area">';
|
||||
echo '<main id="main" class="site-main">';
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the Twenty Twenty wrapper.
|
||||
*/
|
||||
public static function output_content_wrapper_end() {
|
||||
echo '</main>';
|
||||
echo '</section>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set background color to white if it's default, otherwise don't touch it.
|
||||
*/
|
||||
public static function set_white_background() {
|
||||
$background = sanitize_hex_color_no_hash( get_theme_mod( 'background_color' ) );
|
||||
$background_default = 'f5efe0';
|
||||
|
||||
// Don't change user's choice of background color.
|
||||
if ( ! empty( $background ) && $background !== $background_default ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// In case default background is found, change it to white.
|
||||
set_theme_mod( 'background_color', 'fff' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue CSS for this theme.
|
||||
*
|
||||
* @param array $styles Array of registered styles.
|
||||
* @return array
|
||||
*/
|
||||
public static function enqueue_styles( $styles ) {
|
||||
unset( $styles['woocommerce-general'] );
|
||||
|
||||
$styles['woocommerce-general'] = array(
|
||||
'src' => str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/css/twenty-twenty.css',
|
||||
'deps' => '',
|
||||
'version' => WC_VERSION,
|
||||
'media' => 'all',
|
||||
'has_rtl' => true,
|
||||
);
|
||||
|
||||
return apply_filters( 'woocommerce_twenty_twenty_styles', $styles );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WC_Twenty_Twenty::init();
|
|
@ -611,7 +611,7 @@ function wc_create_attribute( $args ) {
|
|||
// Clear cache and flush rewrite rules.
|
||||
wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' );
|
||||
delete_transient( 'wc_attribute_taxonomies' );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' );
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
@ -701,7 +701,7 @@ function wc_delete_attribute( $id ) {
|
|||
do_action( 'woocommerce_attribute_deleted', $id, $name, $taxonomy );
|
||||
wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' );
|
||||
delete_transient( 'wc_attribute_taxonomies' );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1826,7 +1826,7 @@ function wc_print_r( $expression, $return = false ) {
|
|||
|
||||
foreach ( $alternatives as $alternative ) {
|
||||
if ( function_exists( $alternative['func'] ) ) {
|
||||
$res = call_user_func_array( $alternative['func'], $alternative['args'] );
|
||||
$res = $alternative['func']( ...$alternative['args'] );
|
||||
if ( $return ) {
|
||||
return $res;
|
||||
}
|
||||
|
|
|
@ -136,9 +136,12 @@ function wc_print_notices( $return = false ) {
|
|||
|
||||
foreach ( $notice_types as $notice_type ) {
|
||||
if ( wc_notice_count( $notice_type ) > 0 ) {
|
||||
wc_get_template( "notices/{$notice_type}.php", array(
|
||||
wc_get_template(
|
||||
"notices/{$notice_type}.php",
|
||||
array(
|
||||
'messages' => array_filter( $all_notices[ $notice_type ] ),
|
||||
) );
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,9 +168,12 @@ function wc_print_notice( $message, $notice_type = 'success' ) {
|
|||
$message = apply_filters( 'woocommerce_add_message', $message );
|
||||
}
|
||||
|
||||
wc_get_template( "notices/{$notice_type}.php", array(
|
||||
wc_get_template(
|
||||
"notices/{$notice_type}.php",
|
||||
array(
|
||||
'messages' => array( apply_filters( 'woocommerce_add_' . $notice_type, $message ) ),
|
||||
) );
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -217,14 +223,20 @@ function wc_add_wp_error_notices( $errors ) {
|
|||
* @return string
|
||||
*/
|
||||
function wc_kses_notice( $message ) {
|
||||
return wp_kses( $message,
|
||||
array_replace_recursive( // phpcs:ignore PHPCompatibility.PHP.NewFunctions.array_replace_recursiveFound
|
||||
$allowed_tags = array_replace_recursive(
|
||||
wp_kses_allowed_html( 'post' ),
|
||||
array(
|
||||
'a' => array(
|
||||
'tabindex' => true,
|
||||
),
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Kses notice allowed tags.
|
||||
*
|
||||
* @since 3.9.0
|
||||
* @param array[]|string $allowed_tags An array of allowed HTML elements and attributes, or a context name such as 'post'.
|
||||
*/
|
||||
return wp_kses( $message, apply_filters( 'woocommerce_kses_notice_allowed_tags', $allowed_tags ) );
|
||||
}
|
||||
|
|
|
@ -464,7 +464,7 @@ function wc_delete_shop_order_transients( $order = 0 ) {
|
|||
WC_Cache_Helper::get_transient_version( 'orders', true );
|
||||
|
||||
// Do the same for regular cache.
|
||||
WC_Cache_Helper::incr_cache_prefix( 'orders' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'orders' );
|
||||
|
||||
do_action( 'woocommerce_delete_shop_order_transients', $order_id );
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ function wc_delete_order_item( $item_id ) {
|
|||
function wc_update_order_item_meta( $item_id, $meta_key, $meta_value, $prev_value = '' ) {
|
||||
$data_store = WC_Data_Store::load( 'order-item' );
|
||||
if ( $data_store->update_metadata( $item_id, $meta_key, $meta_value, $prev_value ) ) {
|
||||
WC_Cache_Helper::incr_cache_prefix( 'object_' . $item_id ); // Invalidate cache.
|
||||
WC_Cache_Helper::invalidate_cache_group( 'object_' . $item_id ); // Invalidate cache.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -126,7 +126,7 @@ function wc_add_order_item_meta( $item_id, $meta_key, $meta_value, $unique = fal
|
|||
$meta_id = $data_store->add_metadata( $item_id, $meta_key, $meta_value, $unique );
|
||||
|
||||
if ( $meta_id ) {
|
||||
WC_Cache_Helper::incr_cache_prefix( 'object_' . $item_id ); // Invalidate cache.
|
||||
WC_Cache_Helper::invalidate_cache_group( 'object_' . $item_id ); // Invalidate cache.
|
||||
return $meta_id;
|
||||
}
|
||||
return 0;
|
||||
|
@ -146,7 +146,7 @@ function wc_add_order_item_meta( $item_id, $meta_key, $meta_value, $unique = fal
|
|||
function wc_delete_order_item_meta( $item_id, $meta_key, $meta_value = '', $delete_all = false ) {
|
||||
$data_store = WC_Data_Store::load( 'order-item' );
|
||||
if ( $data_store->delete_metadata( $item_id, $meta_key, $meta_value, $delete_all ) ) {
|
||||
WC_Cache_Helper::incr_cache_prefix( 'object_' . $item_id ); // Invalidate cache.
|
||||
WC_Cache_Helper::invalidate_cache_group( 'object_' . $item_id ); // Invalidate cache.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -715,7 +715,7 @@ function wc_get_product_attachment_props( $attachment_id = null, $product = fals
|
|||
);
|
||||
$attachment = get_post( $attachment_id );
|
||||
|
||||
if ( $attachment ) {
|
||||
if ( $attachment && 'attachment' === $attachment->post_type ) {
|
||||
$props['title'] = wp_strip_all_tags( $attachment->post_title );
|
||||
$props['caption'] = wp_strip_all_tags( $attachment->post_excerpt );
|
||||
$props['url'] = wp_get_attachment_url( $attachment_id );
|
||||
|
|
|
@ -253,11 +253,10 @@ function wc_product_dropdown_categories( $args = array() ) {
|
|||
*
|
||||
* Previously used by wc_product_dropdown_categories, but wp_dropdown_categories has been fixed in core.
|
||||
*
|
||||
* @param mixed ...$args Variable number of parameters to be passed to the walker.
|
||||
* @return mixed
|
||||
*/
|
||||
function wc_walk_category_dropdown_tree() {
|
||||
$args = func_get_args();
|
||||
|
||||
function wc_walk_category_dropdown_tree( ...$args ) {
|
||||
if ( ! class_exists( 'WC_Product_Cat_Dropdown_Walker', false ) ) {
|
||||
include_once WC()->plugin_path() . '/includes/walkers/class-wc-product-cat-dropdown-walker.php';
|
||||
}
|
||||
|
@ -269,7 +268,7 @@ function wc_walk_category_dropdown_tree() {
|
|||
$walker = $args[2]['walker'];
|
||||
}
|
||||
|
||||
return call_user_func_array( array( &$walker, 'walk' ), $args );
|
||||
return $walker->walk( ...$args );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -674,7 +674,7 @@ function wc_update_220_attributes() {
|
|||
}
|
||||
|
||||
delete_transient( 'wc_attribute_taxonomies' );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,6 +15,13 @@ defined( 'ABSPATH' ) || exit;
|
|||
*/
|
||||
class WC_WCCOM_Site_Installer {
|
||||
|
||||
/**
|
||||
* Error message returned install_package if the folder already exists.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $folder_exists = 'folder_exists';
|
||||
|
||||
/**
|
||||
* Default state.
|
||||
*
|
||||
|
@ -240,6 +247,7 @@ class WC_WCCOM_Site_Installer {
|
|||
case 'get_product_info':
|
||||
$state_steps[ $product_id ]['download_url'] = $result['download_url'];
|
||||
$state_steps[ $product_id ]['product_type'] = $result['product_type'];
|
||||
$state_steps[ $product_id ]['product_name'] = $result['product_name'];
|
||||
break;
|
||||
case 'download_product':
|
||||
$state_steps[ $product_id ]['download_path'] = $result;
|
||||
|
@ -249,6 +257,12 @@ class WC_WCCOM_Site_Installer {
|
|||
break;
|
||||
case 'move_product':
|
||||
$state_steps[ $product_id ]['installed_path'] = $result['destination'];
|
||||
if ( $result[ self::$folder_exists ] ) {
|
||||
$state_steps[ $product_id ]['warning'] = array(
|
||||
'message' => self::$folder_exists,
|
||||
'plugin_info' => self::get_plugin_info( $state_steps[ $product_id ]['installed_path'] ),
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -287,6 +301,7 @@ class WC_WCCOM_Site_Installer {
|
|||
$result = json_decode( wp_remote_retrieve_body( $request ), true );
|
||||
|
||||
$product_info['product_type'] = $result['_product_type'];
|
||||
$product_info['product_name'] = $result['name'];
|
||||
|
||||
if ( ! empty( $result['_wporg_product'] ) && ! empty( $result['download_link'] ) ) {
|
||||
// For wporg product, download is set already from info response.
|
||||
|
@ -369,7 +384,18 @@ class WC_WCCOM_Site_Installer {
|
|||
),
|
||||
);
|
||||
|
||||
return $upgrader->install_package( $package );
|
||||
$result = $upgrader->install_package( $package );
|
||||
|
||||
/**
|
||||
* If install package returns error 'folder_exists' threat as success.
|
||||
*/
|
||||
if ( is_wp_error( $result ) && array_key_exists( self::$folder_exists, $result->errors ) ) {
|
||||
return array(
|
||||
self::$folder_exists => true,
|
||||
'destination' => $result->error_data[ self::$folder_exists ],
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -511,4 +537,41 @@ class WC_WCCOM_Site_Installer {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get plugin info
|
||||
*
|
||||
* @since 3.9.0
|
||||
* @param string $dir Directory name of the plugin.
|
||||
* @return bool|array
|
||||
*/
|
||||
private static function get_plugin_info( $dir ) {
|
||||
$plugin_folder = basename( $dir );
|
||||
|
||||
if ( ! function_exists( 'get_plugins' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
$plugins = get_plugins();
|
||||
|
||||
$related_plugins = array_filter(
|
||||
$plugins,
|
||||
function( $key ) use ( $plugin_folder ) {
|
||||
return strpos( $key, $plugin_folder . '/' ) === 0;
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
|
||||
if ( 1 === count( $related_plugins ) ) {
|
||||
$plugin_key = array_keys( $related_plugins )[0];
|
||||
$plugin_data = $plugins[ $plugin_key ];
|
||||
return array(
|
||||
'name' => $plugin_data['Name'],
|
||||
'version' => $plugin_data['Version'],
|
||||
'active' => is_plugin_active( $plugin_key ),
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ defined( 'ABSPATH' ) || exit;
|
|||
*/
|
||||
class WC_WCCOM_Site {
|
||||
|
||||
const AUTH_ERROR_FILTER_NAME = 'wccom_auth_error';
|
||||
|
||||
/**
|
||||
* Load the WCCOM site class.
|
||||
*
|
||||
|
@ -53,23 +55,78 @@ class WC_WCCOM_Site {
|
|||
|
||||
$auth_header = self::get_authorization_header();
|
||||
if ( empty( $auth_header ) ) {
|
||||
add_filter(
|
||||
self::AUTH_ERROR_FILTER_NAME,
|
||||
function() {
|
||||
return new WP_Error(
|
||||
WC_REST_WCCOM_Site_Installer_Errors::NO_AUTH_HEADER_CODE,
|
||||
WC_REST_WCCOM_Site_Installer_Errors::NO_AUTH_HEADER_MESSAGE,
|
||||
array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::NO_AUTH_HEADER_HTTP_CODE )
|
||||
);
|
||||
}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$request_auth = trim( $auth_header );
|
||||
if ( stripos( $request_auth, 'Bearer ' ) !== 0 ) {
|
||||
add_filter(
|
||||
self::AUTH_ERROR_FILTER_NAME,
|
||||
function() {
|
||||
return new WP_Error(
|
||||
WC_REST_WCCOM_Site_Installer_Errors::INVALID_AUTH_HEADER_CODE,
|
||||
WC_REST_WCCOM_Site_Installer_Errors::INVALID_AUTH_HEADER_MESSAGE,
|
||||
array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::INVALID_AUTH_HEADER_HTTP_CODE )
|
||||
);
|
||||
}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $_SERVER['HTTP_X_WOO_SIGNATURE'] ) ) {
|
||||
add_filter(
|
||||
self::AUTH_ERROR_FILTER_NAME,
|
||||
function() {
|
||||
return new WP_Error(
|
||||
WC_REST_WCCOM_Site_Installer_Errors::NO_SIGNATURE_HEADER_CODE,
|
||||
WC_REST_WCCOM_Site_Installer_Errors::NO_SIGNATURE_HEADER_MESSAGE,
|
||||
array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::NO_SIGNATURE_HEADER_HTTP_CODE )
|
||||
);
|
||||
}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
require_once WC_ABSPATH . 'includes/admin/helper/class-wc-helper-options.php';
|
||||
$access_token = trim( substr( $request_auth, 7 ) );
|
||||
$site_auth = WC_Helper_Options::get( 'auth' );
|
||||
if ( empty( $site_auth['access_token'] ) || ! hash_equals( $access_token, $site_auth['access_token'] ) ) {
|
||||
|
||||
if ( empty( $site_auth['access_token'] ) ) {
|
||||
add_filter(
|
||||
self::AUTH_ERROR_FILTER_NAME,
|
||||
function() {
|
||||
return new WP_Error(
|
||||
WC_REST_WCCOM_Site_Installer_Errors::SITE_NOT_CONNECTED_CODE,
|
||||
WC_REST_WCCOM_Site_Installer_Errors::SITE_NOT_CONNECTED_MESSAGE,
|
||||
array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::SITE_NOT_CONNECTED_HTTP_CODE )
|
||||
);
|
||||
}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! hash_equals( $access_token, $site_auth['access_token'] ) ) {
|
||||
add_filter(
|
||||
self::AUTH_ERROR_FILTER_NAME,
|
||||
function() {
|
||||
return new WP_Error(
|
||||
WC_REST_WCCOM_Site_Installer_Errors::INVALID_TOKEN_CODE,
|
||||
WC_REST_WCCOM_Site_Installer_Errors::INVALID_TOKEN_MESSAGE,
|
||||
array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::INVALID_TOKEN_HTTP_CODE )
|
||||
);
|
||||
}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -77,11 +134,31 @@ class WC_WCCOM_Site {
|
|||
$signature = trim( $_SERVER['HTTP_X_WOO_SIGNATURE'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
|
||||
if ( ! self::verify_wccom_request( $body, $signature, $site_auth['access_token_secret'] ) ) {
|
||||
add_filter(
|
||||
self::AUTH_ERROR_FILTER_NAME,
|
||||
function() {
|
||||
return new WP_Error(
|
||||
WC_REST_WCCOM_Site_Installer_Errors::REQUEST_VERIFICATION_FAILED_CODE,
|
||||
WC_REST_WCCOM_Site_Installer_Errors::REQUEST_VERIFICATION_FAILED_MESSAGE,
|
||||
array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::REQUEST_VERIFICATION_FAILED_HTTP_CODE )
|
||||
);
|
||||
}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
$user = get_user_by( 'id', $site_auth['user_id'] );
|
||||
if ( ! $user ) {
|
||||
add_filter(
|
||||
self::AUTH_ERROR_FILTER_NAME,
|
||||
function() {
|
||||
return new WP_Error(
|
||||
WC_REST_WCCOM_Site_Installer_Errors::USER_NOT_FOUND_CODE,
|
||||
WC_REST_WCCOM_Site_Installer_Errors::USER_NOT_FOUND_MESSAGE,
|
||||
array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::USER_NOT_FOUND_HTTP_CODE )
|
||||
);
|
||||
}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -166,6 +243,7 @@ class WC_WCCOM_Site {
|
|||
* @return array Registered namespaces.
|
||||
*/
|
||||
public static function register_rest_namespace( $namespaces ) {
|
||||
require_once WC_ABSPATH . 'includes/wccom-site/rest-api/class-wc-rest-wccom-site-installer-errors.php';
|
||||
require_once WC_ABSPATH . 'includes/wccom-site/rest-api/endpoints/class-wc-rest-wccom-site-installer-controller.php';
|
||||
|
||||
$namespaces['wccom-site/v1'] = array(
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
/**
|
||||
* WCCOM Site Installer Errors Class
|
||||
*
|
||||
* @package WooCommerce\WooCommerce_Site\Rest_Api
|
||||
* @since 3.9.0
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* WCCOM Site Installer Errors Class
|
||||
*
|
||||
* Stores data for errors, returned by installer API.
|
||||
*/
|
||||
class WC_REST_WCCOM_Site_Installer_Errors {
|
||||
|
||||
/**
|
||||
* Not unauthenticated generic error
|
||||
*/
|
||||
const NOT_AUTHENTICATED_CODE = 'not_authenticated';
|
||||
const NOT_AUTHENTICATED_MESSAGE = 'Authentication required';
|
||||
const NOT_AUTHENTICATED_HTTP_CODE = 401;
|
||||
|
||||
/**
|
||||
* No Authorization header
|
||||
*/
|
||||
const NO_AUTH_HEADER_CODE = 'no_auth_header';
|
||||
const NO_AUTH_HEADER_MESSAGE = 'No header "Authorization" present';
|
||||
const NO_AUTH_HEADER_HTTP_CODE = 400;
|
||||
|
||||
/**
|
||||
* Authorization header invalid
|
||||
*/
|
||||
const INVALID_AUTH_HEADER_CODE = 'no_auth_header';
|
||||
const INVALID_AUTH_HEADER_MESSAGE = 'Header "Authorization" is invalid';
|
||||
const INVALID_AUTH_HEADER_HTTP_CODE = 400;
|
||||
|
||||
/**
|
||||
* No Signature header
|
||||
*/
|
||||
const NO_SIGNATURE_HEADER_CODE = 'no_signature_header';
|
||||
const NO_SIGNATURE_HEADER_MESSAGE = 'No header "X-Woo-Signature" present';
|
||||
const NO_SIGNATURE_HEADER_HTTP_CODE = 400;
|
||||
|
||||
/**
|
||||
* Site not connected to WooCommerce.com
|
||||
*/
|
||||
const SITE_NOT_CONNECTED_CODE = 'site_not_connnected';
|
||||
const SITE_NOT_CONNECTED_MESSAGE = 'Site not connected to WooCommerce.com';
|
||||
const SITE_NOT_CONNECTED_HTTP_CODE = 401;
|
||||
|
||||
/**
|
||||
* Provided access token is not valid
|
||||
*/
|
||||
const INVALID_TOKEN_CODE = 'invalid_token';
|
||||
const INVALID_TOKEN_MESSAGE = 'Invalid access token provided';
|
||||
const INVALID_TOKEN_HTTP_CODE = 401;
|
||||
|
||||
/**
|
||||
* Request verification by provided signature failed
|
||||
*/
|
||||
const REQUEST_VERIFICATION_FAILED_CODE = 'request_verification_failed';
|
||||
const REQUEST_VERIFICATION_FAILED_MESSAGE = 'Request verification by signature failed';
|
||||
const REQUEST_VERIFICATION_FAILED_HTTP_CODE = 400;
|
||||
|
||||
/**
|
||||
* User doesn't exist
|
||||
*/
|
||||
const USER_NOT_FOUND_CODE = 'user_not_found';
|
||||
const USER_NOT_FOUND_MESSAGE = 'Token owning user not found';
|
||||
const USER_NOT_FOUND_HTTP_CODE = 401;
|
||||
|
||||
/**
|
||||
* No permissions error
|
||||
*/
|
||||
const NO_PERMISSION_CODE = 'forbidden';
|
||||
const NO_PERMISSION_MESSAGE = 'You do not have permission to install plugin or theme';
|
||||
const NO_PERMISSION_HTTP_CODE = 403;
|
||||
}
|
|
@ -69,8 +69,25 @@ class WC_REST_WCCOM_Site_Installer_Controller extends WC_REST_Controller {
|
|||
* @return bool|WP_Error
|
||||
*/
|
||||
public function check_permission( $request ) {
|
||||
if ( ! current_user_can( 'install_plugins' ) || ! current_user_can( 'install_themes' ) ) {
|
||||
return new WP_Error( 'woocommerce_rest_cannot_install_product', __( 'You do not have permission to install plugin or theme', 'woocommerce' ), array( 'status' => 401 ) );
|
||||
$current_user = wp_get_current_user();
|
||||
|
||||
if ( empty( $current_user ) || ( $current_user instanceof WP_User && ! $current_user->exists() ) ) {
|
||||
return apply_filters(
|
||||
WC_WCCOM_Site::AUTH_ERROR_FILTER_NAME,
|
||||
new WP_Error(
|
||||
WC_REST_WCCOM_Site_Installer_Errors::NOT_AUTHENTICATED_CODE,
|
||||
WC_REST_WCCOM_Site_Installer_Errors::NOT_AUTHENTICATED_MESSAGE,
|
||||
array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::NOT_AUTHENTICATED_HTTP_CODE )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! user_can( $current_user, 'install_plugins' ) || ! user_can( $current_user, 'install_themes' ) ) {
|
||||
return new WP_Error(
|
||||
WC_REST_WCCOM_Site_Installer_Errors::NO_PERMISSION_CODE,
|
||||
WC_REST_WCCOM_Site_Installer_Errors::NO_PERMISSION_MESSAGE,
|
||||
array( 'status' => WC_REST_WCCOM_Site_Installer_Errors::NO_PERMISSION_HTTP_CODE )
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -193,7 +193,7 @@ class WC_Widget_Products extends WC_Widget {
|
|||
echo wp_kses_post( apply_filters( 'woocommerce_before_widget_product_list', '<ul class="product_list_widget">' ) );
|
||||
|
||||
$template_args = array(
|
||||
'widget_id' => $args['widget_id'],
|
||||
'widget_id' => isset( $args['widget_id'] ) ? $args['widget_id'] : $this->widget_id,
|
||||
'show_rating' => true,
|
||||
);
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ class WC_Widget_Recently_Viewed extends WC_Widget {
|
|||
echo wp_kses_post( apply_filters( 'woocommerce_before_widget_product_list', '<ul class="product_list_widget">' ) );
|
||||
|
||||
$template_args = array(
|
||||
'widget_id' => $args['widget_id'],
|
||||
'widget_id' => isset( $args['widget_id'] ) ? $args['widget_id'] : $this->widget_id,
|
||||
);
|
||||
|
||||
while ( $r->have_posts() ) {
|
||||
|
|
|
@ -79,7 +79,7 @@ class WC_Widget_Top_Rated_Products extends WC_Widget {
|
|||
echo wp_kses_post( apply_filters( 'woocommerce_before_widget_product_list', '<ul class="product_list_widget">' ) );
|
||||
|
||||
$template_args = array(
|
||||
'widget_id' => $args['widget_id'],
|
||||
'widget_id' => isset( $args['widget_id'] ) ? $args['widget_id'] : $this->widget_id,
|
||||
'show_rating' => true,
|
||||
);
|
||||
|
||||
|
|
|
@ -3967,13 +3967,13 @@
|
|||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
|
||||
},
|
||||
"autoprefixer": {
|
||||
"version": "9.7.2",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.2.tgz",
|
||||
"integrity": "sha512-LCAfcdej1182uVvPOZnytbq61AhnOZ/4JelDaJGDeNwewyU1AMaNthcHsyz1NRjTmd2FkurMckLWfkHg3Z//KA==",
|
||||
"version": "9.7.3",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.3.tgz",
|
||||
"integrity": "sha512-8T5Y1C5Iyj6PgkPSFd0ODvK9DIleuPKUPYniNxybS47g2k2wFgLZ46lGQHlBuGKIAEV8fbCDfKCCRS1tvOgc3Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browserslist": "^4.7.3",
|
||||
"caniuse-lite": "^1.0.30001010",
|
||||
"browserslist": "^4.8.0",
|
||||
"caniuse-lite": "^1.0.30001012",
|
||||
"chalk": "^2.4.2",
|
||||
"normalize-range": "^0.1.2",
|
||||
"num2fraction": "^1.2.2",
|
||||
|
@ -3982,26 +3982,26 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"browserslist": {
|
||||
"version": "4.7.3",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.3.tgz",
|
||||
"integrity": "sha512-jWvmhqYpx+9EZm/FxcZSbUZyDEvDTLDi3nSAKbzEkyWvtI0mNSmUosey+5awDW1RUlrgXbQb5A6qY1xQH9U6MQ==",
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.0.tgz",
|
||||
"integrity": "sha512-HYnxc/oLRWvJ3TsGegR0SRL/UDnknGq2s/a8dYYEO+kOQ9m9apKoS5oiathLKZdh/e9uE+/J3j92qPlGD/vTqA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"caniuse-lite": "^1.0.30001010",
|
||||
"electron-to-chromium": "^1.3.306",
|
||||
"node-releases": "^1.1.40"
|
||||
"caniuse-lite": "^1.0.30001012",
|
||||
"electron-to-chromium": "^1.3.317",
|
||||
"node-releases": "^1.1.41"
|
||||
}
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001011",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001011.tgz",
|
||||
"integrity": "sha512-h+Eqyn/YA6o6ZTqpS86PyRmNWOs1r54EBDcd2NTwwfsXQ8re1B38SnB+p2RKF8OUsyEIjeDU8XGec1RGO/wYCg==",
|
||||
"version": "1.0.30001013",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001013.tgz",
|
||||
"integrity": "sha512-hOAXaWKuq/UVFgYawxIOdPdyMQdYcwOCDOjnZcKn7wCgFUrhP7smuNZjGLuJlPSgE6aRA4cRJ+bGSrhtEt7ZAg==",
|
||||
"dev": true
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.3.311",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.311.tgz",
|
||||
"integrity": "sha512-7GH6RKCzziLzJ9ejmbiBEdzHZsc6C3eRpav14dmRfTWMpNgMqpP1ukw/FU/Le2fR+ep642naq7a23xNdmh2s+A==",
|
||||
"version": "1.3.322",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz",
|
||||
"integrity": "sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA==",
|
||||
"dev": true
|
||||
},
|
||||
"node-releases": {
|
||||
|
@ -6167,9 +6167,9 @@
|
|||
}
|
||||
},
|
||||
"eslint": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.0.tgz",
|
||||
"integrity": "sha512-dQpj+PaHKHfXHQ2Imcw5d853PTvkUGbHk/MR68KQUl98EgKDCdh4vLRH1ZxhqeQjQFJeg8fgN0UwmNhN3l8dDQ==",
|
||||
"version": "6.7.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.2.tgz",
|
||||
"integrity": "sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
|
@ -6616,9 +6616,9 @@
|
|||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
|
||||
},
|
||||
"fast-glob": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.0.tgz",
|
||||
"integrity": "sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==",
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz",
|
||||
"integrity": "sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
|
@ -8337,9 +8337,9 @@
|
|||
}
|
||||
},
|
||||
"grunt-rtlcss": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/grunt-rtlcss/-/grunt-rtlcss-2.0.1.tgz",
|
||||
"integrity": "sha1-6eYc5DdAY5f546Sxv2aeR+cf/MM=",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/grunt-rtlcss/-/grunt-rtlcss-2.0.2.tgz",
|
||||
"integrity": "sha512-WbI2thnwlF04N+xvJu+NxqEaCyPuLyar196SYhEQFZ2EJHkOS8YYE+Zkh+X9cWhwAtKp7ZEpR/IKXcyQggOIsQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^1.0.0",
|
||||
|
@ -11361,9 +11361,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"lint-staged": {
|
||||
"version": "9.4.3",
|
||||
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.4.3.tgz",
|
||||
"integrity": "sha512-PejnI+rwOAmKAIO+5UuAZU9gxdej/ovSEOAY34yMfC3OS4Ac82vCBPzAWLReR9zCPOMqeVwQRaZ3bUBpAsaL2Q==",
|
||||
"version": "9.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.5.0.tgz",
|
||||
"integrity": "sha512-nawMob9cb/G1J98nb8v3VC/E8rcX1rryUYXVZ69aT9kde6YWX+uvNOEHY5yf2gcWcTJGiD0kqXmCnS3oD75GIA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^2.4.2",
|
||||
|
@ -14434,15 +14434,15 @@
|
|||
"integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA=="
|
||||
},
|
||||
"rtlcss": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-2.4.0.tgz",
|
||||
"integrity": "sha512-hdjFhZ5FCI0ABOfyXOMOhBtwPWtANLCG7rOiOcRf+yi5eDdxmDjqBruWouEnwVdzfh/TWF6NNncIEsigOCFZOA==",
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-2.4.1.tgz",
|
||||
"integrity": "sha512-pOY30CIGvvQTW1iBfxO6Ry6/J/C4U7fcOhtF0pm5fNgwmJXOtx5gib6czFmWyp1KXN/6rbMRsTZwWlAridxBTQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^2.3.0",
|
||||
"chalk": "^2.4.2",
|
||||
"findup": "^0.1.5",
|
||||
"mkdirp": "^0.5.1",
|
||||
"postcss": "^6.0.14",
|
||||
"postcss": "^6.0.23",
|
||||
"strip-json-comments": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
"@babel/preset-env": "^7.5.5",
|
||||
"@babel/register": "^7.5.5",
|
||||
"@wordpress/e2e-test-utils": "^2.2.0",
|
||||
"autoprefixer": "9.7.2",
|
||||
"autoprefixer": "9.7.3",
|
||||
"babel-eslint": "10.0.3",
|
||||
"chai": "4.2.0",
|
||||
"chai-as-promised": "7.1.1",
|
||||
|
@ -33,7 +33,7 @@
|
|||
"eslint-plugin-jest": "22.13.6",
|
||||
"config": "3.2.4",
|
||||
"cross-env": "6.0.3",
|
||||
"eslint": "6.7.0",
|
||||
"eslint": "6.7.2",
|
||||
"eslint-config-wpcalypso": "5.0.0",
|
||||
"github-contributors-list": "https://github.com/woocommerce/github-contributors-list/tarball/master",
|
||||
"grunt": "1.0.4",
|
||||
|
@ -48,7 +48,7 @@
|
|||
"grunt-phpcs": "0.4.0",
|
||||
"grunt-postcss": "0.9.0",
|
||||
"grunt-prompt": "1.3.3",
|
||||
"grunt-rtlcss": "2.0.1",
|
||||
"grunt-rtlcss": "2.0.2",
|
||||
"grunt-sass": "3.1.0",
|
||||
"grunt-shell": "3.0.1",
|
||||
"grunt-stylelint": "0.12.0",
|
||||
|
@ -57,7 +57,7 @@
|
|||
"istanbul": "1.0.0-alpha.2",
|
||||
"jest": "24.8.0",
|
||||
"jest-puppeteer": "4.3.0",
|
||||
"lint-staged": "9.4.3",
|
||||
"lint-staged": "9.5.0",
|
||||
"mocha": "6.2.2",
|
||||
"node-sass": "4.13.0",
|
||||
"prettier": "github:automattic/calypso-prettier#c56b4251",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Contributors: automattic, mikejolley, jameskoster, claudiosanches, kloon, rodrigosprimo, peterfabian1000, vedjain
|
||||
Tags: ecommerce, e-commerce, store, sales, sell, shop, cart, checkout, downloadable, downloads, payments, paypal, storefront, stripe, woo commerce, woo
|
||||
Requires at least: 4.9
|
||||
Tested up to: 5.2
|
||||
Tested up to: 5.3
|
||||
Requires PHP: 5.6
|
||||
Stable tag: 3.8.0
|
||||
License: GPLv3
|
||||
|
|
|
@ -48,7 +48,6 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
* The woocommerce_review_meta hook.
|
||||
*
|
||||
* @hooked woocommerce_review_display_meta - 10
|
||||
* @hooked WC_Structured_Data::generate_review_data() - 20
|
||||
*/
|
||||
do_action( 'woocommerce_review_meta', $comment );
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
if [[ ${RUN_E2E} == 1 ]]; then
|
||||
npm install
|
||||
npm run test:e2e
|
||||
fi
|
||||
echo "Waiting for 5 minutes for the Docker container to start...";
|
||||
sleep 300;
|
||||
npm run test:e2e;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/** @format */
|
||||
|
||||
module.exports = {
|
||||
launch: {
|
||||
// Required for the logged out and logged in tests so they don't share app state/token.
|
||||
browserContext: 'incognito',
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { createSimpleProduct } from '../../utils/components';
|
||||
import { CustomerFlow, StoreOwnerFlow } from '../../utils/flows';
|
||||
import { uiUnblocked } from '../../utils';
|
||||
|
||||
describe( 'Cart page', () => {
|
||||
beforeAll( async () => {
|
||||
await StoreOwnerFlow.login();
|
||||
await createSimpleProduct();
|
||||
await StoreOwnerFlow.logout();
|
||||
} );
|
||||
|
||||
it( 'should displays no item in the cart', async () => {
|
||||
await CustomerFlow.goToCart();
|
||||
await expect( page ).toMatchElement( '.cart-empty', { text: 'Your cart is currently empty.' } );
|
||||
} );
|
||||
|
||||
it( 'should add the product to the cart when "Add to cart" is clicked', async () => {
|
||||
await CustomerFlow.goToShop();
|
||||
await CustomerFlow.addToCartFromShopPage( 'Simple product' );
|
||||
|
||||
await CustomerFlow.goToCart();
|
||||
await CustomerFlow.productIsInCart( 'Simple product' );
|
||||
} );
|
||||
|
||||
it( 'should increase item qty when "Add to cart" of the same product is clicked', async () => {
|
||||
await CustomerFlow.goToShop();
|
||||
await CustomerFlow.addToCartFromShopPage( 'Simple product' );
|
||||
|
||||
await CustomerFlow.goToCart();
|
||||
await CustomerFlow.productIsInCart( 'Simple product', 2 );
|
||||
} );
|
||||
|
||||
it( 'should update qty when updated via qty input', async () => {
|
||||
await CustomerFlow.goToCart();
|
||||
await CustomerFlow.setCartQuantity( 'Simple product', 4 );
|
||||
await expect( page ).toClick( 'button', { text: 'Update cart' } );
|
||||
await uiUnblocked();
|
||||
|
||||
await CustomerFlow.productIsInCart( 'Simple product', 4 );
|
||||
} );
|
||||
|
||||
it( 'should remove the item from the cart when remove is clicked', async () => {
|
||||
await CustomerFlow.goToCart();
|
||||
await CustomerFlow.removeFromCart( 'Simple product' );
|
||||
await uiUnblocked();
|
||||
|
||||
await expect( page ).toMatchElement( '.cart-empty', { text: 'Your cart is currently empty.' } );
|
||||
} );
|
||||
|
||||
it( 'should update subtotal in cart totals when adding product to the cart', async () => {
|
||||
await CustomerFlow.goToShop();
|
||||
await CustomerFlow.addToCartFromShopPage( 'Simple product' );
|
||||
|
||||
await CustomerFlow.goToCart();
|
||||
await CustomerFlow.productIsInCart( 'Simple product', 1 );
|
||||
await expect( page ).toMatchElement( '.cart-subtotal .amount', { text: '$9.99' } );
|
||||
|
||||
await CustomerFlow.setCartQuantity( 'Simple product', 2 );
|
||||
await expect( page ).toClick( 'button', { text: 'Update cart' } );
|
||||
await uiUnblocked();
|
||||
|
||||
await expect( page ).toMatchElement( '.cart-subtotal .amount', { text: '$19.98' } );
|
||||
} );
|
||||
|
||||
it( 'should go to the checkout page when "Proceed to Checkout" is clicked', async () => {
|
||||
await CustomerFlow.goToCart();
|
||||
await Promise.all( [
|
||||
page.waitForNavigation( { waitUntil: 'networkidle0' } ),
|
||||
expect( page ).toClick( '.checkout-button', { text: 'Proceed to checkout' } ),
|
||||
] );
|
||||
|
||||
await expect( page ).toMatchElement( '#order_review' );
|
||||
} );
|
||||
} );
|
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { CustomerFlow, StoreOwnerFlow } from '../../utils/flows';
|
||||
|
||||
describe( 'My account page', () => {
|
||||
it( 'allows customer to login', async () => {
|
||||
await StoreOwnerFlow.logout();
|
||||
await CustomerFlow.login();
|
||||
await expect( page ).toMatch( 'Hello' );
|
||||
await expect( page ).toMatchElement( '.woocommerce-MyAccount-navigation-link', { text: 'Dashboard' } );
|
||||
await expect( page ).toMatchElement( '.woocommerce-MyAccount-navigation-link', { text: 'Orders' } );
|
||||
await expect( page ).toMatchElement( '.woocommerce-MyAccount-navigation-link', { text: 'Downloads' } );
|
||||
await expect( page ).toMatchElement( '.woocommerce-MyAccount-navigation-link', { text: 'Addresses' } );
|
||||
await expect( page ).toMatchElement( '.woocommerce-MyAccount-navigation-link', { text: 'Account details' } );
|
||||
await expect( page ).toMatchElement( '.woocommerce-MyAccount-navigation-link', { text: 'Logout' } );
|
||||
} );
|
||||
|
||||
it( 'allows customer to see orders', async () => {
|
||||
await CustomerFlow.goToOrders();
|
||||
await expect( page.url() ).toMatch( 'my-account/orders' );
|
||||
await expect( page ).toMatchElement( 'h1', { text: 'Orders' } );
|
||||
} );
|
||||
|
||||
it( 'allows customer to see downloads', async () => {
|
||||
await CustomerFlow.goToDownloads();
|
||||
expect( page.url() ).toMatch( 'my-account/downloads' );
|
||||
await expect( page ).toMatchElement( 'h1', { text: 'Downloads' } );
|
||||
} );
|
||||
|
||||
it( 'allows customer to see addresses', async () => {
|
||||
await CustomerFlow.goToAddresses();
|
||||
expect( page.url() ).toMatch( 'my-account/edit-address' );
|
||||
await expect( page ).toMatchElement( 'h1', { text: 'Addresses' } );
|
||||
} );
|
||||
|
||||
it( 'allows customer to see account details', async () => {
|
||||
await CustomerFlow.goToAccountDetails();
|
||||
expect( page.url() ).toMatch( 'my-account/edit-account' );
|
||||
await expect( page ).toMatchElement( 'h1', { text: 'Account details' } );
|
||||
} );
|
||||
} );
|
|
@ -2,6 +2,11 @@
|
|||
* @format
|
||||
*/
|
||||
|
||||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { pressKeyWithModifier } from '@wordpress/e2e-test-utils';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
|
@ -21,11 +26,16 @@ const WP_ADMIN_NEW_PRODUCT = baseUrl + 'wp-admin/post-new.php?post_type=product'
|
|||
const WP_ADMIN_WC_SETTINGS = baseUrl + 'wp-admin/admin.php?page=wc-settings&tab=';
|
||||
const WP_ADMIN_PERMALINK_SETTINGS = baseUrl + 'wp-admin/options-permalink.php';
|
||||
|
||||
const SHOP_PAGE = baseUrl + 'shop/';
|
||||
const SHOP_PAGE = baseUrl + 'shop';
|
||||
const SHOP_PRODUCT_PAGE = baseUrl + '?p=';
|
||||
const SHOP_CART_PAGE = baseUrl + 'cart/';
|
||||
const SHOP_CART_PAGE = baseUrl + 'cart';
|
||||
const SHOP_CHECKOUT_PAGE = baseUrl + 'checkout/';
|
||||
const SHOP_MY_ACCOUNT_PAGE = baseUrl + 'my-account/';
|
||||
|
||||
const MY_ACCOUNT_ORDERS = baseUrl + 'my-account/orders';
|
||||
const MY_ACCOUNT_DOWNLOADS = baseUrl + 'my-account/downloads';
|
||||
const MY_ACCOUNT_ADDRESSES = baseUrl + 'my-account/edit-address';
|
||||
const MY_ACCOUNT_ACCOUNT_DETAILS = baseUrl + 'my-account/edit-account';
|
||||
|
||||
const getProductColumnExpression = ( productTitle ) => (
|
||||
'td[@class="product-name" and ' +
|
||||
|
@ -85,12 +95,28 @@ const CustomerFlow = {
|
|||
} );
|
||||
},
|
||||
|
||||
removeFromCart: async ( productTitle ) => {
|
||||
const cartItemXPath = getCartItemExpression( productTitle );
|
||||
const removeItemXPath = cartItemXPath + '//' + getRemoveExpression();
|
||||
goToOrders: async () => {
|
||||
await page.goto( MY_ACCOUNT_ORDERS, {
|
||||
waitUntil: 'networkidle0',
|
||||
} );
|
||||
},
|
||||
|
||||
const [ removeButton ] = await page.$x( removeItemXPath );
|
||||
await removeButton.click();
|
||||
goToDownloads: async () => {
|
||||
await page.goto( MY_ACCOUNT_DOWNLOADS, {
|
||||
waitUntil: 'networkidle0',
|
||||
} );
|
||||
},
|
||||
|
||||
goToAddresses: async () => {
|
||||
await page.goto( MY_ACCOUNT_ADDRESSES, {
|
||||
waitUntil: 'networkidle0',
|
||||
} );
|
||||
},
|
||||
|
||||
goToAccountDetails: async () => {
|
||||
await page.goto( MY_ACCOUNT_ACCOUNT_DETAILS, {
|
||||
waitUntil: 'networkidle0',
|
||||
} );
|
||||
},
|
||||
|
||||
goToProduct: async ( postID ) => {
|
||||
|
@ -126,6 +152,22 @@ const CustomerFlow = {
|
|||
} );
|
||||
},
|
||||
|
||||
login: async () => {
|
||||
await page.goto(SHOP_MY_ACCOUNT_PAGE, {
|
||||
waitUntil: 'networkidle0',
|
||||
} );
|
||||
|
||||
await expect(page.title()).resolves.toMatch('My account');
|
||||
|
||||
await page.type('#username', config.get('users.customer.username'));
|
||||
await page.type('#password', config.get('users.customer.password'));
|
||||
|
||||
await Promise.all([
|
||||
page.waitForNavigation({ waitUntil: 'networkidle0' }),
|
||||
page.click('button[name="login"]'),
|
||||
] );
|
||||
},
|
||||
|
||||
productIsInCart: async ( productTitle, quantity = null ) => {
|
||||
const cartItemArgs = quantity ? { qty: quantity } : {};
|
||||
const cartItemXPath = getCartItemExpression( productTitle, cartItemArgs );
|
||||
|
@ -181,8 +223,26 @@ const CustomerFlow = {
|
|||
await expect( page ).toFill( '#shipping_postcode', postcode );
|
||||
},
|
||||
|
||||
removeFromCart: async ( productTitle ) => {
|
||||
const cartItemXPath = getCartItemExpression(productTitle);
|
||||
const removeItemXPath = cartItemXPath + '//' + getRemoveExpression();
|
||||
|
||||
const [removeButton] = await page.$x(removeItemXPath);
|
||||
await removeButton.click();
|
||||
},
|
||||
|
||||
setCartQuantity: async ( productTitle, quantityValue ) => {
|
||||
const cartItemXPath = getCartItemExpression( productTitle );
|
||||
const quantityInputXPath = cartItemXPath + '//' + getQtyInputExpression();
|
||||
|
||||
const [ quantityInput ] = await page.$x( quantityInputXPath );
|
||||
await quantityInput.focus();
|
||||
await pressKeyWithModifier( 'primary', 'a' );
|
||||
await quantityInput.type( quantityValue.toString() );
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
const StoreOwnerFlow = {
|
||||
login: async () => {
|
||||
await page.goto( WP_ADMIN_LOGIN, {
|
||||
|
|
|
@ -1,16 +1,22 @@
|
|||
<?php
|
||||
/**
|
||||
* Dummy WC data stores used to test data store functionality.
|
||||
*
|
||||
* @package WooCommerce\Tests\Framework
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// phpcs:disable Squiz.Commenting
|
||||
|
||||
/**
|
||||
* WC Dummy Data Store: CPT.
|
||||
*
|
||||
* Used to test swapping out data stores.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @category Class
|
||||
* @author WooThemes
|
||||
*/
|
||||
class WC_Dummy_Data_Store_CPT implements WC_Object_Data_Store_Interface {
|
||||
public function create( &$data ) { }
|
||||
|
@ -21,6 +27,15 @@ class WC_Dummy_Data_Store_CPT implements WC_Object_Data_Store_Interface {
|
|||
public function delete_meta( &$data, $meta ) { }
|
||||
public function add_meta( &$data, $meta ) { }
|
||||
public function update_meta( &$data, $meta ) { }
|
||||
|
||||
/**
|
||||
* Method used to test WC_Data_Store::__call().
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function custom_method( $first_param, $second_param, $third_param ) {
|
||||
return array( $first_param, $second_param, $third_param );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,8 +44,6 @@ class WC_Dummy_Data_Store_CPT implements WC_Object_Data_Store_Interface {
|
|||
* Used to test swapping out data stores.
|
||||
*
|
||||
* @version 3.0.0
|
||||
* @category Class
|
||||
* @author WooThemes
|
||||
*/
|
||||
class WC_Dummy_Data_Store_Custom_Table implements WC_Object_Data_Store_Interface {
|
||||
public function create( &$data ) { }
|
||||
|
@ -42,3 +55,5 @@ class WC_Dummy_Data_Store_Custom_Table implements WC_Object_Data_Store_Interface
|
|||
public function add_meta( &$data, $meta ) { }
|
||||
public function update_meta( &$data, $meta ) { }
|
||||
}
|
||||
|
||||
// phpcs:enable
|
||||
|
|
|
@ -224,7 +224,7 @@ class WC_Helper_Product {
|
|||
|
||||
// Make sure caches are clean.
|
||||
delete_transient( 'wc_attribute_taxonomies' );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'woocommerce-attributes' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' );
|
||||
|
||||
// These are exported as labels, so convert the label to a name if possible first.
|
||||
$attribute_labels = wp_list_pluck( wc_get_attribute_taxonomies(), 'attribute_label', 'attribute_name' );
|
||||
|
|
|
@ -51,6 +51,6 @@ class WC_Helper_Shipping_Zones {
|
|||
$wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_shipping_zone_methods;" );
|
||||
$wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_shipping_zone_locations;" );
|
||||
$wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_shipping_zones;" );
|
||||
WC_Cache_Helper::incr_cache_prefix( 'shipping_zones' );
|
||||
WC_Cache_Helper::invalidate_cache_group( 'shipping_zones' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
/**
|
||||
* Unit tests for the admin product duplication class.
|
||||
*
|
||||
* @package WooCommerce\Tests\Admin
|
||||
*/
|
||||
|
||||
/**
|
||||
* WC_Tests_Admin_Duplicate_Product tests.
|
||||
*
|
||||
* @package WooCommerce\Tests\Admin
|
||||
* @since 3.9.0
|
||||
*/
|
||||
class WC_Tests_Admin_Duplicate_Product extends WC_Unit_Test_Case {
|
||||
/**
|
||||
* Test duplication of a simple product.
|
||||
*/
|
||||
public function test_simple_product_duplication() {
|
||||
$product = WC_Helper_Product::create_simple_product();
|
||||
|
||||
$duplicate = ( new WC_Admin_Duplicate_Product() )->product_duplicate( $product );
|
||||
|
||||
$this->assertNotEquals( $product->get_id(), $duplicate->get_id() );
|
||||
$this->assertEquals( $product->get_name() . ' (Copy)', $duplicate->get_name() );
|
||||
$this->assertEquals( 'draft', $duplicate->get_status() );
|
||||
$this->assertDuplicateWasReset( $duplicate );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test duplication of a variable product.
|
||||
*/
|
||||
public function test_variable_product_duplication() {
|
||||
$product = WC_Helper_Product::create_variation_product();
|
||||
|
||||
$duplicate = ( new WC_Admin_Duplicate_Product() )->product_duplicate( $product );
|
||||
|
||||
$this->assertNotEquals( $product->get_id(), $duplicate->get_id() );
|
||||
$this->assertEquals( $product->get_name() . ' (Copy)', $duplicate->get_name() );
|
||||
$this->assertEquals( 'draft', $duplicate->get_status() );
|
||||
$this->assertDuplicateWasReset( $duplicate );
|
||||
|
||||
$product_children = $product->get_children();
|
||||
$duplicate_children = $duplicate->get_children();
|
||||
$child_count = count( $product_children );
|
||||
$this->assertEquals( $child_count, count( $duplicate_children ) );
|
||||
|
||||
for ( $i = 0; $i < $child_count; $i++ ) {
|
||||
$product_child = wc_get_product( $product_children[ $i ] );
|
||||
$duplicate_child = wc_get_product( $duplicate_children[ $i ] );
|
||||
|
||||
$this->assertNotEquals( $product_child->get_id(), $duplicate_child->get_id() );
|
||||
$this->assertEquals( $product_child->get_name() . ' (Copy)', $duplicate_child->get_name() );
|
||||
$this->assertEquals( 'publish', $duplicate_child->get_status() );
|
||||
$this->assertDuplicateWasReset( $duplicate_child );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the unique slugs generated by variation duplication are correct.
|
||||
*/
|
||||
public function test_variable_product_duplication_unique_slug_generation() {
|
||||
$product = WC_Helper_Product::create_variation_product();
|
||||
|
||||
// We just want to make sure each successive duplication has the correct slugs.
|
||||
$slug_matches = array(
|
||||
array(
|
||||
'dummy-variable-product-small-2',
|
||||
'dummy-variable-product-large-2',
|
||||
'dummy-variable-product-3',
|
||||
'dummy-variable-product-4',
|
||||
),
|
||||
array(
|
||||
'dummy-variable-product-small-3',
|
||||
'dummy-variable-product-large-3',
|
||||
'dummy-variable-product-5',
|
||||
'dummy-variable-product-6',
|
||||
),
|
||||
array(
|
||||
'dummy-variable-product-small-4',
|
||||
'dummy-variable-product-large-4',
|
||||
'dummy-variable-product-7',
|
||||
'dummy-variable-product-8',
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $slug_matches as $slug_match ) {
|
||||
$duplicate = ( new WC_Admin_Duplicate_Product() )->product_duplicate( $product );
|
||||
|
||||
$duplicate_children = $duplicate->get_children();
|
||||
|
||||
$this->assertEquals( 4, count( $duplicate_children ) );
|
||||
foreach ( $slug_match as $key => $slug ) {
|
||||
$child = wc_get_product( $duplicate_children[ $key ] );
|
||||
$this->assertEquals( $slug, $child->get_slug() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the product was correctly reset after duplication.
|
||||
*
|
||||
* @param WC_Product $duplicate The duplicate product to evaluate.
|
||||
*/
|
||||
private function assertDuplicateWasReset( $duplicate ) {
|
||||
$this->assertEquals( 0, $duplicate->get_total_sales() );
|
||||
$this->assertEquals( array(), $duplicate->get_rating_counts() );
|
||||
$this->assertEquals( 0, $duplicate->get_average_rating() );
|
||||
$this->assertEquals( 0, $duplicate->get_rating_count() );
|
||||
}
|
||||
}
|
|
@ -1,7 +1,13 @@
|
|||
<?php
|
||||
/**
|
||||
* Data Store Tests
|
||||
* Data Store tests
|
||||
*
|
||||
* @package WooCommerce\Tests\Product
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class for Data Store tests
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
class WC_Tests_Data_Store extends WC_Unit_Test_Case {
|
||||
|
@ -12,9 +18,9 @@ class WC_Tests_Data_Store extends WC_Unit_Test_Case {
|
|||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function test_invalid_store_throws_exception() {
|
||||
public function test_invalid_store_throws_exception() {
|
||||
try {
|
||||
$product_store = new WC_Data_Store( 'bogus' );
|
||||
new WC_Data_Store( 'bogus' );
|
||||
} catch ( Exception $e ) {
|
||||
$this->assertEquals( $e->getMessage(), 'Invalid data store.' );
|
||||
return;
|
||||
|
@ -27,9 +33,9 @@ class WC_Tests_Data_Store extends WC_Unit_Test_Case {
|
|||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function test_invalid_store_load_throws_exception() {
|
||||
public function test_invalid_store_load_throws_exception() {
|
||||
try {
|
||||
$product_store = WC_Data_Store::load( 'does-not-exist' );
|
||||
WC_Data_Store::load( 'does-not-exist' );
|
||||
} catch ( Exception $e ) {
|
||||
$this->assertEquals( $e->getMessage(), 'Invalid data store.' );
|
||||
return;
|
||||
|
@ -42,7 +48,7 @@ class WC_Tests_Data_Store extends WC_Unit_Test_Case {
|
|||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function test_store_swap() {
|
||||
public function test_store_swap() {
|
||||
$this->load_dummy_store();
|
||||
|
||||
$store = new WC_Data_Store( 'dummy' );
|
||||
|
@ -61,12 +67,25 @@ class WC_Tests_Data_Store extends WC_Unit_Test_Case {
|
|||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function test_store_sub_type() {
|
||||
public function test_store_sub_type() {
|
||||
$this->load_dummy_store();
|
||||
|
||||
$store = WC_Data_Store::load( 'dummy-sub' );
|
||||
$this->assertEquals( 'WC_Dummy_Data_Store_CPT', $store->get_current_class_name() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test WC_Data_Store::__call().
|
||||
*/
|
||||
public function test_data_store_method_overloading() {
|
||||
$this->load_dummy_store();
|
||||
$store = WC_Data_Store::load( 'dummy-sub' );
|
||||
$this->assertEquals(
|
||||
array( 'first param', 'second param', 'third param' ),
|
||||
$store->custom_method( 'first param', 'second param', 'third param', 'asdfsdf' )
|
||||
);
|
||||
}
|
||||
|
||||
/* Helper Functions. */
|
||||
|
||||
/**
|
||||
|
@ -74,7 +93,7 @@ class WC_Tests_Data_Store extends WC_Unit_Test_Case {
|
|||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function load_dummy_store() {
|
||||
private function load_dummy_store() {
|
||||
include_once dirname( dirname( dirname( __FILE__ ) ) ) . '/framework/class-wc-dummy-data-store.php';
|
||||
add_filter( 'woocommerce_data_stores', array( $this, 'add_dummy_data_store' ) );
|
||||
}
|
||||
|
@ -82,9 +101,11 @@ class WC_Tests_Data_Store extends WC_Unit_Test_Case {
|
|||
/**
|
||||
* Adds a default class for the 'dummy' data store.
|
||||
*
|
||||
* @param array $stores Loaded data stores.
|
||||
* @return array Modified list of data stores.
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function add_dummy_data_store( $stores ) {
|
||||
public function add_dummy_data_store( $stores ) {
|
||||
$stores['dummy'] = 'WC_Dummy_Data_Store_CPT';
|
||||
return $stores;
|
||||
}
|
||||
|
@ -92,18 +113,11 @@ class WC_Tests_Data_Store extends WC_Unit_Test_Case {
|
|||
/**
|
||||
* Helper function/filter to swap out the default dummy store for a different one.
|
||||
*
|
||||
* @param string $store Data store class name.
|
||||
* @return string New data store class name.
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function set_dummy_store( $store ) {
|
||||
public function set_dummy_store( $store ) {
|
||||
return 'WC_Dummy_Data_Store_Custom_Table';
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function/filter to swap out the 'dummy' store for the default one.
|
||||
*
|
||||
* @since 3.0.0
|
||||
*/
|
||||
function set_default_product_store( $store ) {
|
||||
return 'WC_Dummy_Data_Store_CPT';
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue