Merge pull request #1 from woocommerce/master

get new commits
This commit is contained in:
Brian 2020-12-17 07:39:38 +01:00 committed by GitHub
commit d6f574c080
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
167 changed files with 9129 additions and 1949 deletions

View File

@ -1,35 +0,0 @@
engines:
phpcodesniffer:
enabled: true
config:
standard: "WordPress"
eslint:
enabled: true
scss-lint:
enabled: true
duplication:
enabled: true
config:
languages:
- php
- javascript
ratings:
paths:
- "includes/*"
exclude_paths:
- "tests/"
- "sample-data/"
- "i18n/"
- "includes/api/legacy/"
- "includes/libraries/"
- "includes/updates/"
- "includes/shipping/legacy-*"
- "includes/wc-deprecated-functions.php"
- "assets/js/accounting/"
- "assets/js/jquery-*"
- "assets/js/prettyPhoto/"
- "assets/js/round/"
- "assets/js/select2/"
- "assets/js/selectWoo/"
- "assets/js/stupidtable/"
- "assets/js/zeroclipboard/"

View File

@ -34,7 +34,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Update nightly tag
uses: richardsimko/github-tag-action@v1.0.4
uses: richardsimko/github-tag-action@v1.0.5
with:
tag_name: nightly
env:

3
.gitignore vendored
View File

@ -59,7 +59,8 @@ tests/cli/vendor
# Composer
/vendor/
/bin/composer/**/vendor
/bin/composer/**/vendor/
/lib/vendor/
contributors.md
contributors.html

2
.nvmrc
View File

@ -1 +1 @@
v10
v12

View File

@ -1,35 +0,0 @@
tools:
php_code_sniffer:
config:
standard: WordPress
sensiolabs_security_checker: true
external_code_coverage:
timeout: 2500
checks:
php:
avoid_closing_tag: false
avoid_superglobals: false
coding_standard:
name: WordPress
no_exit: false
no_global_keyword: false
one_class_per_file: false
psr2_class_declaration: false
psr2_control_structure_declaration: false
psr2_switch_declaration: false
variable_existence: false
verify_access_scope_valid: false
verify_argument_usable_as_reference: false
verify_property_names: false
filter:
excluded_paths:
- sample-data/
- i18n/
- includes/api/legacy/
- includes/legacy/
- includes/libraries/
- includes/shipping/legacy-*
- includes/updates/
- includes/vendor/
- includes/wc-deprecated-functions.php
- tests/

View File

@ -1,24 +1,24 @@
version: ~> 1.0
# Specifies that Travis should create builds for master and release branches and also tags.
branches:
only:
- master
- /^\d+\.\d+(\.\d+)?(-\S*)?$/
- /^release\//
language: php
os:
- linux
dist: xenial
cache:
directories:
- $HOME/.composer/cache
# Since Xenial services are not started by default, we need to instruct it below to start.
services:
- mysql
- docker
# Test main supported versions of PHP against latest WP.
php:
- 7.0
- 7.1
- 7.2
- 7.3
- 7.4
- "7.0"
- "7.1"
- "7.2"
- "7.3"
- "7.4"
env:
- WP_VERSION=latest WP_MULTISITE=0
@ -33,32 +33,50 @@ jobs:
install:
- nvm install
- npm install
- composer install
- composer install --no-dev
script:
- npm run build:assets
- npm run docker:up
- npm run test:e2e
- travis_retry npm run build:assets
- travis_retry npm run docker:up
- travis_retry npm run test:e2e
after_script:
- npm run docker:down
- name: "WP Nightly"
php: 7.4
php: "7.4"
env: WP_VERSION=nightly WP_MULTISITE=0
- name: "WP Latest - 1"
php: 7.2
php: "7.2"
env: WP_VERSION=5.4 WP_MULTISITE=0
- name: "WP Latest - 2"
php: 7.2
php: "7.2"
env: WP_VERSION=5.3 WP_MULTISITE=0
- name: "Code Standards"
php: 7.4
php: "7.4"
env: WP_VERSION=latest WP_MULTISITE=0 RUN_PHPCS=1
- name: "Code Coverage"
php: 7.4
php: "7.4"
env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1
allow_failures:
- php: 7.4
- php: "7.4"
env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1
# Git clone depth
# By default Travis CI clones repositories to a depth of 50 commits. Using a depth of 1 makes this step a bit faster.
git:
depth: 1
# Since Xenial services are not started by default, we need to instruct it below to start.
services:
- mysql
- docker
cache:
directories:
- $HOME/.composer/cache
# Composer 2.0.7 introduced a change that broke the jetpack autoloader in PHP 7.0 - 7.3.
before_install:
- composer self-update 2.0.6
install:
- export PATH="$HOME/.composer/vendor/bin:$PATH"
- |
@ -70,10 +88,9 @@ install:
fi
- composer install
- |
# Install WP Test suite, install PHPUnit globally:
# Install WP Test suite:
if [[ ! -z "$WP_VERSION" ]]; then
bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION
composer global require "phpunit/phpunit=6.5.*|7.5.*"
fi
script:
@ -82,13 +99,3 @@ script:
after_script:
- bash tests/bin/travis.sh after
# Specifies that Travis should create builds for master and release branches and also tags.
branches:
only:
- master
- /^\d+\.\d+(\.\d+)?(-\S*)?$/
- /^release\//
before_install:
- composer self-update --1

View File

@ -1 +0,0 @@
FROM wordpress:5.4.2

View File

@ -6,7 +6,6 @@
<img src="https://img.shields.io/wordpress/plugin/dt/woocommerce.svg" alt="WordPress.org downloads">
<img src="https://img.shields.io/wordpress/plugin/r/woocommerce.svg" alt="WordPress.org rating">
<a href="https://travis-ci.com/woocommerce/woocommerce"><img src="https://travis-ci.com/woocommerce/woocommerce.svg?branch=master" alt="Build Status"></a>
<a href="https://scrutinizer-ci.com/g/woocommerce/woocommerce/?branch=master"><img src="https://scrutinizer-ci.com/g/woocommerce/woocommerce/badges/quality-score.png?b=master" alt="Scrutinizer Code Quality"></a>
<a href="https://codecov.io/gh/woocommerce/woocommerce"><img src="https://codecov.io/gh/woocommerce/woocommerce/branch/master/graph/badge.svg" alt="codecov"></a>
</p>

View File

@ -7,7 +7,7 @@
&::before,
&::after {
content: ' ';
content: " ";
display: table;
}
@ -127,10 +127,14 @@
}
@mixin darkorlighttextshadow($a, $opacity: 0.8) {
@if lightness($a) >= 65% {
@include text_shadow(0, -1px, 0, rgba(0, 0, 0, $opacity));
}
@else {
@include text_shadow(0, 1px, 0, rgba(255, 255, 255, $opacity));
}
}
@ -139,6 +143,7 @@
* Objects
*/
@mixin menu() {
@include clearfix();
li {
@ -147,6 +152,7 @@
}
@mixin mediaright() {
@include clearfix();
img {
@ -156,6 +162,7 @@
}
@mixin medialeft() {
@include clearfix();
img {
@ -172,8 +179,8 @@
width: 1em;
}
@mixin icon( $glyph: '\e001' ) {
font-family: 'WooCommerce';
@mixin icon( $glyph: "\e001" ) {
font-family: "WooCommerce";
speak: none;
font-weight: normal;
font-variant: normal;
@ -190,8 +197,8 @@
content: $glyph;
}
@mixin icon_dashicons( $glyph: '\f333' ) {
font-family: 'Dashicons';
@mixin icon_dashicons( $glyph: "\f333" ) {
font-family: "Dashicons";
speak: none;
font-weight: normal;
font-variant: normal;
@ -209,8 +216,8 @@
content: $glyph;
}
@mixin iconbefore( $glyph: '\e001' ) {
font-family: 'WooCommerce';
@mixin iconbefore( $glyph: "\e001" ) {
font-family: "WooCommerce";
speak: none;
font-weight: normal;
font-variant: normal;
@ -222,8 +229,8 @@
text-decoration: none;
}
@mixin iconbeforedashicons( $glyph: '\f333' ) {
font-family: 'Dashicons';
@mixin iconbeforedashicons( $glyph: "\f333" ) {
font-family: "Dashicons";
speak: none;
font-weight: normal;
font-variant: normal;
@ -234,8 +241,8 @@
text-decoration: none;
}
@mixin iconafter( $glyph: '\e001' ) {
font-family: 'WooCommerce';
@mixin iconafter( $glyph: "\e001" ) {
font-family: "WooCommerce";
speak: none;
font-weight: normal;
font-variant: normal;
@ -248,6 +255,7 @@
}
@mixin loader() {
&::before {
height: 1em;
width: 1em;
@ -257,9 +265,9 @@
left: 50%;
margin-left: -0.5em;
margin-top: -0.5em;
content: '';
content: "";
animation: spin 1s ease-in-out infinite;
background: url('../images/icons/loader.svg') center center;
background: url("../images/icons/loader.svg") center center;
background-size: cover;
line-height: 1;
text-align: center;
@ -267,3 +275,14 @@
color: rgba(#000, 0.75);
}
}
@mixin inversebuttoncolors {
background-color: transparent !important;
color: var(--button--color-text-hover) !important;
&:hover {
background-color: var(--button--color-background) !important;
color: var(--button--color-text) !important;
text-decoration: none !important;
}
}

View File

@ -360,7 +360,7 @@
}
.addons-button-solid {
background-color: #955a89;
background-color:#674399;
color: #fff;
}
@ -379,6 +379,16 @@
opacity: 0.8;
}
.addons-button-outline-purple {
border: 1px solid #674399;
color: #674399;
}
.addons-button-outline-purple:hover {
color: #674399;
opacity: 0.8;
}
.addons-button-outline-white {
border: 1px solid #fff;
color: #fff;
@ -3159,6 +3169,12 @@ table.wc_input_table {
}
}
table.wc_tax_rates {
td.country {
position: relative;
}
}
table.wc_gateways,
table.wc_emails,
table.wc_shipping {

View File

@ -0,0 +1,14 @@
/**
* Admin
*/
.wp-admin.woocommerce-page {
table.wp-list-table {
tr.type-product {
td.thumb {
img {
max-width: 40px !important;
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1661,6 +1661,16 @@ a.reset_variations {
}
}
form[name="checkout"] {
display: table;
}
.blockUI.blockOverlay {
position: relative;
@include loader();
}
form {
.col2-set {

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -405,7 +405,7 @@
}
// Track when suggestions are displayed (and not already visible).
$( 'ul.product_data_tabs li.marketplace-suggestions_options a' ).click( function( e ) {
$( 'ul.product_data_tabs li.marketplace-suggestions_options a' ).on( 'click', function( e ) {
e.preventDefault();
if ( '#marketplace_suggestions' === currentTab ) {

View File

@ -19,16 +19,16 @@ jQuery( function ( $ ) {
)
) {
/* State/Country select boxes */
this.states = $.parseJSON( woocommerce_admin_meta_boxes_order.countries.replace( /&quot;/g, '"' ) );
this.states = JSON.parse( woocommerce_admin_meta_boxes_order.countries.replace( /&quot;/g, '"' ) );
}
$( '.js_field-country' ).selectWoo().change( this.change_country );
$( '.js_field-country' ).trigger( 'change', [ true ] );
$( document.body ).on( 'change', 'select.js_field-state', this.change_state );
$( '#woocommerce-order-actions input, #woocommerce-order-actions a' ).click(function() {
$( '#woocommerce-order-actions input, #woocommerce-order-actions a' ).on( 'click', function() {
window.onbeforeunload = '';
});
$( 'a.edit_address' ).click( this.edit_address );
$( 'a.edit_address' ).on( 'click', this.edit_address );
$( 'a.billing-same-as-shipping' ).on( 'click', this.copy_billing_to_shipping );
$( 'a.load_customer_billing' ).on( 'click', this.load_billing );
$( 'a.load_customer_shipping' ).on( 'click', this.load_shipping );

View File

@ -49,14 +49,14 @@ jQuery( function( $ ) {
});
// Catalog Visibility.
$( '#catalog-visibility' ).find( '.edit-catalog-visibility' ).click( function() {
$( '#catalog-visibility' ).find( '.edit-catalog-visibility' ).on( 'click', function() {
if ( $( '#catalog-visibility-select' ).is( ':hidden' ) ) {
$( '#catalog-visibility-select' ).slideDown( 'fast' );
$( this ).hide();
}
return false;
});
$( '#catalog-visibility' ).find( '.save-post-visibility' ).click( function() {
$( '#catalog-visibility' ).find( '.save-post-visibility' ).on( 'click', function() {
$( '#catalog-visibility-select' ).slideUp( 'fast' );
$( '#catalog-visibility' ).find( '.edit-catalog-visibility' ).show();
@ -70,7 +70,7 @@ jQuery( function( $ ) {
$( '#catalog-visibility-display' ).text( label );
return false;
});
$( '#catalog-visibility' ).find( '.cancel-post-visibility' ).click( function() {
$( '#catalog-visibility' ).find( '.cancel-post-visibility' ).on( 'click', function() {
$( '#catalog-visibility-select' ).slideUp( 'fast' );
$( '#catalog-visibility' ).find( '.edit-catalog-visibility' ).show();
@ -146,6 +146,11 @@ jQuery( function( $ ) {
}
if ( is_virtual ) {
$( '.show_if_virtual' ).show();
// If user enables virtual while on shipping tab, switch to general tab.
if ( $( '.shipping_options.shipping_tab' ).hasClass( 'active' ) ) {
$( '.general_options.general_tab > a' ).trigger( 'click' );
}
}
$( '.show_if_' + product_type ).show();

View File

@ -16,18 +16,6 @@ jQuery( function ( $ ) {
runTipTip();
// Allow Tabbing
$( '#titlediv' ).find( '#title' ).keyup( function( event ) {
var code = event.keyCode || event.which;
// Tab key
if ( code === '9' && $( '#woocommerce-coupon-description' ).length > 0 ) {
event.stopPropagation();
$( '#woocommerce-coupon-description' ).focus();
return false;
}
});
$( '.wc-metaboxes-wrapper' ).on( 'click', '.wc-metabox > h3', function() {
$( this ).parent( '.wc-metabox' ).toggleClass( 'closed' ).toggleClass( 'open' );
});
@ -35,7 +23,7 @@ jQuery( function ( $ ) {
// Tabbed Panels
$( document.body ).on( 'wc-init-tabbed-panels', function() {
$( 'ul.wc-tabs' ).show();
$( 'ul.wc-tabs a' ).click( function( e ) {
$( 'ul.wc-tabs a' ).on( 'click', function( e ) {
e.preventDefault();
var panel_wrap = $( this ).closest( 'div.panel-wrap' );
$( 'ul.wc-tabs li', panel_wrap ).removeClass( 'active' );

View File

@ -130,7 +130,7 @@ jQuery(function( $ ) {
}
// Export
$( '.export_csv' ).click( function() {
$( '.export_csv' ).on( 'click', function() {
var exclude_series = $( this ).data( 'exclude_series' ) || '';
exclude_series = exclude_series.toString();
exclude_series = exclude_series.split( ',' );

View File

@ -80,7 +80,7 @@
}
});
$( '.submit :input' ).click( function() {
$( '.submit :input' ).on( 'click', function() {
window.onbeforeunload = '';
});
});

View File

@ -9,7 +9,7 @@ jQuery( function ( $ ) {
init: function() {
if ( typeof wc_users_params.countries !== 'undefined' ) {
/* State/Country select boxes */
this.states = $.parseJSON( wc_users_params.countries.replace( /&quot;/g, '"' ) );
this.states = JSON.parse( wc_users_params.countries.replace( /&quot;/g, '"' ) );
}
$( '.js_field-country' ).selectWoo().change( this.change_country );

View File

@ -235,7 +235,7 @@
$( this ).focus();
} );
$( '.wc_input_table .remove_rows' ).click( function() {
$( '.wc_input_table .remove_rows' ).on( 'click', function() {
var $tbody = $( this ).closest( '.wc_input_table' ).find( 'tbody' );
if ( $tbody.find( 'tr.current' ).length > 0 ) {
var $current = $tbody.find( 'tr.current' );

View File

@ -6,7 +6,7 @@ jQuery( function( $ ) {
return false;
}
var locale_json = wc_address_i18n_params.locale.replace( /&quot;/g, '"' ), locale = $.parseJSON( locale_json );
var locale_json = wc_address_i18n_params.locale.replace( /&quot;/g, '"' ), locale = JSON.parse( locale_json );
function field_is_required( field, is_required ) {
if ( is_required ) {
@ -51,7 +51,7 @@ jQuery( function( $ ) {
$statefield.attr( 'data-o_class', $statefield.attr( 'class' ) );
}
var locale_fields = $.parseJSON( wc_address_i18n_params.locale_fields );
var locale_fields = JSON.parse( wc_address_i18n_params.locale_fields );
$.each( locale_fields, function( key, value ) {

View File

@ -115,7 +115,7 @@ jQuery( function( $ ) {
} );
try {
var wc_fragments = $.parseJSON( sessionStorage.getItem( wc_cart_fragments_params.fragment_name ) ),
var wc_fragments = JSON.parse( sessionStorage.getItem( wc_cart_fragments_params.fragment_name ) ),
cart_hash = sessionStorage.getItem( cart_hash_key ),
cookie_hash = Cookies.get( 'woocommerce_cart_hash'),
cart_created = sessionStorage.getItem( 'wc_cart_created' );

View File

@ -191,7 +191,7 @@ jQuery( function( $ ) {
},
is_valid_json: function( raw_json ) {
try {
var json = $.parseJSON( raw_json );
var json = JSON.parse( raw_json );
return ( json && 'object' === typeof json );
} catch ( e ) {
@ -507,9 +507,8 @@ jQuery( function( $ ) {
$.ajax({
type: 'POST',
url: wc_checkout_params.checkout_url,
data: new FormData( this ),
contentType: false,
processData: false,
data: $form.serialize(),
dataType: 'json',
success: function( result ) {
// Detach the unload handler that prevents a reload / redirect
wc_checkout_form.detachUnloadEventsOnSubmit();

View File

@ -77,7 +77,7 @@ jQuery( function( $ ) {
/* State/Country select boxes */
var states_json = wc_country_select_params.countries.replace( /&quot;/g, '"' ),
states = $.parseJSON( states_json ),
states = JSON.parse( states_json ),
wrapper_selectors = '.woocommerce-billing-fields,' +
'.woocommerce-shipping-fields,' +
'.woocommerce-address-fields,' +

View File

@ -6,7 +6,7 @@ jQuery( function( $ ) {
return false;
}
$( document.body ).bind( 'price_slider_create price_slider_slide', function( event, min, max ) {
$( document.body ).on( 'price_slider_create price_slider_slide', function( event, min, max ) {
$( '.price_slider_amount span.from' ).html( accounting.formatMoney( min, {
symbol: woocommerce_price_slider_params.currency_format_symbol,
@ -66,6 +66,7 @@ jQuery( function( $ ) {
}
init_price_filter();
$( document.body ).on( 'init_price_filter', init_price_filter );
var hasSelectiveRefresh = (
'undefined' !== typeof wp &&
@ -75,7 +76,7 @@ jQuery( function( $ ) {
wp.customize.widgetsPreview.WidgetPartial
);
if ( hasSelectiveRefresh ) {
wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function() {
wp.customize.selectiveRefresh.on( 'partial-content-rendered', function() {
init_price_filter();
} );
}

View File

@ -25,7 +25,7 @@ jQuery( function( $ ) {
}
// Set a cookie and hide the store notice when the dismiss button is clicked
$( '.woocommerce-store-notice__dismiss-link' ).click( function( event ) {
$( '.woocommerce-store-notice__dismiss-link' ).on( 'click', function( event ) {
Cookies.set( cookieName, 'hidden', { path: '/' } );
$( '.woocommerce-store-notice' ).hide();
event.preventDefault();
@ -85,7 +85,7 @@ jQuery( function( $ ) {
$( '.woocommerce form input' ).filter(':password').parent('span').addClass('password-input');
$( '.password-input' ).append( '<span class="show-password-input"></span>' );
$( '.show-password-input' ).click(
$( '.show-password-input' ).on( 'click',
function() {
$( this ).toggleClass( 'display-password' );
if ( $( this ).hasClass( 'display-password' ) ) {

View File

@ -1,9 +0,0 @@
const { e2eBabelConfig } = require( '@woocommerce/e2e-environment' );
module.exports = function( api ) {
api.cache( true );
return {
...e2eBabelConfig,
};
};

34
bin/build-lib.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/sh
# Output colorized strings
#
# Color codes:
# 0 - black
# 1 - red
# 2 - green
# 3 - yellow
# 4 - blue
# 5 - magenta
# 6 - cian
# 7 - white
output() {
echo "$(tput setaf "$1")$2$(tput sgr0)"
}
if [ -z "$(php -r "echo version_compare(PHP_VERSION,'7.2','>=');")" ]; then
output 1 "PHP 7.2 or newer is required to run Mozart, the current PHP version is $(php -r 'echo PHP_VERSION;')"
exit 1
fi
output 6 "Building lib package"
# Clean the output directories to remove any files not present anymore
rm -rf lib/packages lib/classes
mkdir lib/packages lib/classes
# Running update on the lib package will automatically run Mozart
composer update -d ./lib
output 6 "Updating autoload files"
composer dump-autoload

View File

@ -0,0 +1,10 @@
{
"require-dev": {
"coenjacobs/mozart": "dev-master"
},
"config": {
"platform": {
"php": "7.2"
}
}
}

669
bin/composer/mozart/composer.lock generated Normal file
View File

@ -0,0 +1,669 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "cbcce1648bdb890ae805e1afb7396e3c",
"packages": [],
"packages-dev": [
{
"name": "coenjacobs/mozart",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/coenjacobs/mozart.git",
"reference": "5d8041fdefc94ff57edcbe83ab468a9988c4fc11"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/coenjacobs/mozart/zipball/5d8041fdefc94ff57edcbe83ab468a9988c4fc11",
"reference": "5d8041fdefc94ff57edcbe83ab468a9988c4fc11",
"shasum": ""
},
"require": {
"league/flysystem": "^1.0",
"php": "^7.2",
"symfony/console": "^4|^5",
"symfony/finder": "^4|^5"
},
"require-dev": {
"mheap/phpunit-github-actions-printer": "^1.4",
"phpunit/phpunit": "^8.5",
"squizlabs/php_codesniffer": "^3.5"
},
"bin": [
"bin/mozart"
],
"type": "library",
"autoload": {
"psr-4": {
"CoenJacobs\\Mozart\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Coen Jacobs",
"email": "coenjacobs@gmail.com"
}
],
"description": "Composes all dependencies as a package inside a WordPress plugin",
"funding": [
{
"url": "https://github.com/coenjacobs",
"type": "github"
}
],
"time": "2020-11-23T21:03:43+00:00"
},
{
"name": "league/flysystem",
"version": "1.0.70",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
"reference": "585824702f534f8d3cf7fab7225e8466cc4b7493"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/585824702f534f8d3cf7fab7225e8466cc4b7493",
"reference": "585824702f534f8d3cf7fab7225e8466cc4b7493",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"php": ">=5.5.9"
},
"conflict": {
"league/flysystem-sftp": "<1.0.6"
},
"require-dev": {
"phpspec/phpspec": "^3.4 || ^4.0 || ^5.0 || ^6.0",
"phpunit/phpunit": "^5.7.26"
},
"suggest": {
"ext-fileinfo": "Required for MimeType",
"ext-ftp": "Allows you to use FTP server storage",
"ext-openssl": "Allows you to use FTPS server storage",
"league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2",
"league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3",
"league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
"league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
"league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
"league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
"league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
"league/flysystem-webdav": "Allows you to use WebDAV storage",
"league/flysystem-ziparchive": "Allows you to use ZipArchive adapter",
"spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
"srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
}
},
"autoload": {
"psr-4": {
"League\\Flysystem\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frank de Jonge",
"email": "info@frenky.net"
}
],
"description": "Filesystem abstraction: Many filesystems, one API.",
"keywords": [
"Cloud Files",
"WebDAV",
"abstraction",
"aws",
"cloud",
"copy.com",
"dropbox",
"file systems",
"files",
"filesystem",
"filesystems",
"ftp",
"rackspace",
"remote",
"s3",
"sftp",
"storage"
],
"funding": [
{
"url": "https://offset.earth/frankdejonge",
"type": "other"
}
],
"time": "2020-07-26T07:20:36+00:00"
},
{
"name": "psr/container",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
"homepage": "https://github.com/php-fig/container",
"keywords": [
"PSR-11",
"container",
"container-interface",
"container-interop",
"psr"
],
"time": "2017-02-14T16:28:37+00:00"
},
{
"name": "symfony/console",
"version": "v4.4.17",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "c8e37f6928c19816437a4dd7bf16e3bd79941470"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/c8e37f6928c19816437a4dd7bf16e3bd79941470",
"reference": "c8e37f6928c19816437a4dd7bf16e3bd79941470",
"shasum": ""
},
"require": {
"php": ">=7.1.3",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "^1.8",
"symfony/polyfill-php80": "^1.15",
"symfony/service-contracts": "^1.1|^2"
},
"conflict": {
"symfony/dependency-injection": "<3.4",
"symfony/event-dispatcher": "<4.3|>=5",
"symfony/lock": "<4.4",
"symfony/process": "<3.3"
},
"provide": {
"psr/log-implementation": "1.0"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "^3.4|^4.0|^5.0",
"symfony/dependency-injection": "^3.4|^4.0|^5.0",
"symfony/event-dispatcher": "^4.3",
"symfony/lock": "^4.4|^5.0",
"symfony/process": "^3.4|^4.0|^5.0",
"symfony/var-dumper": "^4.3|^5.0"
},
"suggest": {
"psr/log": "For using the console logger",
"symfony/event-dispatcher": "",
"symfony/lock": "",
"symfony/process": ""
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Console\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-11-28T10:15:42+00:00"
},
{
"name": "symfony/finder",
"version": "v4.4.17",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "9f1d1d883b79a91ef320c0c6e803494e042ef36e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/9f1d1d883b79a91ef320c0c6e803494e042ef36e",
"reference": "9f1d1d883b79a91ef320c0c6e803494e042ef36e",
"shasum": ""
},
"require": {
"php": ">=7.1.3"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Finder\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-11-17T19:45:34+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.20.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "39d483bdf39be819deabf04ec872eb0b2410b531"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531",
"reference": "39d483bdf39be819deabf04ec872eb0b2410b531",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.20-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-23T14:02:19+00:00"
},
{
"name": "symfony/polyfill-php73",
"version": "v1.20.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php73.git",
"reference": "8ff431c517be11c78c48a39a66d37431e26a6bed"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/8ff431c517be11c78c48a39a66d37431e26a6bed",
"reference": "8ff431c517be11c78c48a39a66d37431e26a6bed",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.20-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php73\\": ""
},
"files": [
"bootstrap.php"
],
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-23T14:02:19+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.20.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de",
"reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.20-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"files": [
"bootstrap.php"
],
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ion Bazan",
"email": "ion.bazan@gmail.com"
},
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-23T14:02:19+00:00"
},
{
"name": "symfony/service-contracts",
"version": "v1.1.9",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
"reference": "b776d18b303a39f56c63747bcb977ad4b27aca26"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/b776d18b303a39f56c63747bcb977ad4b27aca26",
"reference": "b776d18b303a39f56c63747bcb977ad4b27aca26",
"shasum": ""
},
"require": {
"php": ">=7.1.3",
"psr/container": "^1.0"
},
"suggest": {
"symfony/service-implementation": ""
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"psr-4": {
"Symfony\\Contracts\\Service\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Generic abstractions related to writing services",
"homepage": "https://symfony.com",
"keywords": [
"abstractions",
"contracts",
"decoupling",
"interfaces",
"interoperability",
"standards"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-07-06T13:19:58+00:00"
}
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"coenjacobs/mozart": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"platform-overrides": {
"php": "7.2"
},
"plugin-api-version": "1.1.0"
}

View File

@ -4,7 +4,7 @@
},
"config": {
"platform": {
"php": "7.1"
"php": "7.0"
}
}
}

View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "ee5c0c106a076ca3b426771807c3ffeb",
"content-hash": "c50f65dd9f9a26d397f7bb30228d7a88",
"packages": [],
"packages-dev": [
{
@ -379,6 +379,7 @@
"platform": [],
"platform-dev": [],
"platform-overrides": {
"php": "7.1"
}
"php": "7.0"
},
"plugin-api-version": "1.1.0"
}

View File

@ -2,11 +2,11 @@
"minimum-stability": "dev",
"prefer-stable": true,
"require-dev": {
"phpunit/phpunit": "7.5.20"
"phpunit/phpunit": "6.5.14"
},
"config": {
"platform": {
"php": "7.1"
"php": "7.0"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@
},
"config": {
"platform": {
"php": "7.1"
"php": "7.0"
}
}
}

View File

@ -4,21 +4,21 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "f89bceee93cc1d38e71a45e4cbf4f4aa",
"content-hash": "4d4f2befccefe100869d30305083672b",
"packages": [],
"packages-dev": [
{
"name": "gettext/gettext",
"version": "v4.8.2",
"version": "v4.8.3",
"source": {
"type": "git",
"url": "https://github.com/php-gettext/Gettext.git",
"reference": "e474f872f2c8636cf53fd283ec4ce1218f3d236a"
"reference": "57ff4fb16647e78e80a5909fe3c190f1c3110321"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-gettext/Gettext/zipball/e474f872f2c8636cf53fd283ec4ce1218f3d236a",
"reference": "e474f872f2c8636cf53fd283ec4ce1218f3d236a",
"url": "https://api.github.com/repos/php-gettext/Gettext/zipball/57ff4fb16647e78e80a5909fe3c190f1c3110321",
"reference": "57ff4fb16647e78e80a5909fe3c190f1c3110321",
"shasum": ""
},
"require": {
@ -67,7 +67,7 @@
"po",
"translation"
],
"time": "2019-12-02T10:21:14+00:00"
"time": "2020-11-18T22:35:49+00:00"
},
{
"name": "gettext/languages",
@ -272,25 +272,25 @@
},
{
"name": "symfony/finder",
"version": "v3.4.45",
"version": "v3.3.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "52140652ed31cee3dabd0c481b5577201fa769b4"
"reference": "baea7f66d30854ad32988c11a09d7ffd485810c4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/52140652ed31cee3dabd0c481b5577201fa769b4",
"reference": "52140652ed31cee3dabd0c481b5577201fa769b4",
"url": "https://api.github.com/repos/symfony/finder/zipball/baea7f66d30854ad32988c11a09d7ffd485810c4",
"reference": "baea7f66d30854ad32988c11a09d7ffd485810c4",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8"
"php": ">=5.5.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.4-dev"
"dev-master": "3.3-dev"
}
},
"autoload": {
@ -317,7 +317,7 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2020-09-02T16:06:40+00:00"
"time": "2017-06-01T21:01:25+00:00"
},
{
"name": "wp-cli/i18n-command",
@ -545,6 +545,7 @@
"platform": [],
"platform-dev": [],
"platform-overrides": {
"php": "7.1"
}
"php": "7.0"
},
"plugin-api-version": "1.1.0"
}

View File

@ -1,29 +0,0 @@
#!/bin/sh
# Output colorized strings
#
# Color codes:
# 0 - black
# 1 - red
# 2 - green
# 3 - yellow
# 4 - blue
# 5 - magenta
# 6 - cian
# 7 - white
output() {
echo "$(tput setaf "$1")$2$(tput sgr0)"
}
output 6 "Prefixing the appropriate vendor namespaces with Automattic\WooCommerce\Vendor"
# Replace "League\Container" in "use" and "namespace" with "Automattic\WooCommerce\Vendor\League\Container".
REGEX='s/^[[:space:]]*(use|namespace)[[:space:]]*(League\\Container)/\1 Automattic\\WooCommerce\\Vendor\\\2/g'
find ./vendor/league/container -iname '*.php' -exec sed -i'.bak' -E -e "$REGEX" {} \;
find ./vendor/league/container -name "*.php.bak" -type f -delete
# Replace too in the composer.json file for the package.
sed -i'.bak' -E -e "s/\"(League\\\\\\\Container)/\"Automattic\\\\\\\WooCommerce\\\\\\\Vendor\\\\\\\\\1/g" vendor/league/container/composer.json
rm -f vendor/league/container/composer.json.bak

View File

@ -1,5 +1,127 @@
== Changelog ==
= 4.8.0 - 2020-12-08 =
**WooCommerce**
* Enhancement - Limited the system status report's "not tested with version" warning to major versions. #28114
* Enhancement - Add shipping, tax, and fee lines to refund REST API response. #28241
* Enhancement - Added support for Twenty Twenty-One theme. #28134
* Tweak - Reduced the memory usage of AJAX product searches. #28177
* Tweak - Replaced deprecated jQuery functionality. #28005, #28058
* Tweak - Hid "Add to cart" button for out of stock grouped products. #28169
* Tweak - Made product date deserialization more explicit. #28052
* Fix - Stock adjustment when deleting a refunded order item. #28069
* Fix - Avatar display for recent reviews widget in admin area. #28067
* Fix - Incorrect product sorting user capability. #28062
* Fix - PayPal response emptying uninitialized cart. #28027
* Fix - Display of visual feedback after pressing "Place Order" in `Twenty Twenty` and `Twenty Nineteen` themes #27997
* Fix - Category and tag bulk deletion message. #27856
* Fix - Corrected Puerto Rico address validation. #28465
* Dev - Filter: `woocommerce_product_has_options` to products. #27514
* Dev - Added error message to `checkout_error` JS event. #28101
* Dev - Replaced usage of deprecated `woocommerce_reset_loop()` in product category shortcodes. #28242
* Dev - Set "Tested up to" header to WordPress 5.6. #28388
* Localization - Jamaican currency, states, and address structure. #27723
* Localization - Better display of inclusive taxes during checkout. #28064
* Localization - Validation for Belgium postcodes. #28145
**WooCommerce Admin - 1.7.0 & 1.7.1 & 1.7.2 & 1.7.3**
* Enhancement - Variations report. #5167
* Enhancement - Add ability to toggle homescreen layouts. #5429
* Enhancement - Accordion component #5474
* Enhancement - Badge component #5520
* Tweak - Remove customer analytics data upon order deletion #5171
* Tweak - Updating Stripe key field validation to support test keys #5201
* Tweak - Wrap search control selected items in list #5231
* Tweak - Update store setup link to redirect to setup wizard #5200
* Tweak - Removing breadcrumbs from wc-admin header #5232
* Tweak - Use consistent markdown headers in navigation readme #5417
* Tweak - Remove Store Setup Alert #5499
* Tweak - Customers: Update column heading for date registered #5542
* Tweak - alter homescreen layout. #5465
* Fix - Added support for custom actionable statuses. #5550
* Fix - wrong casing used on the PayPal brand name #5514 🎉 @rtpHarry
* Fix - Import @wordpress/base-styles/default-custom-properties #5491
* Fix - downloads report #5441
* Fix - missing custom autocompleter attribute in Search component of Advanced Filter #5448
* Fix - empty no posts state on Marketing page. #5411
* Fix - visual issues in the Search component. #5199
* Fix - Inconsistent line endings in readme.txt. #5281
* Fix - popover menu to expand menu item width to 100% #5519
* Fix - Wrong class name for querying Categories Report #5522 🎉 @zzap
* Fix - Remove label printing mention for non us countries #5527
* Fix - First product script navigation dependency #5584
* Fix - Added support for custom actionable statuses #5550
* Fix - Display the store management links last on the homescreen #5579
* Fix - Ensure the "Set up additional payment providers" inbox notification is shown when relevant after completing the OBW. #5547
* Fix - Load wc-tracks in the homepage notice admin script. #5638
* Fix - Link component prop caused a React warning. #5653
* Fix - Flickering of order panel while loading. #5655
* Fix - Tax code duplicated when clicking the button to remove. #5638
* Fix - Restore Autoloading of WooCommerce Classes in PHP Tests. #5650
* Fix - Skip WC Payment plugin note if plugin not added through the onboarding process. #5619
* Fix - Use error_log() to log the deprecated class calls instead of `_deprecated_function()`. #5802
* Fix - Don't show the Orders panel on the homescreen with the Task List. #5552
* Fix - Home Screen: Do not show store setup activity panel. #5801
* Dev - Home Screen - migrate orders panel. #5455
* Dev - Store Profiler - include Creative Mail as a free extension #5543
* Dev - Add undefined check in intervals data util #5546
* Dev - Fix wakeup visibility for PHP 8 compatibility #5211
* Dev - Fix header height and positioning for wc nav #5173
* Dev - Add remote inbox notification rule processors for country and state #5203
* Dev - Rename admin notes classes and file names to fit conventions #514
* Dev - remove checks of store registration that are no longer needed. #5170
* Dev - Fix version update script for composer.json #5165
* Dev - Remove getAdminLink from data package #5158
* Dev - Bump @woocommerce/components dependencies. #5153
* Dev - Add note status remote inbox notifications rule processor #5207
* Dev - Make code chunk filenames more stable. #5229
* Dev - Inbox Panel component moved #5252
* Dev - Added animation to Inbox note deletion #5263
* Dev - Update starter pack dependencies #5254
* Dev - Ensure test zips have latest packages from npm and composer. #5313
* Dev - Add remote inbox notifications rule allowing access to any option #5206
* Dev - Add manage orders on the go admin note #5159
* Dev - Add WooCommerceDependencyExtractionWebpackPlugin package #5198
* Dev - Migrate devdocs examples to Storybook stories #5271
* Dev - Remove Enzyme in favor of React Testing Library #5299
* Dev - Add exclusion rule to PHPCS config for TODO comments #5388
* Dev - Remove no longer used isPanelEmpty logic. #5423
* Dev - Use new @wordpress/components Card on Marketing page. #5428
* Dev - Add PSR-4 naming checks to PHP linting. #5512
* Dev - Rearrange the store management links under categories add filter woocommerce_admin_homescreen_quicklinks. #5476
* Dev - Restyle the setup task list header to display incomplete tasks #5520
**WooCommerce Blocks - 3.7.0 & 3.7.1 & 3.8.0 & 3.8.1**
* Enhancement - Allow shoppers to sign-up for an account from the Checkout block. #3331
* Enhancement - Standardise & refactor colors scss to align with Gutenberg colors and WooCommerce brand. #3300
* Tweak - Show the phone number field in the billing section when shipping is disabled in settings. #3376
* Tweak - Add new doc referencing feature flags and experimental interfaces. #3348
* Tweak - Add __experimental_woocommerce_blocks_checkout_order_processed action. #3238
* Fix - Fix PHP 8 error when argument is not invocable in AssetsDataRegistry::Add_data. #3315
* Fix - Improve layout of Cart block line item quantity selector & price on smaller screens. #3299
* Fix - Correctly process orders with $0 total (e.g. via coupon) in Checkout block. #3298
* Fix - Respect Enable Taxes setting for checkout block taxes display. #3291
* Fix - Fix 3D secure payment errors. #3272
* Fix - Show current selected attributes when re-edit Products by Attribute block. #3185
* Fix - Ensure that accounts are not created via checkout block request if account registration is disabled for WooCommerce. #3371
* Fix - radio controls and checkboxes in Twenty Twenty One dark theme. #3446
* Fix - Twenty Twenty One Price filter, Active filters and radio control styling. #3444
* Fix - Twenty Twenty One Button and Placeholder Styling. #3443
* Fix - checkbox and textarea styles in Twenty Twenty One when it has dark controls active. #3450
= 4.7.1 - 2020-11-24 =
**WooCommerce**
* Fix - Prevent variable product to be added to cart until a valid variation is selected first. #28103
* Fix - Restored support for custom `taxonomy-product_cat-<SLUG>.php` and `taxonomy-product_tag-<SLUG>.php` templates. #28377
* Fix - Display overrides of `taxonomy-product_<cat|tag>.php` and `content-product_cat.php` templates in Status page. #28378
* Dev - Apply `woocommerce_cart_needs_payment` filter in `WC_Checkout::process_checkout()` to make backwards compatible. #28281
= 4.7.0 - 2020-11-10 =
**WooCommerce**

View File

@ -6,25 +6,30 @@
"license": "GPL-3.0-or-later",
"prefer-stable": true,
"minimum-stability": "dev",
"repositories": [
{
"type": "path",
"url": "lib"
}
],
"require": {
"php": ">=7.0",
"automattic/jetpack-autoloader": "2.2.0",
"automattic/jetpack-constants": "1.5.0",
"composer/installers": "1.7.0",
"automattic/jetpack-autoloader": "2.6.0",
"automattic/jetpack-constants": "1.5.1",
"composer/installers": "~1.7",
"maxmind-db/reader": "1.6.0",
"pelago/emogrifier": "3.1.0",
"psr/container": "1.0.0",
"woocommerce/action-scheduler": "3.1.6",
"woocommerce/woocommerce-admin": "1.6.3",
"woocommerce/woocommerce-blocks": "3.6.0",
"league/container": "3.3.3"
"woocommerce/woocommerce-admin": "1.7.3",
"woocommerce/woocommerce-blocks": "3.8.1"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.4"
},
"config": {
"platform": {
"php": "7.1"
"php": "7.0"
},
"preferred-install": {
"woocommerce/action-scheduler": "dist",
@ -43,7 +48,10 @@
],
"psr-4": {
"Automattic\\WooCommerce\\": "src/",
"Automattic\\WooCommerce\\Vendor\\League\\Container\\": "vendor/league/container/"
"Automattic\\WooCommerce\\Vendor\\": "lib/packages/"
},
"psr-0": {
"Automattic\\WooCommerce\\Vendor\\": "lib/packages/"
}
},
"autoload-dev": {
@ -58,12 +66,10 @@
"scripts": {
"post-install-cmd": [
"@composer bin all install --ansi",
"sh ./bin/prefix-vendor-namespaces.sh",
"sh ./bin/package-update.sh"
],
"post-update-cmd": [
"@composer bin all update --ansi",
"sh ./bin/prefix-vendor-namespaces.sh",
"sh ./bin/package-update.sh"
],
"test": [
@ -86,14 +92,18 @@
],
"bin": [
"echo 'bin not installed'"
],
"build-lib": [
"sh ./bin/build-lib.sh"
]
},
"extra": {
"installer-paths": {
"packages/action-scheduler": ["woocommerce/action-scheduler"],
"packages/woocommerce-rest-api": ["woocommerce/woocommerce-rest-api"],
"packages/woocommerce-blocks": ["woocommerce/woocommerce-blocks"],
"packages/woocommerce-admin": ["woocommerce/woocommerce-admin"]
"packages/{$name}": [
"woocommerce/action-scheduler",
"woocommerce/woocommerce-blocks",
"woocommerce/woocommerce-admin"
]
},
"scripts-description": {
"test": "Run unit tests",

193
composer.lock generated
View File

@ -4,20 +4,20 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "ed84c4d91482a5c508caaf50e843de58",
"content-hash": "77e54b85eedb5be94edbd73cf5436900",
"packages": [
{
"name": "automattic/jetpack-autoloader",
"version": "v2.2.0",
"version": "v2.6.0",
"source": {
"type": "git",
"url": "https://github.com/Automattic/jetpack-autoloader.git",
"reference": "66a5d150b3928be718d86696f85631a7f0b98a7b"
"reference": "47dde8dbca6b1e30f176725f2f748a9abefcaf58"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/66a5d150b3928be718d86696f85631a7f0b98a7b",
"reference": "66a5d150b3928be718d86696f85631a7f0b98a7b",
"url": "https://api.github.com/repos/Automattic/jetpack-autoloader/zipball/47dde8dbca6b1e30f176725f2f748a9abefcaf58",
"reference": "47dde8dbca6b1e30f176725f2f748a9abefcaf58",
"shasum": ""
},
"require": {
@ -31,6 +31,9 @@
"class": "Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin"
},
"autoload": {
"classmap": [
"src/AutoloadGenerator.php"
],
"psr-4": {
"Automattic\\Jetpack\\Autoloader\\": "src"
}
@ -40,20 +43,20 @@
"GPL-2.0-or-later"
],
"description": "Creates a custom autoloader for a plugin or theme.",
"time": "2020-08-14T20:34:36+00:00"
"time": "2020-11-19T21:20:12+00:00"
},
{
"name": "automattic/jetpack-constants",
"version": "v1.5.0",
"version": "v1.5.1",
"source": {
"type": "git",
"url": "https://github.com/Automattic/jetpack-constants.git",
"reference": "9827a2f446b8c4faafaf1c740483031c073a381d"
"reference": "18f772daddc8be5df76c9f4a92e017a3c2569a5b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Automattic/jetpack-constants/zipball/9827a2f446b8c4faafaf1c740483031c073a381d",
"reference": "9827a2f446b8c4faafaf1c740483031c073a381d",
"url": "https://api.github.com/repos/Automattic/jetpack-constants/zipball/18f772daddc8be5df76c9f4a92e017a3c2569a5b",
"reference": "18f772daddc8be5df76c9f4a92e017a3c2569a5b",
"shasum": ""
},
"require-dev": {
@ -71,32 +74,35 @@
"GPL-2.0-or-later"
],
"description": "A wrapper for defining constants in a more testable way.",
"time": "2020-08-13T14:33:09+00:00"
"time": "2020-10-28T19:00:31+00:00"
},
{
"name": "composer/installers",
"version": "v1.7.0",
"version": "v1.9.0",
"source": {
"type": "git",
"url": "https://github.com/composer/installers.git",
"reference": "141b272484481432cda342727a427dc1e206bfa0"
"reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/installers/zipball/141b272484481432cda342727a427dc1e206bfa0",
"reference": "141b272484481432cda342727a427dc1e206bfa0",
"url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca",
"reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca",
"shasum": ""
},
"require": {
"composer-plugin-api": "^1.0"
"composer-plugin-api": "^1.0 || ^2.0"
},
"replace": {
"roundcube/plugin-installer": "*",
"shama/baton": "*"
},
"require-dev": {
"composer/composer": "1.0.*@dev",
"phpunit/phpunit": "^4.8.36"
"composer/composer": "1.6.* || 2.0.*@dev",
"composer/semver": "1.0.* || 2.0.*@dev",
"phpunit/phpunit": "^4.8.36",
"sebastian/comparator": "^1.2.4",
"symfony/process": "^2.3"
},
"type": "composer-plugin",
"extra": {
@ -132,6 +138,7 @@
"Kanboard",
"Lan Management System",
"MODX Evo",
"MantisBT",
"Mautic",
"Maya",
"OXID",
@ -186,6 +193,7 @@
"shopware",
"silverstripe",
"sydes",
"sylius",
"symfony",
"typo3",
"wordpress",
@ -193,79 +201,17 @@
"zend",
"zikula"
],
"time": "2019-08-12T15:00:31+00:00"
},
{
"name": "league/container",
"version": "3.3.3",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/container.git",
"reference": "7dc67bdf89efc338e674863c0ea70a63efe4de05"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/container/zipball/7dc67bdf89efc338e674863c0ea70a63efe4de05",
"reference": "7dc67bdf89efc338e674863c0ea70a63efe4de05",
"shasum": ""
},
"require": {
"php": "^7.0 || ^8.0",
"psr/container": "^1.0"
},
"provide": {
"psr/container-implementation": "^1.0"
},
"replace": {
"orno/di": "~2.0"
},
"require-dev": {
"phpunit/phpunit": "^6.0",
"squizlabs/php_codesniffer": "^3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-3.x": "3.x-dev",
"dev-2.x": "2.x-dev",
"dev-1.x": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"League\\Container\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Phil Bennett",
"email": "philipobenito@gmail.com",
"homepage": "http://www.philipobenito.com",
"role": "Developer"
}
],
"description": "A fast and intuitive dependency injection container.",
"homepage": "https://github.com/thephpleague/container",
"keywords": [
"container",
"dependency",
"di",
"injection",
"league",
"provider",
"service"
],
"funding": [
{
"url": "https://github.com/philipobenito",
"type": "github"
"url": "https://packagist.com",
"type": "custom"
},
{
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
"type": "tidelift"
}
],
"time": "2020-09-28T13:38:44+00:00"
"time": "2020-04-07T06:57:05+00:00"
},
{
"name": "maxmind-db/reader",
@ -452,22 +398,27 @@
},
{
"name": "symfony/css-selector",
"version": "v3.4.46",
"version": "v3.3.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33"
"reference": "4d882dced7b995d5274293039370148e291808f2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/da3d9da2ce0026771f5fe64cb332158f1bd2bc33",
"reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/4d882dced7b995d5274293039370148e291808f2",
"reference": "4d882dced7b995d5274293039370148e291808f2",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8"
"php": ">=5.5.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\CssSelector\\": ""
@ -481,14 +432,14 @@
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Jean-François Simon",
"email": "jeanfrancois.simon@sensiolabs.com"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
@ -496,21 +447,7 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-24T10:57:07+00:00"
"time": "2017-05-01T15:01:29+00:00"
},
{
"name": "woocommerce/action-scheduler",
@ -549,26 +486,27 @@
},
{
"name": "woocommerce/woocommerce-admin",
"version": "1.6.3",
"version": "1.7.3",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-admin.git",
"reference": "3015abbda8657ef097b7763e4c941daa06dab6f7"
"reference": "16de972f319e5e6fc8dbebf5024dd263234f39e0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/3015abbda8657ef097b7763e4c941daa06dab6f7",
"reference": "3015abbda8657ef097b7763e4c941daa06dab6f7",
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/16de972f319e5e6fc8dbebf5024dd263234f39e0",
"reference": "16de972f319e5e6fc8dbebf5024dd263234f39e0",
"shasum": ""
},
"require": {
"automattic/jetpack-autoloader": "^2.2.0",
"composer/installers": "1.7.0",
"composer/installers": "^1.9.0",
"php": ">=5.6|>=7.0"
},
"require-dev": {
"phpunit/phpunit": "7.5.20",
"woocommerce/woocommerce-sniffs": "0.0.9"
"suin/phpcs-psr4-sniff": "^2.2",
"woocommerce/woocommerce-sniffs": "0.1.0"
},
"type": "wordpress-plugin",
"extra": {
@ -579,9 +517,6 @@
}
},
"autoload": {
"classmap": [
"includes/"
],
"psr-4": {
"Automattic\\WooCommerce\\Admin\\": "src/"
}
@ -592,29 +527,29 @@
],
"description": "A modern, javascript-driven WooCommerce Admin experience.",
"homepage": "https://github.com/woocommerce/woocommerce-admin",
"time": "2020-10-26T20:25:00+00:00"
"time": "2020-12-03T21:12:01+00:00"
},
{
"name": "woocommerce/woocommerce-blocks",
"version": "v3.6.0",
"version": "v3.8.1",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-gutenberg-products-block.git",
"reference": "1046697451f5e8906e48f0a7532b7637c3ded108"
"reference": "e5aef9eddd13c5511ba673eb70ed8cb3e80d828c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/1046697451f5e8906e48f0a7532b7637c3ded108",
"reference": "1046697451f5e8906e48f0a7532b7637c3ded108",
"url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/e5aef9eddd13c5511ba673eb70ed8cb3e80d828c",
"reference": "e5aef9eddd13c5511ba673eb70ed8cb3e80d828c",
"shasum": ""
},
"require": {
"automattic/jetpack-autoloader": "^2.0.0",
"composer/installers": "1.7.0"
"composer/installers": "^1.7.0"
},
"require-dev": {
"phpunit/phpunit": "6.5.14",
"woocommerce/woocommerce-sniffs": "0.0.7"
"woocommerce/woocommerce-sniffs": "0.1.0"
},
"type": "wordpress-plugin",
"extra": {
@ -639,7 +574,7 @@
"gutenberg",
"woocommerce"
],
"time": "2020-10-12T15:35:42+00:00"
"time": "2020-11-23T20:48:39+00:00"
}
],
"packages-dev": [
@ -700,7 +635,7 @@
},
"platform-dev": [],
"platform-overrides": {
"php": "7.1"
"php": "7.0"
},
"plugin-api-version": "1.1.0"
}

View File

@ -583,6 +583,7 @@ return array(
'JH' => __( 'Jharkhand', 'woocommerce' ),
'KA' => __( 'Karnataka', 'woocommerce' ),
'KL' => __( 'Kerala', 'woocommerce' ),
'LA' => __( 'Ladakh', 'woocommerce' ),
'MP' => __( 'Madhya Pradesh', 'woocommerce' ),
'MH' => __( 'Maharashtra', 'woocommerce' ),
'MN' => __( 'Manipur', 'woocommerce' ),
@ -1236,6 +1237,7 @@ return array(
'SD' => __( 'Sindh', 'woocommerce' ),
),
'PL' => array(),
'PR' => array(),
'PT' => array(),
'PY' => array( // Paraguay states.
'PY-ASU' => __( 'Asunción', 'woocommerce' ),
@ -1501,7 +1503,7 @@ return array(
'TZ30' => __( 'Simiyu', 'woocommerce' ),
),
'LK' => array(),
'RS' => array( // Serbia districts. Ref: https://github.com/unicode-org/cldr/blob/release-37/common/subdivisions/en.xml#L4251-L4283
'RS' => array( // Serbia districts. Ref: https://github.com/unicode-org/cldr/blob/release-37/common/subdivisions/en.xml#L4251-L4283.
'RS00' => _x( 'Belgrade', 'district', 'woocommerce' ),
'RS14' => _x( 'Bor', 'district', 'woocommerce' ),
'RS11' => _x( 'Braničevo', 'district', 'woocommerce' ),

View File

@ -519,6 +519,50 @@ abstract class WC_Data {
}
}
/**
* Helper method to compute meta cache key. Different from WP Meta cache key in that meta data cached using this key also contains meta_id column.
*
* @since 4.7.0
*
* @return string
*/
public function get_meta_cache_key() {
if ( ! $this->get_id() ) {
wc_doing_it_wrong( 'get_meta_cache_key', 'ID needs to be set before fetching a cache key.', '4.7.0' );
return false;
}
return self::generate_meta_cache_key( $this->get_id(), $this->cache_group );
}
/**
* Generate cache key from id and group.
*
* @since 4.7.0
*
* @param int|string $id Object ID.
* @param string $cache_group Group name use to store cache. Whole group cache can be invalidated in one go.
*
* @return string Meta cache key.
*/
public static function generate_meta_cache_key( $id, $cache_group ) {
return WC_Cache_Helper::get_cache_prefix( $cache_group ) . WC_Cache_Helper::get_cache_prefix( 'object_' . $id ) . 'object_meta_' . $id;
}
/**
* Prime caches for raw meta data. This includes meta_id column as well, which is not included by default in WP meta data.
*
* @since 4.7.0
*
* @param array $raw_meta_data_collection Array of objects of { object_id => array( meta_row_1, meta_row_2, ... }.
* @param string $cache_group Name of cache group.
*/
public static function prime_raw_meta_data_cache( $raw_meta_data_collection, $cache_group ) {
foreach ( $raw_meta_data_collection as $object_id => $raw_meta_data_array ) {
$cache_key = self::generate_meta_cache_key( $object_id, $cache_group );
wp_cache_set( $cache_key, $raw_meta_data_array, $cache_group );
}
}
/**
* Read Meta Data from the database. Ignore any internal properties.
* Uses it's own caches because get_metadata does not provide meta_ids.
@ -540,7 +584,7 @@ abstract class WC_Data {
if ( ! empty( $this->cache_group ) ) {
// Prefix by group allows invalidation by group until https://core.trac.wordpress.org/ticket/4476 is implemented.
$cache_key = WC_Cache_Helper::get_cache_prefix( $this->cache_group ) . WC_Cache_Helper::get_cache_prefix( 'object_' . $this->get_id() ) . 'object_meta_' . $this->get_id();
$cache_key = $this->get_meta_cache_key();
}
if ( ! $force_read ) {
@ -550,7 +594,9 @@ abstract class WC_Data {
}
}
$raw_meta_data = $cache_loaded ? $cached_meta : $this->data_store->read_meta( $this );
// We filter the raw meta data again when loading from cache, in case we cached in an earlier version where filter conditions were different.
$raw_meta_data = $cache_loaded ? $this->data_store->filter_raw_meta_data( $this, $cached_meta ) : $this->data_store->read_meta( $this );
if ( $raw_meta_data ) {
foreach ( $raw_meta_data as $meta ) {
$this->meta_data[] = new WC_Meta_Data(

View File

@ -218,7 +218,7 @@ abstract class WC_Payment_Gateway extends WC_Settings_API {
/**
* Get the return url (thank you page).
*
* @param WC_Order $order Order object.
* @param WC_Order|null $order Order object.
* @return string
*/
public function get_return_url( $order = null ) {
@ -369,9 +369,9 @@ abstract class WC_Payment_Gateway extends WC_Settings_API {
* If the gateway declares 'refunds' support, this will allow it to refund.
* a passed in amount.
*
* @param int $order_id Order ID.
* @param float $amount Refund amount.
* @param string $reason Refund reason.
* @param int $order_id Order ID.
* @param float|null $amount Refund amount.
* @param string $reason Refund reason.
* @return boolean True or false based on success, or a WP_Error object.
*/
public function process_refund( $order_id, $amount = null, $reason = '' ) {

View File

@ -370,9 +370,9 @@ class WC_Admin_Addons {
$defaults = array(
'image' => WC()->plugin_url() . '/assets/images/wcs-extensions-banner-3x.png',
'image_alt' => __( 'WooCommerce Services', 'woocommerce' ),
'image_alt' => __( 'WooCommerce Shipping', 'woocommerce' ),
'title' => __( 'Buy discounted shipping labels — then print them from your dashboard.', 'woocommerce' ),
'description' => __( 'Integrate your store with USPS to buy discounted shipping labels, and print them directly from your WooCommerce dashboard. Powered by WooCommerce Services.', 'woocommerce' ),
'description' => __( 'Integrate your store with USPS to buy discounted shipping labels, and print them directly from your WooCommerce dashboard. Powered by WooCommerce Shipping.', 'woocommerce' ),
'button' => __( 'Free - Install now', 'woocommerce' ),
'href' => $button_url,
'logos' => array(),
@ -383,7 +383,7 @@ class WC_Admin_Addons {
$local_defaults = array(
'image' => WC()->plugin_url() . '/assets/images/wcs-truck-banner-3x.png',
'title' => __( 'Show Canada Post shipping rates', 'woocommerce' ),
'description' => __( 'Display live rates from Canada Post at checkout to make shipping a breeze. Powered by WooCommerce Services.', 'woocommerce' ),
'description' => __( 'Display live rates from Canada Post at checkout to make shipping a breeze. Powered by WooCommerce Shipping.', 'woocommerce' ),
'logos' => array_merge(
$defaults['logos'],
array(
@ -440,7 +440,69 @@ class WC_Admin_Addons {
self::output_button(
$block_data['href'],
$block_data['button'],
'addons-button-outline-green'
'addons-button-outline-purple'
);
?>
</div>
</div>
<?php
}
/**
* Handles the outputting of the WooCommerce Pay banner block.
*
* @param object $block Block data.
*/
public static function output_wcpay_banner_block( $block = array() ) {
$is_active = is_plugin_active( 'woocommerce-payments/woocommerce-payments.php' );
$location = wc_get_base_location();
if (
! in_array( $location['country'], array( 'US' ), true ) ||
$is_active ||
! current_user_can( 'install_plugins' ) ||
! current_user_can( 'activate_plugins' )
) {
return;
}
$button_url = wp_nonce_url(
add_query_arg(
array(
'install-addon' => 'woocommerce-payments',
)
),
'install-addon_woocommerce-payments'
);
$defaults = array(
'image' => WC()->plugin_url() . '/assets/images/wcpayments-icon-secure.png',
'image_alt' => __( 'WooCommerce Payments', 'woocommerce' ),
'title' => __( 'Payments made simple, with no monthly fees &mdash; exclusively for WooCommerce stores.', 'woocommerce' ),
'description' => __( 'Securely accept cards in your store. See payments, track cash flow into your bank account, and stay on top of disputes right from your dashboard.', 'woocommerce' ),
'button' => __( 'Free - Install now', 'woocommerce' ),
'href' => $button_url,
'logos' => array(),
);
$block_data = array_merge( $defaults, $block );
?>
<div class="addons-wcs-banner-block">
<div class="addons-wcs-banner-block-image">
<img
class="addons-img"
src="<?php echo esc_url( $block_data['image'] ); ?>"
alt="<?php echo esc_attr( $block_data['image_alt'] ); ?>"
/>
</div>
<div class="addons-wcs-banner-block-content">
<h1><?php echo esc_html( $block_data['title'] ); ?></h1>
<p><?php echo esc_html( $block_data['description'] ); ?></p>
<?php
self::output_button(
$block_data['href'],
$block_data['button'],
'addons-button-outline-purple'
);
?>
</div>
@ -477,6 +539,9 @@ class WC_Admin_Addons {
case 'wcs_banner_block':
self::output_wcs_banner_block( (array) $section );
break;
case 'wcpay_banner_block':
self::output_wcpay_banner_block( (array) $section );
break;
}
}
}
@ -520,7 +585,7 @@ class WC_Admin_Addons {
* @param string $plugin The plugin the button is promoting.
*/
public static function output_button( $url, $text, $style, $plugin = '' ) {
$style = __( 'Free', 'woocommerce' ) === $text ? 'addons-button-outline-green' : $style;
$style = __( 'Free', 'woocommerce' ) === $text ? 'addons-button-outline-purple' : $style;
$style = is_plugin_active( $plugin ) ? 'addons-button-installed' : $style;
$text = is_plugin_active( $plugin ) ? __( 'Installed', 'woocommerce' ) : $text;
$url = self::add_in_app_purchase_url_params( $url );
@ -546,8 +611,18 @@ class WC_Admin_Addons {
return;
}
if ( isset( $_GET['install-addon'] ) && 'woocommerce-services' === $_GET['install-addon'] ) {
self::install_woocommerce_services_addon();
if ( isset( $_GET['install-addon'] ) ) {
switch ( $_GET['install-addon'] ) {
case 'woocommerce-services':
self::install_woocommerce_services_addon();
break;
case 'woocommerce-payments':
self::install_woocommerce_payments_addon();
break;
default:
// Do nothing.
break;
}
}
$sections = self::get_sections();
@ -591,6 +666,26 @@ class WC_Admin_Addons {
exit;
}
/**
* Install WooCommerce Payments from the Extensions screens.
*
* @return void
*/
public static function install_woocommerce_payments_addon() {
check_admin_referer( 'install-addon_woocommerce-payments' );
$wcpay_plugin_id = 'woocommerce-payments';
$wcpay_plugin = array(
'name' => __( 'WooCommerce Payments', 'woocommerce' ),
'repo-slug' => 'woocommerce-payments',
);
WC_Install::background_installer( $services_plugin_id, $wcpay_plugin );
wp_safe_redirect( remove_query_arg( array( 'install-addon', '_wpnonce' ) ) );
exit;
}
/**
* Should an extension be shown on the featured page.
*

View File

@ -462,7 +462,7 @@ class WC_Admin_Attributes {
<script type="text/javascript">
/* <![CDATA[ */
jQuery( 'a.delete' ).click( function() {
jQuery( 'a.delete' ).on( 'click', function() {
if ( window.confirm( '<?php esc_html_e( 'Are you sure you want to delete this attribute?', 'woocommerce' ); ?>' ) ) {
return true;
}

View File

@ -377,6 +377,11 @@ class WC_Admin_Status {
private static function output_plugins_info( $plugins, $untested_plugins ) {
$wc_version = Constants::get_constant( 'WC_VERSION' );
if ( 'major' === WC_SSR_PLUGIN_UPDATE_RELEASE_VERSION_TYPE ) {
// Since we're only testing against major, we don't need to show minor and patch version.
$wc_version = $wc_version[0] . '.0';
}
foreach ( $plugins as $plugin ) {
if ( ! empty( $plugin['name'] ) ) {
// Link the plugin name to the plugin url if available.

View File

@ -236,7 +236,7 @@ class WC_Admin {
'<a href="https://wordpress.org/support/plugin/woocommerce/reviews?rate=5#new-post" target="_blank" class="wc-rating-link" aria-label="' . esc_attr__( 'five star', 'woocommerce' ) . '" data-rated="' . esc_attr__( 'Thanks :)', 'woocommerce' ) . '">&#9733;&#9733;&#9733;&#9733;&#9733;</a>'
);
wc_enqueue_js(
"jQuery( 'a.wc-rating-link' ).click( function() {
"jQuery( 'a.wc-rating-link' ).on( 'click', function() {
jQuery.post( '" . WC()->ajax_url() . "', { action: 'woocommerce_rated' } );
jQuery( this ).parent().text( jQuery( this ).data( 'rated' ) );
});"

View File

@ -57,6 +57,10 @@ class WC_Helper_Updater {
'upgrade_notice' => $data['upgrade_notice'],
);
if ( isset( $data['requires_php'] ) ) {
$item['requires_php'] = $data['requires_php'];
}
// We don't want to deliver a valid upgrade package when their subscription has expired.
// To avoid the generic "no_package" error that empty strings give, we will store an
// indication of expiration for the `upgrader_pre_download` filter to error on.

View File

@ -194,7 +194,7 @@ class WC_Meta_Box_Coupon_Data {
foreach ( $product_ids as $product_id ) {
$product = wc_get_product( $product_id );
if ( is_object( $product ) ) {
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . htmlspecialchars( wp_kses_post( $product->get_formatted_name() ) ) . '</option>';
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
}
}
?>
@ -212,7 +212,7 @@ class WC_Meta_Box_Coupon_Data {
foreach ( $product_ids as $product_id ) {
$product = wc_get_product( $product_id );
if ( is_object( $product ) ) {
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . htmlspecialchars( wp_kses_post( $product->get_formatted_name() ) ) . '</option>';
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
}
}
?>

View File

@ -3,7 +3,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<div data-taxonomy="<?php echo esc_attr( $attribute->get_taxonomy() ); ?>" class="woocommerce_attribute wc-metabox closed <?php echo esc_attr( implode( ' ', $metabox_class ) ); ?>" rel="<?php echo esc_attr( $attribute->get_position() ); ?>">
<div data-taxonomy="<?php echo esc_attr( $attribute->get_taxonomy() ); ?>" class="woocommerce_attribute wc-metabox postbox closed <?php echo esc_attr( implode( ' ', $metabox_class ) ); ?>" rel="<?php echo esc_attr( $attribute->get_position() ); ?>">
<h3>
<a href="#" class="remove_row delete"><?php esc_html_e( 'Remove', 'woocommerce' ); ?></a>
<div class="handlediv" title="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div>

View File

@ -19,7 +19,7 @@ defined( 'ABSPATH' ) || exit;
foreach ( $product_ids as $product_id ) {
$product = wc_get_product( $product_id );
if ( is_object( $product ) ) {
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . htmlspecialchars( wp_kses_post( $product->get_formatted_name() ) ) . '</option>';
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
}
}
?>
@ -37,7 +37,7 @@ defined( 'ABSPATH' ) || exit;
foreach ( $product_ids as $product_id ) {
$product = wc_get_product( $product_id );
if ( is_object( $product ) ) {
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . htmlspecialchars( wp_kses_post( $product->get_formatted_name() ) ) . '</option>';
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
}
}
?>
@ -53,7 +53,7 @@ defined( 'ABSPATH' ) || exit;
foreach ( $product_ids as $product_id ) {
$product = wc_get_product( $product_id );
if ( is_object( $product ) ) {
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . htmlspecialchars( wp_kses_post( $product->get_formatted_name() ) ) . '</option>';
echo '<option value="' . esc_attr( $product_id ) . '"' . selected( true, true, false ) . '>' . esc_html( wp_strip_all_tags( $product->get_formatted_name() ) ) . '</option>';
}
}
?>

View File

@ -10,7 +10,7 @@
defined( 'ABSPATH' ) || exit;
use \Automattic\Jetpack\Constants;
use \Automattic\WooCommerce\Admin\Notes\WC_Admin_Note;
use Automattic\WooCommerce\Admin\Notes\Note;
/**
* WC_Notes_Run_Db_Update.
@ -58,7 +58,7 @@ class WC_Notes_Run_Db_Update {
// Remove weird duplicates. Leave the first one.
$current_notice = array_shift( $note_ids );
foreach ( $note_ids as $note_id ) {
$note = new WC_Admin_Note( $note_id );
$note = new Note( $note_id );
$data_store->delete( $note );
}
return $current_notice;
@ -77,8 +77,8 @@ class WC_Notes_Run_Db_Update {
return;
}
$note = new WC_Admin_Note( $note_id );
$note->set_status( WC_Admin_Note::E_WC_ADMIN_NOTE_ACTIONED );
$note = new Note( $note_id );
$note->set_status( Note::E_WC_ADMIN_NOTE_ACTIONED );
$note->save();
}
@ -89,7 +89,7 @@ class WC_Notes_Run_Db_Update {
* - actions are set up for the first 'Update database' notice, and
* - URL for note's action is equal to the given URL (to check for potential nonce update).
*
* @param WC_Admin_Note $note Note to check.
* @param Note $note Note to check.
* @param string $update_url URL to check the note against.
* @param array<int, string> $current_actions List of actions to check for.
* @return bool
@ -135,9 +135,9 @@ class WC_Notes_Run_Db_Update {
);
if ( $note_id ) {
$note = new WC_Admin_Note( $note_id );
$note = new Note( $note_id );
} else {
$note = new WC_Admin_Note();
$note = new Note();
}
// Check if the note needs to be updated (e.g. expired nonce or different note type stored in the previous run).
@ -151,13 +151,13 @@ class WC_Notes_Run_Db_Update {
/* translators: %1$s: opening <a> tag %2$s: closing </a> tag*/
. sprintf( ' ' . esc_html__( 'The database update process runs in the background and may take a little while, so please be patient. Advanced users can alternatively update via %1$sWP CLI%2$s.', 'woocommerce' ), '<a href="https://github.com/woocommerce/woocommerce/wiki/Upgrading-the-database-using-WP-CLI">', '</a>' )
);
$note->set_type( WC_Admin_Note::E_WC_ADMIN_NOTE_UPDATE );
$note->set_type( Note::E_WC_ADMIN_NOTE_UPDATE );
$note->set_name( self::NOTE_NAME );
$note->set_content_data( (object) array() );
$note->set_source( 'woocommerce-core' );
// In case db version is out of sync with WC version or during the next update, the notice needs to show up again,
// so set it to unactioned.
$note->set_status( WC_Admin_Note::E_WC_ADMIN_NOTE_UNACTIONED );
$note->set_status( Note::E_WC_ADMIN_NOTE_UNACTIONED );
// Set new actions.
$note->clear_actions();
@ -181,7 +181,7 @@ class WC_Notes_Run_Db_Update {
$cron_disabled = Constants::is_true( 'DISABLE_WP_CRON' );
$cron_cta = $cron_disabled ? __( 'You can manually run queued updates here.', 'woocommerce' ) : __( 'View progress →', 'woocommerce' );
$note = new WC_Admin_Note( $note_id );
$note = new Note( $note_id );
$note->set_title( __( 'WooCommerce database update in progress', 'woocommerce' ) );
$note->set_content( __( 'WooCommerce is updating the database in the background. The database update process may take a little while, so please be patient.', 'woocommerce' ) );
@ -227,7 +227,7 @@ class WC_Notes_Run_Db_Update {
),
);
$note = new WC_Admin_Note( $note_id );
$note = new Note( $note_id );
// Check if the note needs to be updated (e.g. expired nonce or different note type stored in the previous run).
if ( self::note_up_to_date( $note, $hide_notices_url, wp_list_pluck( $note_actions, 'name' ) ) ) {
@ -266,7 +266,7 @@ class WC_Notes_Run_Db_Update {
return;
}
$note = new WC_Admin_Note( $note_id );
$note = new Note( $note_id );
if ( $note::E_WC_ADMIN_NOTE_ACTIONED === $note->get_status() ) {
// Db update not needed && note actioned -> don't show it.
return;

View File

@ -163,15 +163,6 @@ class WC_Plugin_Updates {
$version .= '.' . $new_version_parts[1];
}
if ( 'major' === $release ) {
$current_version_parts = explode( '.', Constants::get_constant( 'WC_VERSION' ) );
// If user has already moved to the major version, we don't need to flag up anything.
if ( version_compare( $current_version_parts[0] . '.' . $current_version_parts[1], $new_version_parts[0] . '.0', '>=' ) ) {
return array();
}
}
foreach ( $extensions as $file => $plugin ) {
if ( ! empty( $plugin[ self::VERSION_TESTED_HEADER ] ) ) {
$plugin_version_parts = explode( '.', $plugin[ self::VERSION_TESTED_HEADER ] );

View File

@ -12,8 +12,6 @@ if ( ! defined( 'ABSPATH' ) ) {
/**
* WC_Report_Coupon_Usage
*
* @author WooThemes
* @category Admin
* @package WooCommerce\Admin\Reports
* @version 2.1.0
*/
@ -330,25 +328,26 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
</table>
</div>
<script type="text/javascript">
jQuery('.section_title').click(function(){
var next_section = jQuery(this).next('.section');
jQuery( '.section_title' ).on( 'click', function() {
var next_section = jQuery( this ).next( '.section' );
if ( jQuery(next_section).is(':visible') )
if ( jQuery( next_section ).is( ':visible' ) ) {
return false;
}
jQuery('.section:visible').slideUp();
jQuery('.section_title').removeClass('open');
jQuery(this).addClass('open').next('.section').slideDown();
jQuery( '.section:visible' ).slideUp();
jQuery( '.section_title' ).removeClass( 'open' );
jQuery( this ).addClass( 'open' ).next( '.section' ).slideDown();
return false;
});
jQuery('.section').slideUp( 100, function() {
} );
jQuery( '.section' ).slideUp( 100, function() {
<?php if ( empty( $this->coupon_codes ) ) : ?>
jQuery('.section_title:eq(1)').click();
jQuery( '.section_title:eq(1)' ).click();
<?php else : ?>
jQuery('.section_title:eq(0)').click();
jQuery( '.section_title:eq(0)' ).click();
<?php endif; ?>
});
} );
</script>
<?php
}

View File

@ -62,6 +62,7 @@ class WC_Report_Customer_List extends WP_List_Table {
delete_user_meta( $user_id, '_money_spent' );
delete_user_meta( $user_id, '_order_count' );
delete_user_meta( $user_id, '_last_order' );
/* translators: User display name */
echo '<div class="updated"><p>' . sprintf( esc_html__( 'Refreshed stats for %s', 'woocommerce' ), esc_html( $user->display_name ) ) . '</p></div>';
}

View File

@ -251,7 +251,12 @@ class WC_Report_Sales_By_Date extends WC_Admin_Report {
);
foreach ( $this->report_data->full_refunds as $key => $order ) {
$this->report_data->full_refunds[ $key ]->net_refund = $order->total_refund - ( $order->total_shipping + $order->total_tax + $order->total_shipping_tax );
$total_refund = is_numeric( $order->total_refund ) ? $order->total_refund : 0;
$total_shipping = is_numeric( $order->total_shipping ) ? $order->total_shipping : 0;
$total_tax = is_numeric( $order->total_tax ) ? $order->total_tax : 0;
$total_shipping_tax = is_numeric( $order->total_shipping_tax ) ? $order->total_shipping_tax : 0;
$this->report_data->full_refunds[ $key ]->net_refund = $total_refund - ( $total_shipping + $total_tax + $total_shipping_tax );
}
/**

View File

@ -374,23 +374,24 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
</table>
</div>
<script type="text/javascript">
jQuery('.section_title').click(function(){
var next_section = jQuery(this).next('.section');
jQuery( '.section_title' ).on( 'click', function() {
var next_section = jQuery( this ).next( '.section' );
if ( jQuery(next_section).is(':visible') )
if ( jQuery( next_section ).is( ':visible' ) ) {
return false;
}
jQuery('.section:visible').slideUp();
jQuery('.section_title').removeClass('open');
jQuery(this).addClass('open').next('.section').slideDown();
jQuery( '.section:visible' ).slideUp();
jQuery( '.section_title' ).removeClass( 'open' );
jQuery( this ).addClass( 'open' ).next( '.section' ).slideDown();
return false;
});
jQuery('.section').slideUp( 100, function() {
} );
jQuery( '.section' ).slideUp( 100, function() {
<?php if ( empty( $this->product_ids ) ) : ?>
jQuery('.section_title:eq(1)').click();
jQuery( '.section_title:eq(1)' ).click();
<?php endif; ?>
});
} );
</script>
<?php
}

View File

@ -41,6 +41,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( isset( $_GET['search'] ) ) : // phpcs:ignore WordPress.Security.NonceVerification.Recommended ?>
<h1 class="search-form-title" >
<?php // translators: search keyword. ?>
<?php printf( esc_html__( 'Showing search results for: %s', 'woocommerce' ), '<strong>' . esc_html( sanitize_text_field( wp_unslash( $_GET['search'] ) ) ) . '</strong>' ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended ?>
</h1>
<?php endif; ?>
@ -71,6 +72,11 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php WC_Admin_Addons::output_wcs_banner_block(); ?>
</div>
<?php endif; ?>
<?php if ( 'payment-gateways' === $current_section ) : ?>
<div class="addons-shipping-methods">
<?php WC_Admin_Addons::output_wcpay_banner_block(); ?>
</div>
<?php endif; ?>
<ul class="products">
<?php foreach ( $addons as $addon ) : ?>
<?php

View File

@ -22,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</form>
<?php
wc_enqueue_js(
"jQuery( '#flush-logs' ).click( function() {
"jQuery( '#flush-logs' ).on( 'click', function() {
if ( window.confirm('" . esc_js( __( 'Are you sure you want to clear all logs from the database?', 'woocommerce' ) ) . "') ) {
return true;
}

View File

@ -9,6 +9,11 @@ defined( 'ABSPATH' ) || exit;
global $wpdb;
if ( ! defined( 'WC_SSR_PLUGIN_UPDATE_RELEASE_VERSION_TYPE' ) ) {
// Define if we're checking against major or minor versions.
define( 'WC_SSR_PLUGIN_UPDATE_RELEASE_VERSION_TYPE', 'major' );
}
$report = wc()->api->get_endpoint_data( '/wc/v3/system_status' );
$environment = $report['environment'];
$database = $report['database'];
@ -21,7 +26,7 @@ $security = $report['security'];
$settings = $report['settings'];
$wp_pages = $report['pages'];
$plugin_updates = new WC_Plugin_Updates();
$untested_plugins = $plugin_updates->get_untested_plugins( WC()->version, 'minor' );
$untested_plugins = $plugin_updates->get_untested_plugins( WC()->version, WC_SSR_PLUGIN_UPDATE_RELEASE_VERSION_TYPE );
?>
<div class="updated woocommerce-message inline">
<p>

View File

@ -218,6 +218,14 @@ function wc_maybe_adjust_line_item_product_stock( $item, $item_quantity = -1 ) {
$refunded_item_quantity = $order->get_qty_refunded_for_item( $item->get_id() );
$diff = $item_quantity + $refunded_item_quantity - $already_reduced_stock;
/*
* 0 as $item_quantity usually indicates we're deleting the order item.
* We need to perform different calculations for this case.
*/
if ( 0 === $item_quantity ) {
$diff = min( absint( $refunded_item_quantity ), $already_reduced_stock ) * -1;
}
if ( $diff < 0 ) {
$new_stock = wc_update_product_stock( $product, $diff * -1, 'increase' );
} elseif ( $diff > 0 ) {

View File

@ -368,7 +368,7 @@ class WC_AJAX {
$woocommerce_checkout_payment = ob_get_clean();
// Get messages if reload checkout is not true.
$reload_checkout = isset( WC()->session->reload_checkout ) ? true : false;
$reload_checkout = isset( WC()->session->reload_checkout );
if ( ! $reload_checkout ) {
$messages = wc_print_notices( true );
} else {
@ -1594,7 +1594,7 @@ class WC_AJAX {
$formatted_name .= ' &ndash; ' . sprintf( __( 'Stock: %d', 'woocommerce' ), wc_format_stock_quantity_for_display( $stock_amount, $product_object ) );
}
$products[ $product_object->get_id() ] = rawurldecode( $formatted_name );
$products[ $product_object->get_id() ] = rawurldecode( wp_strip_all_tags( $formatted_name ) );
}
wp_send_json( apply_filters( 'woocommerce_json_search_found_products', $products ) );

View File

@ -1158,7 +1158,16 @@ class WC_Checkout {
do_action( 'woocommerce_checkout_order_processed', $order_id, $posted_data, $order );
if ( $order->needs_payment() ) {
/**
* Note that woocommerce_cart_needs_payment is only used in
* WC_Checkout::process_checkout() to keep backwards compatibility.
* Use woocommerce_order_needs_payment instead.
*
* Note that at this point you can't rely on the Cart Object anymore,
* since it could be empty see:
* https://github.com/woocommerce/woocommerce/issues/24631
*/
if ( apply_filters( 'woocommerce_cart_needs_payment', $order->needs_payment(), WC()->cart ) ) {
$this->process_order_payment( $order_id, $posted_data['payment_method'] );
} else {
$this->process_order_without_payment( $order_id );

View File

@ -358,9 +358,6 @@ class WC_Countries {
if ( 'eu_vat' === $type ) {
$countries[] = 'MC';
$countries[] = 'IM';
// The UK is still part of the EU VAT zone.
$countries[] = 'GB';
}
return apply_filters( 'woocommerce_european_union_countries', $countries, $type );
@ -528,7 +525,7 @@ class WC_Countries {
'NZ' => "{name}\n{company}\n{address_1}\n{address_2}\n{city} {postcode}\n{country}",
'NO' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
'PL' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
'PR' => "{company}\n{name}\n{address_1} {address_2}\n{state} \n{country} {postcode}",
'PR' => "{company}\n{name}\n{address_1} {address_2}\n{city} \n{country} {postcode}",
'PT' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
'SK' => "{company}\n{name}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
'RS' => "{name}\n{company}\n{address_1}\n{address_2}\n{postcode} {city}\n{country}",
@ -1205,11 +1202,11 @@ class WC_Countries {
),
'PR' => array(
'city' => array(
'required' => false,
'hidden' => true,
'label' => __( 'Municipality', 'woocommerce' ),
),
'state' => array(
'label' => __( 'Municipality', 'woocommerce' ),
'required' => false,
'hidden' => true,
),
),
'PT' => array(
@ -1230,10 +1227,10 @@ class WC_Countries {
),
'RS' => array(
'city' => array(
'required' => false,
'required' => true,
),
'postcode' => array(
'required' => false,
'required' => true,
),
'state' => array(
'label' => __( 'District', 'woocommerce' ),

View File

@ -190,7 +190,7 @@ class WC_Emails {
$this->init();
// Email Header, Footer and content hooks.
add_action( 'woocommerce_email_header', array( $this, 'email_header' ) );
add_action( 'woocommerce_email_header', array( $this, 'email_header' ), 10, 2 );
add_action( 'woocommerce_email_footer', array( $this, 'email_footer' ) );
add_action( 'woocommerce_email_order_details', array( $this, 'order_downloads' ), 10, 4 );
add_action( 'woocommerce_email_order_details', array( $this, 'order_details' ), 10, 4 );
@ -263,17 +263,26 @@ class WC_Emails {
/**
* Get the email header.
*
* @param mixed $email_heading Heading for the email.
* @param mixed $email_heading Heading for the email.
* @param WC_Email $email Email object for the email.
*/
public function email_header( $email_heading ) {
wc_get_template( 'emails/email-header.php', array( 'email_heading' => $email_heading ) );
public function email_header( $email_heading, $email ) {
wc_get_template(
'emails/email-header.php',
array(
'email_heading' => $email_heading,
'email' => $email,
)
);
}
/**
* Get the email footer.
*
* @param WC_Email $email Email object for the email.
*/
public function email_footer() {
wc_get_template( 'emails/email-footer.php' );
public function email_footer( $email ) {
wc_get_template( 'emails/email-footer.php', array( 'email' => $email ) );
}
/**

View File

@ -906,12 +906,9 @@ class WC_Form_Handler {
}
// Prevent parent variable product from being added to cart.
if ( empty( $variation_id ) && $product->is_type( 'variable' ) ) {
$url = get_permalink( $product_id );
$product_name = $product->get_name();
/* translators: %1$s: Product link, %2$s: Product title, %3$s: Product name. */
wc_add_notice( sprintf( __( 'Please choose product options by visiting <a href="%1$s" title="%2$s">%3$s</a>.', 'woocommerce' ), esc_url( $url ), esc_html( $product_name ), esc_html( $product_name ) ), 'error' );
if ( empty( $variation_id ) && $product && $product->is_type( 'variable' ) ) {
/* translators: 1: product link, 2: product name */
wc_add_notice( sprintf( __( 'Please choose product options by visiting <a href="%1$s" title="%2$s">%2$s</a>.', 'woocommerce' ), esc_url( get_permalink( $product_id ) ), esc_html( $product->get_name() ) ), 'error' );
return false;
}

View File

@ -1373,7 +1373,7 @@ CREATE TABLE {$wpdb->prefix}wc_reserved_stock (
);
if ( WCConnectionHelper::is_connected() ) {
$row_meta['premium_support'] = '<a href="' . esc_url( apply_filters( 'woocommerce_support_url', 'https://woocommerce.com/my-account/tickets/' ) ) . '" aria-label="' . esc_attr__( 'Visit premium customer support', 'woocommerce' ) . '">' . esc_html__( 'Premium support', 'woocommerce' ) . '</a>';
$row_meta['premium_support'] = '<a href="' . esc_url( apply_filters( 'woocommerce_support_url', 'https://woocommerce.com/my-account/create-a-ticket/' ) ) . '" aria-label="' . esc_attr__( 'Visit premium customer support', 'woocommerce' ) . '">' . esc_html__( 'Premium support', 'woocommerce' ) . '</a>';
}
return array_merge( $links, $row_meta );

View File

@ -406,8 +406,9 @@ class WC_Post_Data {
$customer->save();
}
// Delete order count meta.
// Delete order count and last order meta.
delete_user_meta( $customer_id, '_order_count' );
delete_user_meta( $customer_id, '_last_order' );
}
// Clean up items.

View File

@ -230,7 +230,7 @@ class WC_Shortcodes {
woocommerce_product_loop_end();
}
woocommerce_reset_loop();
wc_reset_loop();
return '<div class="woocommerce columns-' . $columns . '">' . ob_get_clean() . '</div>';
}

View File

@ -1191,8 +1191,10 @@ class WC_Tax {
public static function get_rates_for_tax_class( $tax_class ) {
global $wpdb;
$tax_class = self::format_tax_rate_class( $tax_class );
// Get all the rates and locations. Snagging all at once should significantly cut down on the number of queries.
$rates = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}woocommerce_tax_rates` WHERE `tax_rate_class` = %s;", sanitize_title( $tax_class ) ) );
$rates = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}woocommerce_tax_rates` WHERE `tax_rate_class` = %s;", $tax_class ) );
$locations = $wpdb->get_results( "SELECT * FROM `{$wpdb->prefix}woocommerce_tax_rate_locations`" );
if ( ! empty( $rates ) ) {

View File

@ -155,6 +155,12 @@ class WC_Template_Loader {
if ( is_product_taxonomy() ) {
$object = get_queried_object();
$templates[] = 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
$templates[] = WC()->template_path() . 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
$templates[] = 'taxonomy-' . $object->taxonomy . '.php';
$templates[] = WC()->template_path() . 'taxonomy-' . $object->taxonomy . '.php';
if ( is_tax( 'product_cat' ) || is_tax( 'product_tag' ) ) {
$cs_taxonomy = str_replace( '_', '-', $object->taxonomy );
$cs_default = str_replace( '_', '-', $default_file );
@ -163,11 +169,6 @@ class WC_Template_Loader {
$templates[] = 'taxonomy-' . $object->taxonomy . '.php';
$templates[] = WC()->template_path() . 'taxonomy-' . $cs_taxonomy . '.php';
$templates[] = $cs_default;
} else {
$templates[] = 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
$templates[] = WC()->template_path() . 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.php';
$templates[] = 'taxonomy-' . $object->taxonomy . '.php';
$templates[] = WC()->template_path() . 'taxonomy-' . $object->taxonomy . '.php';
}
}

View File

@ -91,6 +91,7 @@ class WC_Validation {
case 'PT':
$valid = (bool) preg_match( '/^([0-9]{4})([-])([0-9]{3})$/', $postcode );
break;
case 'PR':
case 'US':
$valid = (bool) preg_match( '/^([0-9]{5})(-[0-9]{4})?$/i', $postcode );
break;

View File

@ -22,7 +22,7 @@ final class WooCommerce {
*
* @var string
*/
public $version = '4.8.0';
public $version = '4.9.0';
/**
* WooCommerce Schema version.
@ -530,6 +530,9 @@ final class WooCommerce {
case 'twentytwenty':
include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-twenty.php';
break;
case 'twentytwentyone':
include_once WC_ABSPATH . 'includes/theme-support/class-wc-twenty-twenty-one.php';
break;
}
}
}
@ -599,13 +602,7 @@ final class WooCommerce {
* - WP_LANG_DIR/plugins/woocommerce-LOCALE.mo
*/
public function load_plugin_textdomain() {
if ( function_exists( 'determine_locale' ) ) {
$locale = determine_locale();
} else {
// @todo Remove when start supporting WP 5.0 or later.
$locale = is_admin() ? get_user_locale() : get_locale();
}
$locale = determine_locale();
$locale = apply_filters( 'plugin_locale', $locale, 'woocommerce' );
unload_textdomain( 'woocommerce' );

View File

@ -93,14 +93,13 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
/**
* Method to read an order from the database.
*
* @param WC_Data $order Order object.
* @param WC_Order $order Order object.
*
* @throws Exception If passed order is invalid.
*/
public function read( &$order ) {
$order->set_defaults();
$post_object = get_post( $order->get_id() );
if ( ! $order->get_id() || ! $post_object || ! in_array( $post_object->post_type, wc_get_order_types(), true ) ) {
throw new Exception( __( 'Invalid order.', 'woocommerce' ) );
}

View File

@ -64,6 +64,7 @@ class WC_Customer_Data_Store extends WC_Data_Store_WP implements WC_Customer_Dat
'syntax_highlighting',
'_order_count',
'_money_spent',
'_last_order',
'_woocommerce_tracks_anon_id',
);
@ -152,10 +153,11 @@ class WC_Customer_Data_Store extends WC_Data_Store_WP implements WC_Customer_Dat
$customer_id = $customer->get_id();
// Load meta but exclude deprecated props.
// Load meta but exclude deprecated props and parent keys.
$user_meta = array_diff_key(
array_change_key_case( array_map( 'wc_flatten_meta_callback', get_user_meta( $customer_id ) ) ),
array_flip( array( 'country', 'state', 'postcode', 'city', 'address', 'address_2', 'default', 'location' ) )
array_flip( array( 'country', 'state', 'postcode', 'city', 'address', 'address_2', 'default', 'location' ) ),
array_change_key_case( (array) $user_object->data )
);
$customer->set_props( $user_meta );
@ -324,21 +326,30 @@ class WC_Customer_Data_Store extends WC_Data_Store_WP implements WC_Customer_Dat
* @return WC_Order|false
*/
public function get_last_order( &$customer ) {
global $wpdb;
$last_order = $wpdb->get_var(
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
"SELECT posts.ID
FROM $wpdb->posts AS posts
LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id
WHERE meta.meta_key = '_customer_user'
AND meta.meta_value = '" . esc_sql( $customer->get_id() ) . "'
AND posts.post_type = 'shop_order'
AND posts.post_status IN ( '" . implode( "','", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' )
ORDER BY posts.ID DESC"
// phpcs:enable
$last_order = apply_filters(
'woocommerce_customer_get_last_order',
get_user_meta( $customer->get_id(), '_last_order', true ),
$customer
);
if ( '' === $last_order ) {
global $wpdb;
$last_order = $wpdb->get_var(
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
"SELECT posts.ID
FROM $wpdb->posts AS posts
LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id
WHERE meta.meta_key = '_customer_user'
AND meta.meta_value = '" . esc_sql( $customer->get_id() ) . "'
AND posts.post_type = 'shop_order'
AND posts.post_status IN ( '" . implode( "','", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' )
ORDER BY posts.ID DESC"
// phpcs:enable
);
update_user_meta( $customer->get_id(), '_last_order', $last_order );
}
if ( ! $last_order ) {
return false;
}
@ -354,7 +365,11 @@ class WC_Customer_Data_Store extends WC_Data_Store_WP implements WC_Customer_Dat
* @return integer
*/
public function get_order_count( &$customer ) {
$count = get_user_meta( $customer->get_id(), '_order_count', true );
$count = apply_filters(
'woocommerce_customer_get_order_count',
get_user_meta( $customer->get_id(), '_order_count', true ),
$customer
);
if ( '' === $count ) {
global $wpdb;

View File

@ -94,7 +94,20 @@ class WC_Data_Store_WP {
$object->get_id()
)
);
return $this->filter_raw_meta_data( $object, $raw_meta_data );
}
/**
* Helper method to filter internal meta keys from all meta data rows for the object.
*
* @since 4.7.0
*
* @param WC_Data $object WC_Data object.
* @param array $raw_meta_data Array of std object of meta data to be filtered.
*
* @return mixed|void
*/
public function filter_raw_meta_data( &$object, $raw_meta_data ) {
$this->internal_meta_keys = array_merge( array_map( array( $this, 'prefix_key' ), $object->get_data_keys() ), $this->internal_meta_keys );
$meta_data = array_filter( $raw_meta_data, array( $this, 'exclude_internal_meta_keys' ) );
return apply_filters( "woocommerce_data_store_wp_{$this->meta_type}_read_meta", $meta_data, $object, $this );

View File

@ -734,11 +734,12 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
* Get the order type based on Order ID.
*
* @since 3.0.0
* @param int $order_id Order ID.
* @param int|WP_Post $order Order | Order id.
*
* @return string
*/
public function get_order_type( $order_id ) {
return get_post_type( $order_id );
public function get_order_type( $order ) {
return get_post_type( $order );
}
/**
@ -865,7 +866,13 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
$query = new WP_Query( $args );
}
$orders = ( isset( $query_vars['return'] ) && 'ids' === $query_vars['return'] ) ? $query->posts : array_filter( array_map( 'wc_get_order', $query->posts ) );
if ( isset( $query_vars['return'] ) && 'ids' === $query_vars['return'] ) {
$orders = $query->posts;
} else {
update_post_caches( $query->posts ); // We already fetching posts, might as well hydrate some caches.
$order_ids = wp_list_pluck( $query->posts, 'ID' );
$orders = $this->compile_orders( $order_ids, $query_vars, $query );
}
if ( isset( $query_vars['paginate'] ) && $query_vars['paginate'] ) {
return (object) array(
@ -878,6 +885,213 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
return $orders;
}
/**
* Compile order response and set caches as needed for order ids.
*
* @param array $order_ids List of order IDS to compile.
* @param array $query_vars Original query arguments.
* @param WP_Query $query Query object.
*
* @return array Orders.
*/
private function compile_orders( $order_ids, $query_vars, $query ) {
if ( empty( $order_ids ) ) {
return array();
}
$orders = array();
// Lets do some cache hydrations so that we don't have to fetch data from DB for every order.
$this->prime_raw_meta_cache_for_orders( $order_ids, $query_vars );
$this->prime_refund_caches_for_order( $order_ids, $query_vars );
$this->prime_order_item_caches_for_orders( $order_ids, $query_vars );
foreach ( $query->posts as $post ) {
$orders[] = wc_get_order( $post );
}
return $orders;
}
/**
* Prime refund cache for orders.
*
* @param array $order_ids Order Ids to prime cache for.
* @param array $query_vars Query vars for the query.
*/
private function prime_refund_caches_for_order( $order_ids, $query_vars ) {
if ( ! isset( $query_vars['type'] ) || ! ( 'shop_order' === $query_vars['type'] ) ) {
return;
}
if ( isset( $query_vars['fields'] ) && 'all' !== $query_vars['fields'] ) {
if ( is_array( $query_vars['fields'] ) && ! in_array( 'refunds', $query_vars['fields'] ) ) {
return;
}
}
$cache_keys_mapping = array();
foreach ( $order_ids as $order_id ) {
$cache_keys_mapping[ $order_id ] = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'refunds' . $order_id;
}
$non_cached_ids = array();
$cache_values = wc_cache_get_multiple( array_values( $cache_keys_mapping ), 'orders' );
foreach ( $order_ids as $order_id ) {
if ( false === $cache_values[ $cache_keys_mapping[ $order_id ] ] ) {
$non_cached_ids[] = $order_id;
}
}
if ( empty( $non_cached_ids ) ) {
return;
}
$refunds = wc_get_orders(
array(
'type' => 'shop_order_refund',
'post_parent__in' => $non_cached_ids,
'limit' => - 1,
)
);
$order_refunds = array_reduce(
$refunds,
function ( $order_refunds_array, WC_Order_Refund $refund ) {
if ( ! isset( $order_refunds_array[ $refund->get_parent_id() ] ) ) {
$order_refunds_array[ $refund->get_parent_id() ] = array();
}
$order_refunds_array[ $refund->get_parent_id() ][] = $refund;
return $order_refunds_array;
},
array()
);
foreach ( $non_cached_ids as $order_id ) {
$refunds = array();
if ( isset( $order_refunds[ $order_id ] ) ) {
$refunds = $order_refunds[ $order_id ];
}
wp_cache_set( $cache_keys_mapping[ $order_id ], $refunds, 'orders' );
}
}
/**
* Prime following caches:
* 1. item-$order_item_id For individual items.
* 2. order-items-$order-id For fetching items associated with an order.
* 3. order-item meta.
*
* @param array $order_ids Order Ids to prime cache for.
* @param array $query_vars Query vars for the query.
*/
private function prime_order_item_caches_for_orders( $order_ids, $query_vars ) {
global $wpdb;
if ( isset( $query_vars['fields'] ) && 'all' !== $query_vars['fields'] ) {
$line_items = array(
'line_items',
'shipping_lines',
'fee_lines',
'coupon_lines',
);
if ( is_array( $query_vars['fields'] ) && 0 === count( array_intersect( $line_items, $query_vars['fields'] ) ) ) {
return;
}
}
$cache_keys = array_map(
function ( $order_id ) {
return 'order-items-' . $order_id;
},
$order_ids
);
$cache_values = wc_cache_get_multiple( $cache_keys, 'orders' );
$non_cached_ids = array();
foreach ( $order_ids as $order_id ) {
if ( false === $cache_values[ 'order-items-' . $order_id ] ) {
$non_cached_ids[] = $order_id;
}
}
if ( empty( $non_cached_ids ) ) {
return;
}
$non_cached_ids = esc_sql( $non_cached_ids );
$non_cached_ids_string = implode( ',', $non_cached_ids );
$order_items = $wpdb->get_results(
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
"SELECT order_item_type, order_item_id, order_id, order_item_name FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id in ( $non_cached_ids_string ) ORDER BY order_item_id;"
);
if ( empty( $order_items ) ) {
return;
}
$order_items_for_all_orders = array_reduce(
$order_items,
function ( $order_items_collection, $order_item ) {
if ( ! isset( $order_items_collection[ $order_item->order_id ] ) ) {
$order_items_collection[ $order_item->order_id ] = array();
}
$order_items_collection[ $order_item->order_id ][] = $order_item;
return $order_items_collection;
}
);
foreach ( $order_items_for_all_orders as $order_id => $items ) {
wp_cache_set( 'order-items-' . $order_id, $items, 'orders' );
}
foreach ( $order_items as $item ) {
wp_cache_set( 'item-' . $item->order_item_id, $item, 'order-items' );
}
$order_item_ids = wp_list_pluck( $order_items, 'order_item_id' );
update_meta_cache( 'order_item', $order_item_ids );
}
/**
* Prime cache for raw meta data for orders in bulk. Difference between this and WP built-in metadata is that this method also fetches `meta_id` field which we use and cache it.
*
* @param array $order_ids Order Ids to prime cache for.
* @param array $query_vars Query vars for the query.
*/
private function prime_raw_meta_cache_for_orders( $order_ids, $query_vars ) {
global $wpdb;
if ( isset( $query_vars['fields'] ) && 'all' !== $query_vars['fields'] ) {
if ( is_array( $query_vars['fields'] ) && ! in_array( 'meta_data', $query_vars['fields'] ) ) {
return;
}
}
$cache_keys_mapping = array();
foreach ( $order_ids as $order_id ) {
$cache_keys_mapping[ $order_id ] = WC_Order::generate_meta_cache_key( $order_id, 'orders' );
}
$cache_values = wc_cache_get_multiple( array_values( $cache_keys_mapping ), 'orders' );
$non_cached_ids = array();
foreach ( $order_ids as $order_id ) {
if ( false === $cache_values[ $cache_keys_mapping[ $order_id ] ] ) {
$non_cached_ids[] = $order_id;
}
}
if ( empty( $non_cached_ids ) ) {
return;
}
$order_ids = esc_sql( $non_cached_ids );
$order_ids_in = "'" . implode( "', '", $order_ids ) . "'";
$raw_meta_data_array = $wpdb->get_results(
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
"SELECT post_id as object_id, meta_id, meta_key, meta_value
FROM {$wpdb->postmeta}
WHERE post_id IN ( $order_ids_in )
ORDER BY post_id"
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
);
$raw_meta_data_collection = array_reduce(
$raw_meta_data_array,
function ( $collection, $raw_meta_data ) {
if ( ! isset( $collection[ $raw_meta_data->object_id ] ) ) {
$collection[ $raw_meta_data->object_id ] = array();
}
$collection[ $raw_meta_data->object_id ][] = $raw_meta_data;
return $collection;
},
array()
);
WC_Order::prime_raw_meta_data_cache( $raw_meta_data_collection, 'orders' );
}
/**
* Return the order type of a given item which belongs to WC_Order.
*

View File

@ -47,12 +47,15 @@ class WC_Order_Refund_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT im
*/
public function delete( &$order, $args = array() ) {
$id = $order->get_id();
$parent_order_id = $order->get_parent_id();
$refund_cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'refunds' . $parent_order_id;
if ( ! $id ) {
return;
}
wp_delete_post( $id );
wp_cache_delete( $refund_cache_key, 'orders' );
$order->set_id( 0 );
do_action( 'woocommerce_delete_order_refund', $id );
}

View File

@ -569,6 +569,28 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
case 'date_on_sale_to':
$value = $value ? $value->getTimestamp() : '';
break;
case 'stock_quantity':
// Fire actions to let 3rd parties know the stock is about to be changed.
if ( $product->is_type( 'variation' ) ) {
/**
* Action to signal that the value of 'stock_quantity' for a variation is about to change.
*
* @since 4.9
*
* @param int $product The variation whose stock is about to change.
*/
do_action( 'woocommerce_variation_before_set_stock', $product );
} else {
/**
* Action to signal that the value of 'stock_quantity' for a product is about to change.
*
* @since 4.9
*
* @param int $product The product whose stock is about to change.
*/
do_action( 'woocommerce_product_before_set_stock', $product );
}
break;
}
$updated = $this->update_or_delete_post_meta( $product, $meta_key, $value );
@ -1614,7 +1636,7 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
// Variations should also search the parent's meta table for fallback fields.
if ( $include_variations ) {
$variation_query = $wpdb->prepare( ' OR ( wc_product_meta_lookup.sku = "" AND parent_wc_product_meta_lookup.sku LIKE %s ) ', $like );
$variation_query = $wpdb->prepare( " OR ( wc_product_meta_lookup.sku = '' AND parent_wc_product_meta_lookup.sku LIKE %s ) ", $like );
} else {
$variation_query = '';
}

View File

@ -1048,15 +1048,18 @@ class WC_Email extends WC_Settings_API {
var view = '" . esc_js( __( 'View template', 'woocommerce' ) ) . "';
var hide = '" . esc_js( __( 'Hide template', 'woocommerce' ) ) . "';
jQuery( 'a.toggle_editor' ).text( view ).toggle( function() {
jQuery( this ).text( hide ).closest(' .template' ).find( '.editor' ).slideToggle();
return false;
}, function() {
jQuery( this ).text( view ).closest( '.template' ).find( '.editor' ).slideToggle();
jQuery( 'a.toggle_editor' ).text( view ).on( 'click', function() {
var label = hide;
if ( jQuery( this ).closest(' .template' ).find( '.editor' ).is(':visible') ) {
var label = view;
}
jQuery( this ).text( label ).closest(' .template' ).find( '.editor' ).slideToggle();
return false;
} );
jQuery( 'a.delete_template' ).click( function() {
jQuery( 'a.delete_template' ).on( 'click', function() {
if ( window.confirm('" . esc_js( __( 'Are you sure you want to delete this template file?', 'woocommerce' ) ) . "') ) {
return true;
}

View File

@ -127,7 +127,6 @@ class WC_Gateway_Paypal_Request {
'upload' => 1,
'return' => esc_url_raw( add_query_arg( 'utm_nooverride', '1', $this->gateway->get_return_url( $order ) ) ),
'cancel_return' => esc_url_raw( $order->get_cancel_order_url_raw() ),
'page_style' => $this->gateway->get_option( 'page_style' ),
'image_url' => esc_url_raw( $this->gateway->get_option( 'image_url' ) ),
'paymentaction' => $this->gateway->get_option( 'paymentaction' ),
'invoice' => $this->limit_length( $this->gateway->get_option( 'invoice_prefix' ) . $order->get_order_number(), 127 ),

View File

@ -113,14 +113,6 @@ return array(
'authorization' => __( 'Authorize', 'woocommerce' ),
),
),
'page_style' => array(
'title' => __( 'Page style', 'woocommerce' ),
'type' => 'text',
'description' => __( 'Optionally enter the name of the page style you wish to use. These are defined within your PayPal account. This affects classic PayPal checkout screens.', 'woocommerce' ),
'default' => '',
'desc_tip' => true,
'placeholder' => __( 'Optional', 'woocommerce' ),
),
'image_url' => array(
'title' => __( 'Image url', 'woocommerce' ),
'type' => 'text',

View File

@ -126,7 +126,7 @@ class WC_Action_Queue implements WC_Queue_Interface {
$next_timestamp = as_next_scheduled_action( $hook, $args, $group );
if ( $next_timestamp ) {
if ( is_numeric( $next_timestamp ) ) {
return new WC_DateTime( "@{$next_timestamp}", new DateTimeZone( 'UTC' ) );
}

View File

@ -1041,6 +1041,12 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller {
$override_files = array();
$outdated_templates = false;
$scan_files = WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' );
// Include *-product_<cat|tag> templates for backwards compatibility.
$scan_files[] = 'content-product_cat.php';
$scan_files[] = 'taxonomy-product_cat.php';
$scan_files[] = 'taxonomy-product_tag.php';
foreach ( $scan_files as $file ) {
$located = apply_filters( 'wc_get_template', $file, $file, array(), WC()->template_path(), WC()->plugin_path() . '/templates/' );
@ -1059,7 +1065,14 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller {
}
if ( ! empty( $theme_file ) ) {
$core_version = WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $file );
$core_file = $file;
// Update *-product_<cat|tag> template name before searching in core.
if ( false !== strpos( $core_file, '-product_cat' ) || false !== strpos( $core_file, '-product_tag' ) ) {
$core_file = str_replace( '_', '-', $core_file );
}
$core_version = WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $core_file );
$theme_version = WC_Admin_Status::get_file_version( $theme_file );
if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) {
if ( ! $outdated_templates ) {

View File

@ -283,6 +283,7 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller {
$args['post_parent__in'] = $request['parent'];
$args['post_parent__not_in'] = $request['parent_exclude'];
$args['s'] = $request['search'];
$args['fields'] = $this->get_fields_for_response( $request );
if ( 'date' === $args['orderby'] ) {
$args['orderby'] = 'date ID';

View File

@ -293,7 +293,7 @@ class WC_Shortcode_My_Account {
$errors = new WP_Error();
do_action( 'lostpassword_post', $errors );
do_action( 'lostpassword_post', $errors, $user_data );
if ( $errors->get_error_code() ) {
wc_add_notice( $errors->get_error_message(), 'error' );

View File

@ -0,0 +1,105 @@
<?php
/**
* Twenty Twenty One support.
*
* @since 4.7.0
* @package WooCommerce\Classes
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
* WC_Twenty_Twenty_One class.
*/
class WC_Twenty_Twenty_One {
/**
* 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' ) );
// Enqueue wp-admin compatibility styles.
add_action( 'admin_enqueue_scripts', array( __CLASS__ , 'enqueue_admin_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,
)
);
}
/**
* Open the Twenty Twenty One 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 One wrapper.
*/
public static function output_content_wrapper_end() {
echo '</main>';
echo '</section>';
}
/**
* 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-one.css',
'deps' => '',
'version' => Constants::get_constant( 'WC_VERSION' ),
'media' => 'all',
'has_rtl' => true,
);
return apply_filters( 'woocommerce_twenty_twenty_one_styles', $styles );
}
/**
* Enqueue the wp-admin CSS overrides for this theme.
*/
public static function enqueue_admin_styles() {
wp_enqueue_style(
'woocommerce-twenty-twenty-one-admin',
str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/css/twenty-twenty-one-admin.css',
'',
Constants::get_constant( 'WC_VERSION' ),
'all'
);
}
}
WC_Twenty_Twenty_One::init();

View File

@ -131,7 +131,7 @@ class WC_Products_Tracking {
var initialStockValue = $( '#_stock' ).val();
var hasRecordedEvent = false;
$( '#publish' ).click( function() {
$( '#publish' ).on( 'click', function() {
if ( hasRecordedEvent ) {
return;
}

View File

@ -37,7 +37,7 @@ class WC_Status_Tracking {
if ( 'status' === $tab ) {
wc_enqueue_js(
"
$( 'a.debug-report' ).click( function() {
$( 'a.debug-report' ).on( 'click', function() {
window.wcTracks.recordEvent( 'status_view_reports' );
} );
"

View File

@ -2336,6 +2336,7 @@ function wc_is_active_theme( $theme ) {
function wc_is_wp_default_theme_active() {
return wc_is_active_theme(
array(
'twentytwentyone',
'twentytwenty',
'twentynineteen',
'twentyseventeen',
@ -2501,3 +2502,23 @@ function wc_is_running_from_async_action_scheduler() {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
return isset( $_REQUEST['action'] ) && 'as_async_request_queue_runner' === $_REQUEST['action'];
}
/**
* Polyfill for wp_cache_get_multiple for WP versions before 5.5.
*
* @param array $keys Array of keys to get from group.
* @param string $group Optional. Where the cache contents are grouped. Default empty.
* @param bool $force Optional. Whether to force an update of the local cache from the persistent
* cache. Default false.
* @return array|bool Array of values.
*/
function wc_cache_get_multiple( $keys, $group = '', $force = false ) {
if ( function_exists( 'wp_cache_get_multiple' ) ) {
return wp_cache_get_multiple( $keys, $group, $force );
}
$values = array();
foreach ( $keys as $key ) {
$values[ $key ] = wp_cache_get( $key, $group, $force );
}
return $values;
}

View File

@ -638,7 +638,12 @@ function wc_let_to_num( $size ) {
* @return string
*/
function wc_date_format() {
return apply_filters( 'woocommerce_date_format', get_option( 'date_format' ) );
$date_format = get_option( 'date_format' );
if ( empty( $date_format ) ) {
// Return default date format if the option is empty.
$date_format = 'F j, Y';
}
return apply_filters( 'woocommerce_date_format', $date_format );
}
/**
@ -647,7 +652,12 @@ function wc_date_format() {
* @return string
*/
function wc_time_format() {
return apply_filters( 'woocommerce_time_format', get_option( 'time_format' ) );
$time_format = get_option( 'time_format' );
if ( empty( $time_format ) ) {
// Return default time format if the option is empty.
$time_format = 'g:i a';
}
return apply_filters( 'woocommerce_time_format', $time_format );
}
/**
@ -952,6 +962,7 @@ function wc_format_postcode( $postcode, $country ) {
case 'PT':
$postcode = substr_replace( $postcode, '-', 4, 0 );
break;
case 'PR':
case 'US':
$postcode = rtrim( substr_replace( $postcode, '-', 5, 0 ), '-' );
break;
@ -1190,7 +1201,7 @@ function wc_format_stock_for_display( $product ) {
switch ( get_option( 'woocommerce_stock_format' ) ) {
case 'low_amount':
if ( $stock_amount <= get_option( 'woocommerce_notify_low_stock_amount' ) ) {
if ( $stock_amount <= wc_get_low_stock_amount( $product ) ) {
/* translators: %s: stock amount */
$display = sprintf( __( 'Only %s left in stock', 'woocommerce' ), wc_format_stock_quantity_for_display( $stock_amount, $product ) );
}

View File

@ -71,7 +71,7 @@ function wc_get_orders( $args ) {
*
* @since 2.2
*
* @param mixed $the_order Post object or post ID of the order.
* @param mixed $the_order Post object or post ID of the order.
*
* @return bool|WC_Order|WC_Order_Refund
*/
@ -456,11 +456,12 @@ function wc_delete_shop_order_transients( $order = 0 ) {
delete_transient( $transient );
}
// Clear money spent for user associated with order.
// Clear customer's order related caches.
if ( is_a( $order, 'WC_Order' ) ) {
$order_id = $order->get_id();
delete_user_meta( $order->get_customer_id(), '_money_spent' );
delete_user_meta( $order->get_customer_id(), '_order_count' );
delete_user_meta( $order->get_customer_id(), '_last_order' );
} else {
$order_id = 0;
}

View File

@ -38,6 +38,13 @@ function wc_update_product_stock( $product, $stock_quantity = null, $operation =
$product_with_stock = $product_id_with_stock !== $product->get_id() ? wc_get_product( $product_id_with_stock ) : $product;
$data_store = WC_Data_Store::load( 'product' );
// Fire actions to let 3rd parties know the stock is about to be changed.
if ( $product_with_stock->is_type( 'variation' ) ) {
do_action( 'woocommerce_variation_before_set_stock', $product_with_stock );
} else {
do_action( 'woocommerce_product_before_set_stock', $product_with_stock );
}
// Update the database.
$new_stock = $data_store->update_product_stock( $product_id_with_stock, $stock_quantity, $operation );

View File

@ -2748,7 +2748,7 @@ if ( ! function_exists( 'woocommerce_form_field' ) ) {
} else {
$field = '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" class="country_to_state country_select ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" ' . implode( ' ', $custom_attributes ) . '><option value="default">' . esc_html__( 'Select a country / region&hellip;', 'woocommerce' ) . '</option>';
$field = '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $args['id'] ) . '" class="country_to_state country_select ' . esc_attr( implode( ' ', $args['input_class'] ) ) . '" ' . implode( ' ', $custom_attributes ) . ' data-placeholder="' . esc_attr( $args['placeholder'] ? $args['placeholder'] : esc_attr__( 'Select a country / region&hellip;', 'woocommerce' ) ) . '"><option value="">' . esc_html__( 'Select a country / region&hellip;', 'woocommerce' ) . '</option>';
foreach ( $countries as $ckey => $cvalue ) {
$field .= '<option value="' . esc_attr( $ckey ) . '" ' . selected( $value, $ckey, false ) . '>' . esc_html( $cvalue ) . '</option>';

View File

@ -701,6 +701,7 @@ function wc_update_230_options() {
// _money_spent and _order_count may be out of sync - clear them
delete_metadata( 'user', 0, '_money_spent', '', true );
delete_metadata( 'user', 0, '_order_count', '', true );
delete_metadata( 'user', 0, '_last_order', '', true );
// To prevent taxes being hidden when using a default 'no address' in a store with tax inc prices, set the woocommerce_default_customer_address to use the store base address by default.
if ( '' === get_option( 'woocommerce_default_customer_address', false ) && wc_prices_include_tax() ) {

View File

@ -272,6 +272,7 @@ function wc_update_new_customer_past_orders( $customer_id ) {
update_user_meta( $customer_id, 'paying_customer', 1 );
update_user_meta( $customer_id, '_order_count', '' );
update_user_meta( $customer_id, '_money_spent', '' );
delete_user_meta( $customer_id, '_last_order' );
}
return $linked;
@ -897,7 +898,7 @@ function wc_update_user_last_active( $user_id ) {
if ( ! $user_id ) {
return;
}
update_user_meta( $user_id, 'wc_last_active', (string) strtotime( date( 'Y-m-d', time() ) ) );
update_user_meta( $user_id, 'wc_last_active', (string) strtotime( gmdate( 'Y-m-d', time() ) ) );
}
/**

31
lib/README.md Normal file
View File

@ -0,0 +1,31 @@
## WooCommerce Lib Directory
This directory contains a dummy package responsible for managing WooCommerce dependencies that require conflict avoidance.
The contents of the `packages` and `classes` directories get automatically generated by `composer install` and `composer update`.
This allows us to prefix namespaces and classmap classes to avoid conflicts with plugins that include the same package.
All namespaces are prefixed with `Automattic\WooCommerce\Vendor` and classmap classes prefixed with `WC_Vendor_`.
**_Do not_ make direct changes in the files contained in `packages` or `classes`! Any changes will be lost!**
### Adding Packages
In order to avoid including the original dependencies in the root autoloader we must utilize `require-dev` for them.
Composer treats `require` dependencies as transitive while `require-dev` dependencies get ignored by consumers.
1. Add package to `require-dev` section of `composer.json`
2. Add package slug to `extra/mozart/packages` section of `composer.json`
3. Run `composer run-script build-lib` from the root directory (You should now see the package in `packages/VendorName/PackageName` or `classes`)
### Updating Packages
Updating a package is as easy as changing the version in `composer.json` and then running `composer run-script build-lib` from the root directory.
### Ignoring Packages
If you would like to add a package which does not undergo conflict avoidance you must take steps to ensure it appears in
the root autoloader.
1. Add package to the `require` section of both the `lib/composer.json` and root `composer.json` file instead of `require-dev`
2. Add package slug to `extra/mozart/excluded-packages` section of `composer.json`
3. Run `composer run-script build-lib` from the root directory (You **should not** see the package in `packages/VendorName/PackageName` or `classes`)

41
lib/composer.json Normal file
View File

@ -0,0 +1,41 @@
{
"name": "woocommerce/woocommerce-lib",
"description": "A package for hiding re-namespaced dependencies and executing them",
"prefer-stable": true,
"minimum-stability": "dev",
"require": {
"php": ">=7.0",
"psr/container": "^1.0"
},
"require-dev": {
"league/container": "3.3.3"
},
"config": {
"platform": {
"php": "7.0"
}
},
"scripts": {
"post-install-cmd": [
"\"../vendor/bin/mozart\" compose"
],
"post-update-cmd": [
"\"../vendor/bin/mozart\" compose"
]
},
"extra": {
"mozart": {
"dep_namespace": "Automattic\\WooCommerce\\Vendor\\",
"dep_directory": "/packages/",
"packages": [
"league/container"
],
"excluded_packages": [
"psr/container"
],
"classmap_directory": "/classes/",
"classmap_prefix": "WC_Vendor_",
"delete_vendor_directories": true
}
}
}

Some files were not shown because too many files have changed in this diff Show More