Merge branch 'master' into privacy-policy-update

This commit is contained in:
Garrett Hyder 2020-04-01 16:37:41 -07:00 committed by GitHub
commit 99279211c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
160 changed files with 6632 additions and 6000 deletions

View File

@ -38,7 +38,7 @@ matrix:
- name: "E2E tests"
php: 7.4
script:
- npm install
- composer require wp-cli/i18n-command
- npm run build
- docker-compose up --build -d
- bash tests/bin/run-e2e-CI.sh
@ -50,6 +50,9 @@ matrix:
- name: "WooCommerce unit tests using WordPress nightly"
php: 7.4
env: WP_VERSION=nightly WP_MULTISITE=0
- name: "Minimum requirements"
php: 5.6
env: WP_VERSION=5.0 WP_MULTISITE=0
allow_failures:
- php: 7.4
env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1
@ -63,6 +66,8 @@ before_script:
else
echo "xdebug.ini does not exist"
fi
- nvm install 10
- npm install
- composer install --no-dev
- |
# Install WP Test suite, install PHPUnit globally:

View File

@ -1,5 +1,96 @@
== Changelog ==
= 4.0.0 - 2020-03-10 =
* Enhancement - Included information about packages in the System Status Report. #25584
* Enhancement - New WooCommerce Admin. #25011
* Enhancement - Update dependency woocommerce/woocommerce-blocks to v2.5.12 #25587
* Enhancement - Updated Action Scheduler to 3.0.1. #25566
* Enhancement - Update dependency woocommerce/woocommerce-admin to v0.25.1. #25620
* Enhancement - Update dependency woocommerce/woocommerce-blocks to v2.5.13. #25696
* Enhancement - Added the WC Admin enabled db update notice. #25736
* Enhancement - Update Action Scheduler to version 3.1.1. #25745
* Enhancement - Update dependency woocommerce/woocommerce-blocks to v2.5.14. #25807
* Enhancement - Update dependency woocommerce/woocommerce-admin to v1.0. #25822
* Enhancement - Update dependency woocommerce/action-scheduler to v3.1.2. #25859
* Performance - Improved the client-side preparation for variation saving. #25382
* Tweak - Enhance order details and payment summary. #25504
* Tweak - Increase new onboarding group test to 50%. #25501
* Tweak - Increased range and precision for `min_price` and `max_price` in the product meta lookup table. #25253
* Tweak - Move action scheduler to external via composer. #25404
* Tweak - Only update the customer IP address when order gets created from admin. #25137
* Tweak - Remove WooCommerce Admin install alert. #25502
* Tweak - Removed WC Admin from the Setup Wizard if it's already active. #25562
* Tweak - Set email header table width to 100% for full width. #25294
* Tweak - Simplified MaxMind integration title. #25522
* Tweak - Update 'Country' to 'Country / Region' label. #25530
* Tweak - WooCommerce.com plugins auto-install and update improvement. #25532
* Fix - Add missing closing tag. #25319
* Fix - Added validation to the cost field for flat rate shipping. #24919
* Fix - Address in shipping calculator malformed for Canada. #25149
* Fix - Adjusted package shipping rates to only be visible when a full address is entered. #25128
* Fix - Check for WooCommerce Admin feature plugin class before adding install notice. #25395
* Fix - Corrected the performance issues caused by the Cash-On-Delivery plugin's initialization process. #25512
* Fix - Duplicate webhook deliveries. #25183
* Fix - Fix fatal error that would occur when calling the WC_Payment_Gateways::set_current_gateway() function and there is no WC session. #25322
* Fix - Fixed adding multiple items to cart from any product listing page. #24818
* Fix - Fixed get_discount function return type. #25567
* Fix - Fixed possible multiple is_vat_exempt order meta in order creation. #25426
* Fix - Fixed wrong context help for translators. #25496
* Fix - Make `WC_Shipping::is` package shippable less strict. #25386
* Fix - Prevent undefined `wp_delete_user()` error while removing inactive accounts. #25489
* Fix - Removed constants and autoloader from the uninstall script. #25589
* Fix - Removed the lowercase conversion for product search terms that caused incorrect results to case sensitive searches. #25314
* Fix - Restored the default behavior of "Shipping destination" option. #25571
* Fix - Set image CSS on emails to be `max-width: 100%` so that they don't break the email template. #24764
* Fix - Setup wizard shipping setup verification logic correction. #25540
* Fix - Fixed typo in label. #25645
* Fix - Added the missing "bestRating" and "worstRating" params to structured schema data. #25667
* Fix - Replaced deprecated Jetpack::is_staging_site call. #25670
* Fix - Avoid `Automattic\Jetpack\Constants` in main woocommerce class. #25697
* Fix - Change the namespace of the WC Admin Package class and update WC Admin package. #25701
* Fix - Unmark completed AS migration during the update to make sure AS migration happens. #25707
* Fix - configure Jetpack plugin before trying to connect/register. #25742
* Fix - Check configure exists before calling to support older JP versions. #25747
* Fix - Prevent edited attribute notice being hidden by new dashboard. #25757
* Fix - Corrected the cache invalidation behavior of order item CRUD actions. #25734
* Fix - Don't show duplicated update notifications on Woo Screens. #25828
* Fix - Escape MaxMind database URL. #25682
* Fix - System status report should correctly identify inactive package. #25830
* Dev - Added support for placeholder attribute in quantity inputs. #25418
* Dev - Added `tax_status` and `tax_class` columns to the product meta data lookup table. #25428
* Dev - Introduced `woocommerce_top_rated_widget_args` filter. #25320
* Dev - Introduced `woocommerce_admin_process_variation_object` hook. #24929
* Dev - Added actions before and after grouped product list to allow adding custom rows. #25093
* Dev - Added filter to tweak whether a product has enough stock while attempting to pay for an order. #25230
* Dev - Added the `automattic/jetpack-constants` package and replace PHP constant definition checks with it. #25516
* Dev - Added a `triggerHandler` called `checkout_place_order_success` on a successful order during the checkout process. #25289
* Dev - Allow filtering of default meta value inside `WC_Data::get_meta` even if meta key not found. #24066
* Dev - Includes Emogrifier composer package instead of including into `includes/libraries`. #25525
* Dev - Introduce `WC_Countries::get_vat_countries` for returning a list of countries that uses VAT and refactor `WC_Countries::get_european_union_countries` with backward compatibility and deprecation to remove the VAT functionality from there. Brexit, remove GB from `WC_Countries::get_european_union_countries`. #24943
* Dev - Introduced `woocommerce_download_product_filepath` filter. #25485
* Dev - Introduced `woocommerce_email_content_type` filter. #25405
* Dev - Updated `woocommerce_email_from_name` and `woocommerce_email_from_address` filter arguments to include `wp_email()` default data. #25405
* Dev - Introduced `woocommerce_shortcode_products_query_results` filter. #25573
* Dev - Removed `hash_equals()` polyfill as it was no longer needed. #25474
* Dev - Removed unused `.order-actions` CSS. #25581
* Dev - Applies woocommerce_maxmind_geolocation_database_path in MaxMind database migration. #25681
* Dev - Support both .data() and .dataset for formdata in add to cart requests. #25726
= 3.9.3 - 2020-02-27 =
* Fix - Replaced deprecated Jetpack::is_staging_site call. #25670
* Fix - Corrected the cache invalidation behavior of order item CRUD actions. #25734
* Fix - Configure Jetpack plugin before trying to connect/register. #25742
* Fix - Check configure exists before calling to support older JP versions. #25747
* Fix - Better handling of coupon code when rendering.
* Dev - Updated WooCommerce blocks to 2.5.14 (See changelog at https://github.com/woocommerce/woocommerce-gutenberg-products-block/releases).
= 3.9.2 - 2020-02-13 =
* Security - Show a notice when a logged-in customer pays for a guest order.
* Security - Disallow links in coupon error messages.
* Fix - Restored the default behavior of the "Shipping destination" option. #25571
= 3.9.1 - 2020-01-28 =
* Tweak - Trim whitespaces and strip slashes from MaxMind License Key.

View File

@ -1 +1 @@
FROM wordpress:5.3
FROM wordpress:5.3.2

View File

@ -201,62 +201,6 @@ module.exports = function( grunt ) {
}
},
// Generate POT files.
makepot: {
options: {
type: 'wp-plugin',
domainPath: 'i18n/languages',
potHeaders: {
'report-msgid-bugs-to': 'https://github.com/woocommerce/woocommerce/issues',
'language-team': 'LANGUAGE <EMAIL@ADDRESS>'
}
},
dist: {
options: {
potFilename: 'woocommerce.pot',
exclude: [
'vendor/.*',
'tests/.*',
'tmp/.*'
]
}
}
},
// Check textdomain errors.
checktextdomain: {
options:{
text_domain: 'woocommerce',
keywords: [
'__:1,2d',
'_e:1,2d',
'_x:1,2c,3d',
'esc_html__:1,2d',
'esc_html_e:1,2d',
'esc_html_x:1,2c,3d',
'esc_attr__:1,2d',
'esc_attr_e:1,2d',
'esc_attr_x:1,2c,3d',
'_ex:1,2c,3d',
'_n:1,2,4d',
'_nx:1,2,4c,5d',
'_n_noop:1,2,3d',
'_nx_noop:1,2,3c,4d'
]
},
files: {
src: [
'**/*.php', // Include all files
'!node_modules/**', // Exclude node_modules/
'!tests/**', // Exclude tests/
'!vendor/**', // Exclude vendor/
'!tmp/**', // Exclude tmp/
'!packages/*/vendor/**' // Exclude packages/*/vendor
],
expand: true
}
},
// Exec shell commands.
shell: {
options: {
@ -306,6 +250,7 @@ module.exports = function( grunt ) {
}
}
},
// PHP Code Sniffer.
phpcs: {
options: {
@ -346,8 +291,6 @@ module.exports = function( grunt ) {
grunt.loadNpmTasks( 'grunt-rtlcss' );
grunt.loadNpmTasks( 'grunt-postcss' );
grunt.loadNpmTasks( 'grunt-stylelint' );
grunt.loadNpmTasks( 'grunt-wp-i18n' );
grunt.loadNpmTasks( 'grunt-checktextdomain' );
grunt.loadNpmTasks( 'grunt-contrib-jshint' );
grunt.loadNpmTasks( 'grunt-contrib-uglify' );
grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
@ -360,8 +303,7 @@ module.exports = function( grunt ) {
// Register tasks.
grunt.registerTask( 'default', [
'js',
'css',
'i18n'
'css'
]);
grunt.registerTask( 'js', [
@ -400,11 +342,6 @@ module.exports = function( grunt ) {
'default'
]);
grunt.registerTask( 'i18n', [
'checktextdomain',
'makepot'
]);
grunt.registerTask( 'e2e-tests', [
'shell:e2e_tests'
]);

View File

@ -1135,14 +1135,6 @@ p.demo_store,
.button {
white-space: nowrap;
}
.order-actions {
text-align: right;
.button {
margin: 0.125em 0 0.125em 0.25em;
}
}
}
table.woocommerce-MyAccount-downloads {

View File

@ -71,6 +71,13 @@ jQuery( function( $ ) {
var data = {};
// Fetch changes that are directly added by calling $thisbutton.data( key, value )
$.each( $thisbutton.data(), function( key, value ) {
data[ key ] = value;
});
// Fetch data attributes in $thisbutton. Give preference to data-attributes because they can be directly modified by javascript
// while `.data` are jquery specific memory stores.
$.each( $thisbutton[0].dataset, function( key, value ) {
data[ key ] = value;
});

View File

@ -50,7 +50,7 @@ jQuery( function( $ ) {
this.$checkout_form.on( 'change', '#ship-to-different-address input', this.ship_to_different_address );
// Trigger events
this.init_ship_to_different_address();
this.$checkout_form.find( '#ship-to-different-address input' ).change();
this.init_payment_methods();
// Update on page load
@ -135,10 +135,7 @@ jQuery( function( $ ) {
}
},
init_checkout: function() {
// Fire updated_checkout event after existing ready event handlers.
$( function() {
$( document.body ).trigger( 'updated_checkout' );
} );
$( document.body ).trigger( 'update_checkout' );
},
maybe_input_changed: function( e ) {
if ( wc_checkout_form.dirtyInput ) {
@ -183,31 +180,10 @@ jQuery( function( $ ) {
wc_checkout_form.trigger_update_checkout();
}
},
init_ship_to_different_address: function() {
var $checkbox = $( '#ship-to-different-address input' );
if ( ! $checkbox.prop( 'checked' ) ) {
var $billing = $( 'div.woocommerce-billing-fields' );
// Find shipping field values that diverge from billing.
var $differentFields = $( 'div.shipping_address' ).find( 'input, select' ).filter( function() {
$( this ).attr( 'id' ).replace( 'shipping', 'billing' );
var id = $( this ).attr( 'id' ).replace( 'shipping', 'billing' );
return $( this ).val() !== $billing.find( '#' + id ).val();
} );
if ( $differentFields.length > 0 ) {
$checkbox.prop( 'checked', true );
}
}
$( 'div.shipping_address' ).toggle( $checkbox.prop( 'checked' ) );
},
ship_to_different_address: function() {
$( 'div.shipping_address' ).hide();
if ( $( this ).is( ':checked' ) ) {
$( 'div.shipping_address' ).slideDown();
} else {
$( 'div.shipping_address' ).slideUp();
}
},
reset_update_checkout_timer: function() {

View File

@ -0,0 +1,25 @@
const wpTextdomain = require( 'wp-textdomain' );
wpTextdomain( 'packages/**/*.php', {
domain: 'woocommerce',
fix: true,
missingDomain: true,
variableDomain: true,
keywords: [
'__:1,2d',
'_e:1,2d',
'_x:1,2c,3d',
'esc_html__:1,2d',
'esc_html_e:1,2d',
'esc_html_x:1,2c,3d',
'esc_attr__:1,2d',
'esc_attr_e:1,2d',
'esc_attr_x:1,2c,3d',
'_ex:1,2c,3d',
'_n:1,2,4d',
'_nx:1,2,4c,5d',
'_n_noop:1,2,3d',
'_nx_noop:1,2,3c,4d',
'wp_set_script_translations:1,2d,3'
],
} );

View File

@ -26,11 +26,15 @@ composer dump-autoload
output 2 "Done"
# Convert textdomains
output 3 "Updating package textdomains..."
output 3 "Updating package PHP textdomains..."
# Replace text domains within packages with woocommerce
find ./packages/woocommerce-blocks \( -iname '*.php' -o -iname '*.js' \) -exec sed -i.bak -e "s/'woo-gutenberg-products-block'/'woocommerce'/g" -e "s/\"woo-gutenberg-products-block\"/'woocommerce'/g" {} \;
find ./packages/woocommerce-rest-api -iname '*.php' -exec sed -i.bak -e "s/, 'woocommerce-rest-api'/, 'woocommerce'/g" {} \;
npm run packages:fix:textdomain
output 2 "Done!"
output 3 "Updating package JS textdomains..."
find ./packages/woocommerce-blocks -iname '*.js' -exec sed -i.bak -e "s/'woo-gutenberg-products-block'/'woocommerce'/g" -e "s/\"woo-gutenberg-products-block\"/'woocommerce'/g" {} \;
find ./packages/woocommerce-admin -iname '*.js' -exec sed -i.bak -e "s/, 'woocommerce-admin'/, 'woocommerce'/g" {} \;
# Cleanup backup files
find ./packages -name "*.bak" -type f -delete

View File

@ -9,15 +9,19 @@
"require": {
"php": ">=5.6|>=7.0",
"automattic/jetpack-autoloader": "^1.2.0",
"automattic/jetpack-constants": "^1.1",
"composer/installers": "1.7.0",
"maxmind-db/reader": "1.6.0",
"woocommerce/action-scheduler": "2.2.5",
"woocommerce/woocommerce-blocks": "2.5.11",
"woocommerce/woocommerce-rest-api": "1.0.7"
"pelago/emogrifier": "^3.1",
"woocommerce/action-scheduler": "3.1.4",
"woocommerce/woocommerce-blocks": "2.5.14",
"woocommerce/woocommerce-rest-api": "1.0.7",
"woocommerce/woocommerce-admin": "1.0.3"
},
"require-dev": {
"phpunit/phpunit": "7.5.20",
"woocommerce/woocommerce-sniffs": "0.0.9"
"woocommerce/woocommerce-sniffs": "0.0.9",
"wp-cli/i18n-command": "^2.2"
},
"config": {
"platform": {
@ -57,18 +61,27 @@
],
"phpcbf": [
"phpcbf -p"
],
"makepot-audit": [
"wp i18n make-pot . --exclude=\".github,.wordpress-org,bin,sample-data,node_modules,tests\" --slug=woocommerce"
],
"makepot": [
"@makepot-audit --skip-audit"
]
},
"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-blocks": ["woocommerce/woocommerce-blocks"],
"packages/woocommerce-admin": ["woocommerce/woocommerce-admin"]
},
"scripts-description": {
"test": "Run unit tests",
"phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer",
"phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier"
"phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier",
"makepot-audit": "Generate i18n/langauges/woocommerce.pot file and run audit",
"makepot": "Generate i18n/langauges/woocommerce.pot file"
}
}
}

802
composer.lock generated
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": "d2f5085db8a002bfb5349dca8dc82878",
"content-hash": "38f346b36bf1a98514e0492ef807de15",
"packages": [
{
"name": "automattic/jetpack-autoloader",
@ -42,6 +42,36 @@
"description": "Creates a custom autoloader for a plugin or theme.",
"time": "2019-09-24T06:39:29+00:00"
},
{
"name": "automattic/jetpack-constants",
"version": "v1.1.3",
"source": {
"type": "git",
"url": "https://github.com/Automattic/jetpack-constants.git",
"reference": "5fdd94dec1151e7defd684a97e0b64fe6ff1bd3a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Automattic/jetpack-constants/zipball/5fdd94dec1151e7defd684a97e0b64fe6ff1bd3a",
"reference": "5fdd94dec1151e7defd684a97e0b64fe6ff1bd3a",
"shasum": ""
},
"require-dev": {
"phpunit/phpunit": "^5.7 || ^6.5 || ^7.5"
},
"type": "library",
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0-or-later"
],
"description": "A wrapper for defining constants in a more testable way.",
"time": "2019-11-08T21:16:05+00:00"
},
{
"name": "composer/installers",
"version": "v1.7.0",
@ -224,43 +254,227 @@
],
"time": "2019-12-19T22:59:03+00:00"
},
{
"name": "pelago/emogrifier",
"version": "v3.1.0",
"source": {
"type": "git",
"url": "https://github.com/MyIntervals/emogrifier.git",
"reference": "f6a5c7d44612d86c3901c93f1592f5440e6b2cd8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/f6a5c7d44612d86c3901c93f1592f5440e6b2cd8",
"reference": "f6a5c7d44612d86c3901c93f1592f5440e6b2cd8",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-libxml": "*",
"php": "^5.6 || ~7.0 || ~7.1 || ~7.2 || ~7.3 || ~7.4",
"symfony/css-selector": "^2.8 || ^3.0 || ^4.0 || ^5.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.15.3",
"phpmd/phpmd": "^2.7.0",
"phpunit/phpunit": "^5.7.27",
"squizlabs/php_codesniffer": "^3.5.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Pelago\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Oliver Klee",
"email": "github@oliverklee.de"
},
{
"name": "Zoli Szabó",
"email": "zoli.szabo+github@gmail.com"
},
{
"name": "John Reeve",
"email": "jreeve@pelagodesign.com"
},
{
"name": "Jake Hotson",
"email": "jake@qzdesign.co.uk"
},
{
"name": "Cameron Brooks"
},
{
"name": "Jaime Prado"
}
],
"description": "Converts CSS styles into inline style attributes in your HTML code",
"homepage": "https://www.myintervals.com/emogrifier.php",
"keywords": [
"css",
"email",
"pre-processing"
],
"time": "2019-12-26T19:37:31+00:00"
},
{
"name": "symfony/css-selector",
"version": "v3.4.37",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "e1b3e1a0621d6e48ee46092b4c7d8280f746b3c5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/e1b3e1a0621d6e48ee46092b4c7d8280f746b3c5",
"reference": "e1b3e1a0621d6e48ee46092b4c7d8280f746b3c5",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.4-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\CssSelector\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Jean-François Simon",
"email": "jeanfrancois.simon@sensiolabs.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"time": "2020-01-01T11:03:25+00:00"
},
{
"name": "woocommerce/action-scheduler",
"version": "2.2.5",
"version": "3.1.4",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/action-scheduler.git",
"reference": "fd7c6b76a7af27d6403ffe39b0963dbd8ce50488"
"reference": "5a01f0b549a283dc88c2feeef877650215907a76"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/action-scheduler/zipball/fd7c6b76a7af27d6403ffe39b0963dbd8ce50488",
"reference": "fd7c6b76a7af27d6403ffe39b0963dbd8ce50488",
"url": "https://api.github.com/repos/woocommerce/action-scheduler/zipball/5a01f0b549a283dc88c2feeef877650215907a76",
"reference": "5a01f0b549a283dc88c2feeef877650215907a76",
"shasum": ""
},
"require-dev": {
"wp-cli/wp-cli": "1.5.1"
"phpunit/phpunit": "^5.6",
"woocommerce/woocommerce-sniffs": "0.0.8",
"wp-cli/wp-cli": "~1.5.1"
},
"type": "wordpress-plugin",
"extra": {
"scripts-description": {
"test": "Run unit tests",
"phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer",
"phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0"
"GPL-3.0-or-later"
],
"description": "Action Scheduler for WordPress and WooCommerce",
"time": "2019-04-24T12:45:40+00:00"
"homepage": "https://actionscheduler.org/",
"time": "2020-03-18T15:05:10+00:00"
},
{
"name": "woocommerce/woocommerce-blocks",
"version": "v2.5.11",
"name": "woocommerce/woocommerce-admin",
"version": "v1.0.3",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-gutenberg-products-block.git",
"reference": "3d3c7bf1b425bbf39a222a4715b1c8efe9e72f60"
"url": "https://github.com/woocommerce/woocommerce-admin.git",
"reference": "36a0f6e6c237ad43357af21ea12e400baffa2aef"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/3d3c7bf1b425bbf39a222a4715b1c8efe9e72f60",
"reference": "3d3c7bf1b425bbf39a222a4715b1c8efe9e72f60",
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/36a0f6e6c237ad43357af21ea12e400baffa2aef",
"reference": "36a0f6e6c237ad43357af21ea12e400baffa2aef",
"shasum": ""
},
"require": {
"automattic/jetpack-autoloader": "^1.2.0",
"composer/installers": "1.7.0",
"php": ">=5.6|>=7.0"
},
"require-dev": {
"phpunit/phpunit": "7.5.20",
"woocommerce/woocommerce-sniffs": "0.0.9"
},
"type": "wordpress-plugin",
"extra": {
"scripts-description": {
"test": "Run unit tests",
"phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer",
"phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier"
}
},
"autoload": {
"classmap": [
"includes/"
],
"psr-4": {
"Automattic\\WooCommerce\\Admin\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0-or-later"
],
"description": "A modern, javascript-driven WooCommerce Admin experience.",
"homepage": "https://github.com/woocommerce/woocommerce-admin",
"time": "2020-03-19T17:17:00+00:00"
},
{
"name": "woocommerce/woocommerce-blocks",
"version": "v2.5.14",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-gutenberg-products-block.git",
"reference": "0dd70617085d2e73f3adfb38df98a90df3514816"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/0dd70617085d2e73f3adfb38df98a90df3514816",
"reference": "0dd70617085d2e73f3adfb38df98a90df3514816",
"shasum": ""
},
"require": {
@ -294,7 +508,7 @@
"gutenberg",
"woocommerce"
],
"time": "2020-01-20T20:26:05+00:00"
"time": "2020-03-03T13:25:56+00:00"
},
{
"name": "woocommerce/woocommerce-rest-api",
@ -460,6 +674,220 @@
],
"time": "2019-10-21T16:45:58+00:00"
},
{
"name": "gettext/gettext",
"version": "v4.8.2",
"source": {
"type": "git",
"url": "https://github.com/php-gettext/Gettext.git",
"reference": "e474f872f2c8636cf53fd283ec4ce1218f3d236a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-gettext/Gettext/zipball/e474f872f2c8636cf53fd283ec4ce1218f3d236a",
"reference": "e474f872f2c8636cf53fd283ec4ce1218f3d236a",
"shasum": ""
},
"require": {
"gettext/languages": "^2.3",
"php": ">=5.4.0"
},
"require-dev": {
"illuminate/view": "*",
"phpunit/phpunit": "^4.8|^5.7|^6.5",
"squizlabs/php_codesniffer": "^3.0",
"symfony/yaml": "~2",
"twig/extensions": "*",
"twig/twig": "^1.31|^2.0"
},
"suggest": {
"illuminate/view": "Is necessary if you want to use the Blade extractor",
"symfony/yaml": "Is necessary if you want to use the Yaml extractor/generator",
"twig/extensions": "Is necessary if you want to use the Twig extractor",
"twig/twig": "Is necessary if you want to use the Twig extractor"
},
"type": "library",
"autoload": {
"psr-4": {
"Gettext\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Oscar Otero",
"email": "oom@oscarotero.com",
"homepage": "http://oscarotero.com",
"role": "Developer"
}
],
"description": "PHP gettext manager",
"homepage": "https://github.com/oscarotero/Gettext",
"keywords": [
"JS",
"gettext",
"i18n",
"mo",
"po",
"translation"
],
"time": "2019-12-02T10:21:14+00:00"
},
{
"name": "gettext/languages",
"version": "2.6.0",
"source": {
"type": "git",
"url": "https://github.com/php-gettext/Languages.git",
"reference": "38ea0482f649e0802e475f0ed19fa993bcb7a618"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-gettext/Languages/zipball/38ea0482f649e0802e475f0ed19fa993bcb7a618",
"reference": "38ea0482f649e0802e475f0ed19fa993bcb7a618",
"shasum": ""
},
"require": {
"php": ">=5.3"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.16.0",
"phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.4"
},
"bin": [
"bin/export-plural-rules"
],
"type": "library",
"autoload": {
"psr-4": {
"Gettext\\Languages\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michele Locati",
"email": "mlocati@gmail.com",
"role": "Developer"
}
],
"description": "gettext languages with plural rules",
"homepage": "https://github.com/php-gettext/Languages",
"keywords": [
"cldr",
"i18n",
"internationalization",
"l10n",
"language",
"languages",
"localization",
"php",
"plural",
"plural rules",
"plurals",
"translate",
"translations",
"unicode"
],
"time": "2019-11-13T10:30:21+00:00"
},
{
"name": "mck89/peast",
"version": "v1.10.1",
"source": {
"type": "git",
"url": "https://github.com/mck89/peast.git",
"reference": "461fbe96212ac1b511f527fd11b942e976429398"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mck89/peast/zipball/461fbe96212ac1b511f527fd11b942e976429398",
"reference": "461fbe96212ac1b511f527fd11b942e976429398",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0|^5.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.10.1-dev"
}
},
"autoload": {
"psr-4": {
"Peast\\": "lib/Peast/",
"Peast\\test\\": "test/Peast/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Marco Marchiò",
"email": "marco.mm89@gmail.com"
}
],
"description": "Peast is PHP library that generates AST for JavaScript code",
"time": "2019-12-22T16:46:42+00:00"
},
{
"name": "mustache/mustache",
"version": "v2.13.0",
"source": {
"type": "git",
"url": "https://github.com/bobthecow/mustache.php.git",
"reference": "e95c5a008c23d3151d59ea72484d4f72049ab7f4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/e95c5a008c23d3151d59ea72484d4f72049ab7f4",
"reference": "e95c5a008c23d3151d59ea72484d4f72049ab7f4",
"shasum": ""
},
"require": {
"php": ">=5.2.4"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "~1.11",
"phpunit/phpunit": "~3.7|~4.0|~5.0"
},
"type": "library",
"autoload": {
"psr-0": {
"Mustache": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Justin Hileman",
"email": "justin@justinhileman.info",
"homepage": "http://justinhileman.com"
}
],
"description": "A Mustache implementation in PHP.",
"homepage": "https://github.com/bobthecow/mustache.php",
"keywords": [
"mustache",
"templating"
],
"time": "2019-11-23T21:40:31+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.9.5",
@ -1320,6 +1748,55 @@
],
"time": "2020-01-08T08:45:45+00:00"
},
{
"name": "rmccue/requests",
"version": "v1.7.0",
"source": {
"type": "git",
"url": "https://github.com/rmccue/Requests.git",
"reference": "87932f52ffad70504d93f04f15690cf16a089546"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rmccue/Requests/zipball/87932f52ffad70504d93f04f15690cf16a089546",
"reference": "87932f52ffad70504d93f04f15690cf16a089546",
"shasum": ""
},
"require": {
"php": ">=5.2"
},
"require-dev": {
"requests/test-server": "dev-master"
},
"type": "library",
"autoload": {
"psr-0": {
"Requests": "library/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"ISC"
],
"authors": [
{
"name": "Ryan McCue",
"homepage": "http://ryanmccue.info"
}
],
"description": "A HTTP library written in PHP, for human beings.",
"homepage": "http://github.com/rmccue/Requests",
"keywords": [
"curl",
"fsockopen",
"http",
"idna",
"ipv6",
"iri",
"sockets"
],
"time": "2016-10-13T00:11:37+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
"version": "1.0.1",
@ -1938,17 +2415,66 @@
"time": "2020-01-30T22:20:29+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.13.1",
"name": "symfony/finder",
"version": "v3.4.37",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3"
"url": "https://github.com/symfony/finder.git",
"reference": "a90a9d3b9f458a5cdeabfa4090b20c000ca3962f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f8f0b461be3385e56d6de3dbb5a0df24c0c275e3",
"reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3",
"url": "https://api.github.com/repos/symfony/finder/zipball/a90a9d3b9f458a5cdeabfa4090b20c000ca3962f",
"reference": "a90a9d3b9f458a5cdeabfa4090b20c000ca3962f",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.4-dev"
}
},
"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",
"time": "2020-01-01T11:03:25+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.14.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/fbdeaec0df06cf3d51c93de80c7eb76e271f5a38",
"reference": "fbdeaec0df06cf3d51c93de80c7eb76e271f5a38",
"shasum": ""
},
"require": {
@ -1960,7 +2486,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.13-dev"
"dev-master": "1.14-dev"
}
},
"autoload": {
@ -1993,7 +2519,7 @@
"polyfill",
"portable"
],
"time": "2019-11-27T13:56:44+00:00"
"time": "2020-01-13T11:15:53+00:00"
},
{
"name": "theseer/tokenizer",
@ -2037,16 +2563,16 @@
},
{
"name": "webmozart/assert",
"version": "1.6.0",
"version": "1.7.0",
"source": {
"type": "git",
"url": "https://github.com/webmozart/assert.git",
"reference": "573381c0a64f155a0d9a23f4b0c797194805b925"
"reference": "aed98a490f9a8f78468232db345ab9cf606cf598"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925",
"reference": "573381c0a64f155a0d9a23f4b0c797194805b925",
"url": "https://api.github.com/repos/webmozart/assert/zipball/aed98a490f9a8f78468232db345ab9cf606cf598",
"reference": "aed98a490f9a8f78468232db345ab9cf606cf598",
"shasum": ""
},
"require": {
@ -2081,7 +2607,7 @@
"check",
"validate"
],
"time": "2019-11-24T13:36:37+00:00"
"time": "2020-02-14T12:15:55+00:00"
},
{
"name": "woocommerce/woocommerce-sniffs",
@ -2123,6 +2649,223 @@
],
"time": "2019-11-11T15:48:34+00:00"
},
{
"name": "wp-cli/i18n-command",
"version": "v2.2.2",
"source": {
"type": "git",
"url": "https://github.com/wp-cli/i18n-command.git",
"reference": "2804c5246d9338da59951737b03c54d257be8e47"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/wp-cli/i18n-command/zipball/2804c5246d9338da59951737b03c54d257be8e47",
"reference": "2804c5246d9338da59951737b03c54d257be8e47",
"shasum": ""
},
"require": {
"gettext/gettext": "^4.8",
"mck89/peast": "^1.8",
"wp-cli/wp-cli": "^2"
},
"require-dev": {
"wp-cli/scaffold-command": "^1.2 || ^2",
"wp-cli/wp-cli-tests": "^2.1.3"
},
"type": "wp-cli-package",
"extra": {
"branch-alias": {
"dev-master": "2.x-dev"
},
"bundled": true,
"commands": [
"i18n",
"i18n make-pot",
"i18n make-json"
]
},
"autoload": {
"psr-4": {
"WP_CLI\\I18n\\": "src/"
},
"files": [
"i18n-command.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Pascal Birchler",
"homepage": "https://pascalbirchler.com/"
}
],
"description": "Provides internationalization tools for WordPress projects.",
"homepage": "https://github.com/wp-cli/i18n-command",
"time": "2019-12-13T09:00:43+00:00"
},
{
"name": "wp-cli/mustangostang-spyc",
"version": "0.6.3",
"source": {
"type": "git",
"url": "https://github.com/wp-cli/spyc.git",
"reference": "6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/wp-cli/spyc/zipball/6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7",
"reference": "6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7",
"shasum": ""
},
"require": {
"php": ">=5.3.1"
},
"require-dev": {
"phpunit/phpunit": "4.3.*@dev"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.5.x-dev"
}
},
"autoload": {
"psr-4": {
"Mustangostang\\": "src/"
},
"files": [
"includes/functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "mustangostang",
"email": "vlad.andersen@gmail.com"
}
],
"description": "A simple YAML loader/dumper class for PHP (WP-CLI fork)",
"homepage": "https://github.com/mustangostang/spyc/",
"time": "2017-04-25T11:26:20+00:00"
},
{
"name": "wp-cli/php-cli-tools",
"version": "v0.11.11",
"source": {
"type": "git",
"url": "https://github.com/wp-cli/php-cli-tools.git",
"reference": "fe9c7c44a9e1bf2196ec51dc38da0593dbf2993f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/fe9c7c44a9e1bf2196ec51dc38da0593dbf2993f",
"reference": "fe9c7c44a9e1bf2196ec51dc38da0593dbf2993f",
"shasum": ""
},
"require": {
"php": ">= 5.3.0"
},
"type": "library",
"autoload": {
"psr-0": {
"cli": "lib/"
},
"files": [
"lib/cli/cli.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "James Logsdon",
"email": "jlogsdon@php.net",
"role": "Developer"
},
{
"name": "Daniel Bachhuber",
"email": "daniel@handbuilt.co",
"role": "Maintainer"
}
],
"description": "Console utilities for PHP",
"homepage": "http://github.com/wp-cli/php-cli-tools",
"keywords": [
"cli",
"console"
],
"time": "2018-09-04T13:28:00+00:00"
},
{
"name": "wp-cli/wp-cli",
"version": "v2.4.1",
"source": {
"type": "git",
"url": "https://github.com/wp-cli/wp-cli.git",
"reference": "ceb18598e79befa9b2a37a51efbb34910628988b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/wp-cli/wp-cli/zipball/ceb18598e79befa9b2a37a51efbb34910628988b",
"reference": "ceb18598e79befa9b2a37a51efbb34910628988b",
"shasum": ""
},
"require": {
"ext-curl": "*",
"mustache/mustache": "~2.13",
"php": "^5.4 || ^7.0",
"rmccue/requests": "~1.6",
"symfony/finder": ">2.7",
"wp-cli/mustangostang-spyc": "^0.6.3",
"wp-cli/php-cli-tools": "~0.11.2"
},
"require-dev": {
"roave/security-advisories": "dev-master",
"wp-cli/db-command": "^1.3 || ^2",
"wp-cli/entity-command": "^1.2 || ^2",
"wp-cli/extension-command": "^1.1 || ^2",
"wp-cli/package-command": "^1 || ^2",
"wp-cli/wp-cli-tests": "^2.1"
},
"suggest": {
"ext-readline": "Include for a better --prompt implementation",
"ext-zip": "Needed to support extraction of ZIP archives when doing downloads or updates"
},
"bin": [
"bin/wp",
"bin/wp.bat"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4.x-dev"
}
},
"autoload": {
"psr-0": {
"WP_CLI": "php"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "WP-CLI framework",
"homepage": "https://wp-cli.org",
"keywords": [
"cli",
"wordpress"
],
"time": "2020-02-18T08:15:37+00:00"
},
{
"name": "wp-coding-standards/wpcs",
"version": "2.2.0",
@ -2180,5 +2923,6 @@
"platform-dev": [],
"platform-overrides": {
"php": "7.1"
}
},
"plugin-api-version": "1.1.0"
}

View File

@ -3,7 +3,7 @@ version: '3.7'
services:
db:
image: mariadb:10.4
image: mariadb:10.5
restart: on-failure
environment:
MYSQL_DATABASE: testdb

View File

@ -7,6 +7,8 @@
* @version 3.3.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -94,7 +96,7 @@ abstract class WC_Deprecated_Hooks {
* @return string
*/
protected function get_deprecated_version( $old_hook ) {
return ! empty( $this->deprecated_version[ $old_hook ] ) ? $this->deprecated_version[ $old_hook ] : WC_VERSION;
return ! empty( $this->deprecated_version[ $old_hook ] ) ? $this->deprecated_version[ $old_hook ] : Constants::get_constant( 'WC_VERSION' );
}
/**

View File

@ -1050,10 +1050,10 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
$result = $coupon->get_data_store()->check_and_hold_coupon( $coupon );
if ( false === $result ) {
// translators: Actual coupon code.
throw new Exception( sprintf( __( 'An unexpected error happened while applying the Coupon %s.', 'woocommerce' ), $coupon->get_code() ) );
throw new Exception( sprintf( __( 'An unexpected error happened while applying the Coupon %s.', 'woocommerce' ), esc_html( $coupon->get_code() ) ) );
} elseif ( 0 === $result ) {
// translators: Actual coupon code.
throw new Exception( sprintf( __( 'Coupon %s was used in another transaction during this checkout, and coupon usage limit is reached. Please remove the coupon and try again.', 'woocommerce' ), $coupon->get_code() ) );
throw new Exception( sprintf( __( 'Coupon %s was used in another transaction during this checkout, and coupon usage limit is reached. Please remove the coupon and try again.', 'woocommerce' ), esc_html( $coupon->get_code() ) ) );
}
return $result;
}
@ -1072,10 +1072,10 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
$result = $coupon->get_data_store()->check_and_hold_coupon_for_user( $coupon, $user_ids_and_emails, $user_alias );
if ( false === $result ) {
// translators: Actual coupon code.
throw new Exception( sprintf( __( 'An unexpected error happened while applying the Coupon %s.', 'woocommerce' ), $coupon->get_code() ) );
throw new Exception( sprintf( __( 'An unexpected error happened while applying the Coupon %s.', 'woocommerce' ), esc_html( $coupon->get_code() ) ) );
} elseif ( 0 === $result ) {
// translators: Actual coupon code.
throw new Exception( sprintf( __( 'You have used this coupon %s in another transaction during this checkout, and coupon usage limit is reached. Please remove the coupon and try again.', 'woocommerce' ), $coupon->get_code() ) );
throw new Exception( sprintf( __( 'You have used this coupon %s in another transaction during this checkout, and coupon usage limit is reached. Please remove the coupon and try again.', 'woocommerce' ), esc_html( $coupon->get_code() ) ) );
}
return $result;
}
@ -1522,7 +1522,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
$args['city'] = WC()->countries->get_base_city();
}
return $args;
return apply_filters( 'woocommerce_order_get_tax_location', $args, $this );
}
/**
@ -1568,6 +1568,20 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
$this->update_taxes();
}
/**
* Calculate fees for all line items.
*
* @return float Fee total.
*/
public function get_total_fees() {
return array_reduce(
$this->get_fees(),
function( $carry, $item ) {
return $carry + $item->get_total();
}
);
}
/**
* Update tax lines for the order based on the line item taxes themselves.
*/
@ -1695,7 +1709,6 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
$item->set_total( $max_discount );
}
}
$fees_total += $item->get_total();
}

View File

@ -9,6 +9,8 @@
* @package WooCommerce/Abstracts
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -450,7 +452,7 @@ abstract class WC_Payment_Gateway extends WC_Settings_API {
public function tokenization_script() {
wp_enqueue_script(
'woocommerce-tokenization-form',
plugins_url( '/assets/js/frontend/tokenization-form' . ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' ) . '.js', WC_PLUGIN_FILE ),
plugins_url( '/assets/js/frontend/tokenization-form' . ( Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min' ) . '.js', WC_PLUGIN_FILE ),
array( 'jquery' ),
WC()->version
);

View File

@ -6,6 +6,8 @@
* @package WooCommerce/Abstracts
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -319,7 +321,7 @@ abstract class WC_Widget extends WP_Widget {
* @since 3.3.0
*/
protected function get_current_page_url() {
if ( defined( 'SHOP_IS_ON_FRONT' ) ) {
if ( Constants::is_defined( 'SHOP_IS_ON_FRONT' ) ) {
$link = home_url();
} elseif ( is_shop() ) {
$link = get_permalink( wc_get_page_id( 'shop' ) );

View File

@ -6,6 +6,8 @@
* @version 2.5.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -489,7 +491,7 @@ class WC_Admin_Addons {
return array(
'wccom-site' => site_url(),
'wccom-back' => rawurlencode( $back_admin_path ),
'wccom-woo-version' => WC_VERSION,
'wccom-woo-version' => Constants::get_constant( 'WC_VERSION' ),
'wccom-connect-nonce' => wp_create_nonce( 'connect' ),
);
}

View File

@ -6,6 +6,8 @@
* @version 3.7.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -31,17 +33,18 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
public function admin_styles() {
global $wp_scripts;
$version = Constants::get_constant( 'WC_VERSION' );
$screen = get_current_screen();
$screen_id = $screen ? $screen->id : '';
// Register admin styles.
wp_register_style( 'woocommerce_admin_menu_styles', WC()->plugin_url() . '/assets/css/menu.css', array(), WC_VERSION );
wp_register_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_VERSION );
wp_register_style( 'jquery-ui-style', WC()->plugin_url() . '/assets/css/jquery-ui/jquery-ui.min.css', array(), WC_VERSION );
wp_register_style( 'woocommerce_admin_dashboard_styles', WC()->plugin_url() . '/assets/css/dashboard.css', array(), WC_VERSION );
wp_register_style( 'woocommerce_admin_print_reports_styles', WC()->plugin_url() . '/assets/css/reports-print.css', array(), WC_VERSION, 'print' );
wp_register_style( 'woocommerce_admin_marketplace_styles', WC()->plugin_url() . '/assets/css/marketplace-suggestions.css', array(), WC_VERSION );
wp_register_style( 'woocommerce_admin_privacy_styles', WC()->plugin_url() . '/assets/css/privacy.css', array(), WC_VERSION );
wp_register_style( 'woocommerce_admin_menu_styles', WC()->plugin_url() . '/assets/css/menu.css', array(), $version );
wp_register_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), $version );
wp_register_style( 'jquery-ui-style', WC()->plugin_url() . '/assets/css/jquery-ui/jquery-ui.min.css', array(), $version );
wp_register_style( 'woocommerce_admin_dashboard_styles', WC()->plugin_url() . '/assets/css/dashboard.css', array(), $version );
wp_register_style( 'woocommerce_admin_print_reports_styles', WC()->plugin_url() . '/assets/css/reports-print.css', array(), $version, 'print' );
wp_register_style( 'woocommerce_admin_marketplace_styles', WC()->plugin_url() . '/assets/css/marketplace-suggestions.css', array(), $version );
wp_register_style( 'woocommerce_admin_privacy_styles', WC()->plugin_url() . '/assets/css/privacy.css', array(), $version );
// Add RTL support for admin styles.
wp_style_add_data( 'woocommerce_admin_menu_styles', 'rtl', 'replace' );
@ -95,32 +98,33 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
$screen = get_current_screen();
$screen_id = $screen ? $screen->id : '';
$wc_screen_id = sanitize_title( __( 'WooCommerce', 'woocommerce' ) );
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
$suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min';
$version = Constants::get_constant( 'WC_VERSION' );
// Register scripts.
wp_register_script( 'woocommerce_admin', WC()->plugin_url() . '/assets/js/admin/woocommerce_admin' . $suffix . '.js', array( 'jquery', 'jquery-blockui', 'jquery-ui-sortable', 'jquery-ui-widget', 'jquery-ui-core', 'jquery-tiptip' ), WC_VERSION );
wp_register_script( 'woocommerce_admin', WC()->plugin_url() . '/assets/js/admin/woocommerce_admin' . $suffix . '.js', array( 'jquery', 'jquery-blockui', 'jquery-ui-sortable', 'jquery-ui-widget', 'jquery-ui-core', 'jquery-tiptip' ), $version );
wp_register_script( 'jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.70', true );
wp_register_script( 'jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip' . $suffix . '.js', array( 'jquery' ), WC_VERSION, true );
wp_register_script( 'round', WC()->plugin_url() . '/assets/js/round/round' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
wp_register_script( 'wc-admin-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes' . $suffix . '.js', array( 'jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'accounting', 'round', 'wc-enhanced-select', 'plupload-all', 'stupidtable', 'jquery-tiptip' ), WC_VERSION );
wp_register_script( 'zeroclipboard', WC()->plugin_url() . '/assets/js/zeroclipboard/jquery.zeroclipboard' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
wp_register_script( 'qrcode', WC()->plugin_url() . '/assets/js/jquery-qrcode/jquery.qrcode' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
wp_register_script( 'stupidtable', WC()->plugin_url() . '/assets/js/stupidtable/stupidtable' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
wp_register_script( 'jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip' . $suffix . '.js', array( 'jquery' ), $version, true );
wp_register_script( 'round', WC()->plugin_url() . '/assets/js/round/round' . $suffix . '.js', array( 'jquery' ), $version );
wp_register_script( 'wc-admin-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes' . $suffix . '.js', array( 'jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'accounting', 'round', 'wc-enhanced-select', 'plupload-all', 'stupidtable', 'jquery-tiptip' ), $version );
wp_register_script( 'zeroclipboard', WC()->plugin_url() . '/assets/js/zeroclipboard/jquery.zeroclipboard' . $suffix . '.js', array( 'jquery' ), $version );
wp_register_script( 'qrcode', WC()->plugin_url() . '/assets/js/jquery-qrcode/jquery.qrcode' . $suffix . '.js', array( 'jquery' ), $version );
wp_register_script( 'stupidtable', WC()->plugin_url() . '/assets/js/stupidtable/stupidtable' . $suffix . '.js', array( 'jquery' ), $version );
wp_register_script( 'serializejson', WC()->plugin_url() . '/assets/js/jquery-serializejson/jquery.serializejson' . $suffix . '.js', array( 'jquery' ), '2.8.1' );
wp_register_script( 'flot', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
wp_register_script( 'flot-resize', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.resize' . $suffix . '.js', array( 'jquery', 'flot' ), WC_VERSION );
wp_register_script( 'flot-time', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.time' . $suffix . '.js', array( 'jquery', 'flot' ), WC_VERSION );
wp_register_script( 'flot-pie', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.pie' . $suffix . '.js', array( 'jquery', 'flot' ), WC_VERSION );
wp_register_script( 'flot-stack', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.stack' . $suffix . '.js', array( 'jquery', 'flot' ), WC_VERSION );
wp_register_script( 'wc-settings-tax', WC()->plugin_url() . '/assets/js/admin/settings-views-html-settings-tax' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-blockui' ), WC_VERSION );
wp_register_script( 'wc-backbone-modal', WC()->plugin_url() . '/assets/js/admin/backbone-modal' . $suffix . '.js', array( 'underscore', 'backbone', 'wp-util' ), WC_VERSION );
wp_register_script( 'wc-shipping-zones', WC()->plugin_url() . '/assets/js/admin/wc-shipping-zones' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-ui-sortable', 'wc-enhanced-select', 'wc-backbone-modal' ), WC_VERSION );
wp_register_script( 'wc-shipping-zone-methods', WC()->plugin_url() . '/assets/js/admin/wc-shipping-zone-methods' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-ui-sortable', 'wc-backbone-modal' ), WC_VERSION );
wp_register_script( 'wc-shipping-classes', WC()->plugin_url() . '/assets/js/admin/wc-shipping-classes' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone' ), WC_VERSION );
wp_register_script( 'wc-clipboard', WC()->plugin_url() . '/assets/js/admin/wc-clipboard' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
wp_register_script( 'flot', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot' . $suffix . '.js', array( 'jquery' ), $version );
wp_register_script( 'flot-resize', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.resize' . $suffix . '.js', array( 'jquery', 'flot' ), $version );
wp_register_script( 'flot-time', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.time' . $suffix . '.js', array( 'jquery', 'flot' ), $version );
wp_register_script( 'flot-pie', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.pie' . $suffix . '.js', array( 'jquery', 'flot' ), $version );
wp_register_script( 'flot-stack', WC()->plugin_url() . '/assets/js/jquery-flot/jquery.flot.stack' . $suffix . '.js', array( 'jquery', 'flot' ), $version );
wp_register_script( 'wc-settings-tax', WC()->plugin_url() . '/assets/js/admin/settings-views-html-settings-tax' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-blockui' ), $version );
wp_register_script( 'wc-backbone-modal', WC()->plugin_url() . '/assets/js/admin/backbone-modal' . $suffix . '.js', array( 'underscore', 'backbone', 'wp-util' ), $version );
wp_register_script( 'wc-shipping-zones', WC()->plugin_url() . '/assets/js/admin/wc-shipping-zones' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-ui-sortable', 'wc-enhanced-select', 'wc-backbone-modal' ), $version );
wp_register_script( 'wc-shipping-zone-methods', WC()->plugin_url() . '/assets/js/admin/wc-shipping-zone-methods' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-ui-sortable', 'wc-backbone-modal' ), $version );
wp_register_script( 'wc-shipping-classes', WC()->plugin_url() . '/assets/js/admin/wc-shipping-classes' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone' ), $version );
wp_register_script( 'wc-clipboard', WC()->plugin_url() . '/assets/js/admin/wc-clipboard' . $suffix . '.js', array( 'jquery' ), $version );
wp_register_script( 'select2', WC()->plugin_url() . '/assets/js/select2/select2.full' . $suffix . '.js', array( 'jquery' ), '4.0.3' );
wp_register_script( 'selectWoo', WC()->plugin_url() . '/assets/js/selectWoo/selectWoo.full' . $suffix . '.js', array( 'jquery' ), '1.0.6' );
wp_register_script( 'wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array( 'jquery', 'selectWoo' ), WC_VERSION );
wp_register_script( 'wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array( 'jquery', 'selectWoo' ), $version );
wp_register_script( 'js-cookie', WC()->plugin_url() . '/assets/js/js-cookie/js.cookie' . $suffix . '.js', array(), '2.1.4', true );
wp_localize_script(
@ -153,7 +157,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
)
);
wp_register_script( 'wc-orders', WC()->plugin_url() . '/assets/js/admin/wc-orders' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-blockui' ), WC_VERSION );
wp_register_script( 'wc-orders', WC()->plugin_url() . '/assets/js/admin/wc-orders' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-blockui' ), $version );
wp_localize_script(
'wc-orders',
'wc_orders_params',
@ -209,7 +213,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
// Products.
if ( in_array( $screen_id, array( 'edit-product' ) ) ) {
wp_enqueue_script( 'woocommerce_quick-edit', WC()->plugin_url() . '/assets/js/admin/quick-edit' . $suffix . '.js', array( 'jquery', 'woocommerce_admin' ), WC_VERSION );
wp_enqueue_script( 'woocommerce_quick-edit', WC()->plugin_url() . '/assets/js/admin/quick-edit' . $suffix . '.js', array( 'jquery', 'woocommerce_admin' ), $version );
$params = array(
'strings' => array(
@ -223,8 +227,8 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
// Meta boxes.
if ( in_array( $screen_id, array( 'product', 'edit-product' ) ) ) {
wp_enqueue_media();
wp_register_script( 'wc-admin-product-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product' . $suffix . '.js', array( 'wc-admin-meta-boxes', 'media-models' ), WC_VERSION );
wp_register_script( 'wc-admin-variation-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product-variation' . $suffix . '.js', array( 'wc-admin-meta-boxes', 'serializejson', 'media-models' ), WC_VERSION );
wp_register_script( 'wc-admin-product-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product' . $suffix . '.js', array( 'wc-admin-meta-boxes', 'media-models' ), $version );
wp_register_script( 'wc-admin-variation-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-product-variation' . $suffix . '.js', array( 'wc-admin-meta-boxes', 'serializejson', 'media-models' ), $version );
wp_enqueue_script( 'wc-admin-product-meta-boxes' );
wp_enqueue_script( 'wc-admin-variation-meta-boxes' );
@ -241,7 +245,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
'save_variations_nonce' => wp_create_nonce( 'save-variations' ),
'bulk_edit_variations_nonce' => wp_create_nonce( 'bulk-edit-variations' ),
/* translators: %d: Number of variations */
'i18n_link_all_variations' => esc_js( sprintf( __( 'Are you sure you want to link all variations? This will create a new variation for each and every possible combination of variation attributes (max %d per run).', 'woocommerce' ), defined( 'WC_MAX_LINKED_VARIATIONS' ) ? WC_MAX_LINKED_VARIATIONS : 50 ) ),
'i18n_link_all_variations' => esc_js( sprintf( __( 'Are you sure you want to link all variations? This will create a new variation for each and every possible combination of variation attributes (max %d per run).', 'woocommerce' ), Constants::is_defined( 'WC_MAX_LINKED_VARIATIONS' ) ? Constants::get_constant( 'WC_MAX_LINKED_VARIATIONS' ) : 50 ) ),
'i18n_enter_a_value' => esc_js( __( 'Enter a value', 'woocommerce' ) ),
'i18n_enter_menu_order' => esc_js( __( 'Variation menu order (determines position in the list of variations)', 'woocommerce' ) ),
'i18n_enter_a_value_fixed_or_percent' => esc_js( __( 'Enter a value (fixed or %)', 'woocommerce' ) ),
@ -266,7 +270,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
if ( in_array( str_replace( 'edit-', '', $screen_id ), wc_get_order_types( 'order-meta-boxes' ) ) ) {
$default_location = wc_get_customer_default_location();
wp_enqueue_script( 'wc-admin-order-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-order' . $suffix . '.js', array( 'wc-admin-meta-boxes', 'wc-backbone-modal', 'selectWoo', 'wc-clipboard' ), WC_VERSION );
wp_enqueue_script( 'wc-admin-order-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-order' . $suffix . '.js', array( 'wc-admin-meta-boxes', 'wc-backbone-modal', 'selectWoo', 'wc-clipboard' ), $version );
wp_localize_script(
'wc-admin-order-meta-boxes',
'woocommerce_admin_meta_boxes_order',
@ -281,7 +285,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
);
}
if ( in_array( $screen_id, array( 'shop_coupon', 'edit-shop_coupon' ) ) ) {
wp_enqueue_script( 'wc-admin-coupon-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-coupon' . $suffix . '.js', array( 'wc-admin-meta-boxes' ), WC_VERSION );
wp_enqueue_script( 'wc-admin-coupon-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-coupon' . $suffix . '.js', array( 'wc-admin-meta-boxes' ), $version );
wp_localize_script(
'wc-admin-coupon-meta-boxes',
'woocommerce_admin_meta_boxes_coupon',
@ -372,7 +376,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
// Term ordering - only when sorting by term_order.
if ( ( strstr( $screen_id, 'edit-pa_' ) || ( ! empty( $_GET['taxonomy'] ) && in_array( wp_unslash( $_GET['taxonomy'] ), apply_filters( 'woocommerce_sortable_taxonomies', array( 'product_cat' ) ) ) ) ) && ! isset( $_GET['orderby'] ) ) {
wp_register_script( 'woocommerce_term_ordering', WC()->plugin_url() . '/assets/js/admin/term-ordering' . $suffix . '.js', array( 'jquery-ui-sortable' ), WC_VERSION );
wp_register_script( 'woocommerce_term_ordering', WC()->plugin_url() . '/assets/js/admin/term-ordering' . $suffix . '.js', array( 'jquery-ui-sortable' ), $version );
wp_enqueue_script( 'woocommerce_term_ordering' );
$taxonomy = isset( $_GET['taxonomy'] ) ? wc_clean( wp_unslash( $_GET['taxonomy'] ) ) : '';
@ -386,13 +390,13 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
// Product sorting - only when sorting by menu order on the products page.
if ( current_user_can( 'edit_others_pages' ) && 'edit-product' === $screen_id && isset( $wp_query->query['orderby'] ) && 'menu_order title' === $wp_query->query['orderby'] ) {
wp_register_script( 'woocommerce_product_ordering', WC()->plugin_url() . '/assets/js/admin/product-ordering' . $suffix . '.js', array( 'jquery-ui-sortable' ), WC_VERSION, true );
wp_register_script( 'woocommerce_product_ordering', WC()->plugin_url() . '/assets/js/admin/product-ordering' . $suffix . '.js', array( 'jquery-ui-sortable' ), $version, true );
wp_enqueue_script( 'woocommerce_product_ordering' );
}
// Reports Pages.
if ( in_array( $screen_id, apply_filters( 'woocommerce_reports_screen_ids', array( $wc_screen_id . '_page_wc-reports', 'toplevel_page_wc-reports', 'dashboard' ) ) ) ) {
wp_register_script( 'wc-reports', WC()->plugin_url() . '/assets/js/admin/reports' . $suffix . '.js', array( 'jquery', 'jquery-ui-datepicker' ), WC_VERSION );
wp_register_script( 'wc-reports', WC()->plugin_url() . '/assets/js/admin/reports' . $suffix . '.js', array( 'jquery', 'jquery-ui-datepicker' ), $version );
wp_enqueue_script( 'wc-reports' );
wp_enqueue_script( 'flot' );
@ -404,7 +408,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
// API settings.
if ( $wc_screen_id . '_page_wc-settings' === $screen_id && isset( $_GET['section'] ) && 'keys' == $_GET['section'] ) {
wp_register_script( 'wc-api-keys', WC()->plugin_url() . '/assets/js/admin/api-keys' . $suffix . '.js', array( 'jquery', 'woocommerce_admin', 'underscore', 'backbone', 'wp-util', 'qrcode', 'wc-clipboard' ), WC_VERSION, true );
wp_register_script( 'wc-api-keys', WC()->plugin_url() . '/assets/js/admin/api-keys' . $suffix . '.js', array( 'jquery', 'woocommerce_admin', 'underscore', 'backbone', 'wp-util', 'qrcode', 'wc-clipboard' ), $version, true );
wp_enqueue_script( 'wc-api-keys' );
wp_localize_script(
'wc-api-keys',
@ -419,7 +423,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
// System status.
if ( $wc_screen_id . '_page_wc-status' === $screen_id ) {
wp_register_script( 'wc-admin-system-status', WC()->plugin_url() . '/assets/js/admin/system-status' . $suffix . '.js', array( 'wc-clipboard' ), WC_VERSION );
wp_register_script( 'wc-admin-system-status', WC()->plugin_url() . '/assets/js/admin/system-status' . $suffix . '.js', array( 'wc-clipboard' ), $version );
wp_enqueue_script( 'wc-admin-system-status' );
wp_localize_script(
'wc-admin-system-status',
@ -431,7 +435,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
}
if ( in_array( $screen_id, array( 'user-edit', 'profile' ) ) ) {
wp_register_script( 'wc-users', WC()->plugin_url() . '/assets/js/admin/users' . $suffix . '.js', array( 'jquery', 'wc-enhanced-select', 'selectWoo' ), WC_VERSION, true );
wp_register_script( 'wc-users', WC()->plugin_url() . '/assets/js/admin/users' . $suffix . '.js', array( 'jquery', 'wc-enhanced-select', 'selectWoo' ), $version, true );
wp_enqueue_script( 'wc-users' );
wp_localize_script(
'wc-users',
@ -449,7 +453,7 @@ if ( ! class_exists( 'WC_Admin_Assets', false ) ) :
'marketplace-suggestions',
WC()->plugin_url() . '/assets/js/admin/marketplace-suggestions' . $suffix . '.js',
array( 'jquery', 'underscore', 'js-cookie' ),
WC_VERSION,
$version,
true
);
wp_localize_script(

View File

@ -15,6 +15,13 @@ defined( 'ABSPATH' ) || exit;
*/
class WC_Admin_Attributes {
/**
* Edited attribute ID.
*
* @var int
*/
private static $edited_attribute_id;
/**
* Handles output of the attributes page in admin.
*
@ -135,7 +142,7 @@ class WC_Admin_Attributes {
return $id;
}
echo '<div class="updated"><p>' . esc_html__( 'Attribute updated successfully', 'woocommerce' ) . '</p><p><a href="' . esc_url( admin_url( 'edit.php?post_type=product&amp;page=product_attributes' ) ) . '">' . esc_html__( 'Back to Attributes', 'woocommerce' ) . '</a></p></div>';
self::$edited_attribute_id = $id;
return true;
}
@ -180,6 +187,10 @@ class WC_Admin_Attributes {
if ( ! $attribute_to_edit ) {
echo '<div id="woocommerce_errors" class="error"><p>' . esc_html__( 'Error: non-existing attribute ID.', 'woocommerce' ) . '</p></div>';
} else {
if ( self::$edited_attribute_id > 0 ) {
echo '<div id="message" class="updated"><p>' . esc_html__( 'Attribute updated successfully', 'woocommerce' ) . '</p><p><a href="' . esc_url( admin_url( 'edit.php?post_type=product&amp;page=product_attributes' ) ) . '">' . esc_html__( 'Back to Attributes', 'woocommerce' ) . '</a></p></div>';
self::$edited_attribute_id = null;
}
$att_type = $attribute_to_edit->attribute_type;
$att_label = format_to_edit( $attribute_to_edit->attribute_label );
$att_name = $attribute_to_edit->attribute_name;

View File

@ -6,6 +6,8 @@
* @version 2.1.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
@ -322,11 +324,12 @@ if ( ! class_exists( 'WC_Admin_Dashboard', false ) ) :
* Network orders widget.
*/
public function network_orders() {
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
$suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min';
$version = Constants::get_constant( 'WC_VERSION' );
wp_enqueue_style( 'wc-network-orders', WC()->plugin_url() . '/assets/css/network-order-widget.css', array(), WC_VERSION );
wp_enqueue_style( 'wc-network-orders', WC()->plugin_url() . '/assets/css/network-order-widget.css', array(), $version );
wp_enqueue_script( 'wc-network-orders', WC()->plugin_url() . '/assets/js/admin/network-orders' . $suffix . '.js', array( 'jquery', 'underscore' ), WC_VERSION, true );
wp_enqueue_script( 'wc-network-orders', WC()->plugin_url() . '/assets/js/admin/network-orders' . $suffix . '.js', array( 'jquery', 'underscore' ), $version, true );
$user = wp_get_current_user();
$blogs = get_blogs_of_user( $user->ID );

View File

@ -6,6 +6,8 @@
* @version 3.1.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -84,8 +86,9 @@ class WC_Admin_Exporters {
* Enqueue scripts.
*/
public function admin_scripts() {
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
wp_register_script( 'wc-product-export', WC()->plugin_url() . '/assets/js/admin/wc-product-export' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
$suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min';
$version = Constants::get_constant( 'WC_VERSION' );
wp_register_script( 'wc-product-export', WC()->plugin_url() . '/assets/js/admin/wc-product-export' . $suffix . '.js', array( 'jquery' ), $version );
wp_localize_script(
'wc-product-export',
'wc_product_export_params',

View File

@ -49,12 +49,12 @@ class WC_Admin_Help {
) . '</p>' .
'<p>' . sprintf(
/* translators: %s: Forum URL */
__( 'For further assistance with WooCommerce core you can use the <a href="%1$s">community forum</a>. If you need help with premium extensions sold by WooCommerce, please <a href="%2$s">use our helpdesk</a>.', 'woocommerce' ),
__( 'For further assistance with WooCommerce core, use the <a href="%1$s">community forum</a>. For help with premium extensions sold on WooCommerce.com, <a href="%2$s">open a support request at WooCommerce.com</a>.', 'woocommerce' ),
'https://wordpress.org/support/plugin/woocommerce',
'https://woocommerce.com/my-account/tickets/?utm_source=helptab&utm_medium=product&utm_content=tickets&utm_campaign=woocommerceplugin'
'https://woocommerce.com/my-account/create-a-ticket/?utm_source=helptab&utm_medium=product&utm_content=tickets&utm_campaign=woocommerceplugin'
) . '</p>' .
'<p>' . __( 'Before asking for help we recommend checking the system status page to identify any problems with your configuration.', 'woocommerce' ) . '</p>' .
'<p><a href="' . admin_url( 'admin.php?page=wc-status' ) . '" class="button button-primary">' . __( 'System status', 'woocommerce' ) . '</a> <a href="https://wordpress.org/support/plugin/woocommerce" class="button">' . __( 'Community forum', 'woocommerce' ) . '</a> <a href="https://woocommerce.com/my-account/tickets/?utm_source=helptab&utm_medium=product&utm_content=tickets&utm_campaign=woocommerceplugin" class="button">' . __( 'WooCommerce helpdesk', 'woocommerce' ) . '</a></p>',
'<p>' . __( 'Before asking for help, we recommend checking the system status page to identify any problems with your configuration.', 'woocommerce' ) . '</p>' .
'<p><a href="' . admin_url( 'admin.php?page=wc-status' ) . '" class="button button-primary">' . __( 'System status', 'woocommerce' ) . '</a> <a href="https://wordpress.org/support/plugin/woocommerce" class="button">' . __( 'Community forum', 'woocommerce' ) . '</a> <a href="https://woocommerce.com/my-account/create-a-ticket/?utm_source=helptab&utm_medium=product&utm_content=tickets&utm_campaign=woocommerceplugin" class="button">' . __( 'WooCommerce.com support', 'woocommerce' ) . '</a></p>',
)
);
@ -71,17 +71,6 @@ class WC_Admin_Help {
)
);
$screen->add_help_tab(
array(
'id' => 'woocommerce_education_tab',
'title' => __( 'Education', 'woocommerce' ),
'content' =>
'<h2>' . __( 'Education', 'woocommerce' ) . '</h2>' .
'<p>' . __( 'If you would like to learn about using WooCommerce from an expert, consider a WooCommerce course to further your education.', 'woocommerce' ) . '</p>' .
'<p><a href="https://docs.woocommerce.com/document/further-education/?utm_source=helptab&utm_medium=product&utm_content=edupartners&utm_campaign=woocommerceplugin" class="button button-primary">' . __( 'Further education', 'woocommerce' ) . '</a></p>',
)
);
$screen->add_help_tab(
array(
'id' => 'woocommerce_onboard_tab',

View File

@ -5,6 +5,8 @@
* @package WooCommerce/Admin
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -81,8 +83,9 @@ class WC_Admin_Importers {
* Register importer scripts.
*/
public function admin_scripts() {
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
wp_register_script( 'wc-product-import', WC()->plugin_url() . '/assets/js/admin/wc-product-import' . $suffix . '.js', array( 'jquery' ), WC_VERSION, true );
$suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min';
$version = Constants::get_constant( 'WC_VERSION' );
wp_register_script( 'wc-product-import', WC()->plugin_url() . '/assets/js/admin/wc-product-import' . $suffix . '.js', array( 'jquery' ), $version, true );
}
/**
@ -92,7 +95,7 @@ class WC_Admin_Importers {
* If we're on that screen, redirect to the custom one.
*/
public function product_importer() {
if ( defined( 'WP_LOAD_IMPORTERS' ) ) {
if ( Constants::is_defined( 'WP_LOAD_IMPORTERS' ) ) {
wp_safe_redirect( admin_url( 'edit.php?post_type=product&page=product_importer' ) );
exit;
}
@ -108,7 +111,7 @@ class WC_Admin_Importers {
* Register WordPress based importers.
*/
public function register_importers() {
if ( defined( 'WP_LOAD_IMPORTERS' ) ) {
if ( Constants::is_defined( 'WP_LOAD_IMPORTERS' ) ) {
add_action( 'import_start', array( $this, 'post_importer_compatibility' ) );
register_importer( 'woocommerce_product_csv', __( 'WooCommerce products (CSV)', 'woocommerce' ), __( 'Import <strong>products</strong> to your store via a csv file.', 'woocommerce' ), array( $this, 'product_importer' ) );
register_importer( 'woocommerce_tax_rate_csv', __( 'WooCommerce tax rates (CSV)', 'woocommerce' ), __( 'Import <strong>tax rates</strong> to your store via a csv file.', 'woocommerce' ), array( $this, 'tax_rates_importer' ) );

View File

@ -7,6 +7,8 @@
* @package WooCommerce/Admin/Meta Boxes
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -188,7 +190,7 @@ class WC_Admin_Meta_Boxes {
}
// Dont' save meta boxes for revisions or autosaves.
if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || is_int( wp_is_post_revision( $post ) ) || is_int( wp_is_post_autosave( $post ) ) ) {
if ( Constants::is_true( 'DOING_AUTOSAVE' ) || is_int( wp_is_post_revision( $post ) ) || is_int( wp_is_post_autosave( $post ) ) ) {
return;
}

View File

@ -6,6 +6,8 @@
* @version 3.4.0
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -36,6 +38,7 @@ class WC_Admin_Notices {
'no_secure_connection' => 'secure_connection_notice',
WC_PHP_MIN_REQUIREMENTS_NOTICE => 'wp_php_min_requirements_notice',
'maxmind_license_key' => 'maxmind_missing_license_key_notice',
'redirect_download_method' => 'redirect_download_method_notice',
);
/**
@ -46,8 +49,14 @@ class WC_Admin_Notices {
add_action( 'switch_theme', array( __CLASS__, 'reset_admin_notices' ) );
add_action( 'woocommerce_installed', array( __CLASS__, 'reset_admin_notices' ) );
add_action( 'wp_loaded', array( __CLASS__, 'add_redirect_download_method_notice' ) );
add_action( 'wp_loaded', array( __CLASS__, 'hide_notices' ) );
add_action( 'shutdown', array( __CLASS__, 'store_notices' ) );
// @TODO: This prevents Action Scheduler async jobs from storing empty list of notices during WC installation.
// That could lead to OBW not starting and 'Run setup wizard' notice not appearing in WP admin, which we want
// to avoid.
if ( ! WC_Install::is_new_install() || ! wc_is_running_from_async_action_scheduler() ) {
add_action( 'shutdown', array( __CLASS__, 'store_notices' ) );
}
if ( current_user_can( 'manage_woocommerce' ) ) {
add_action( 'admin_print_styles', array( __CLASS__, 'add_notices' ) );
@ -93,19 +102,31 @@ class WC_Admin_Notices {
* Show a notice.
*
* @param string $name Notice name.
* @param bool $force_save Force saving inside this method instead of at the 'shutdown'.
*/
public static function add_notice( $name ) {
public static function add_notice( $name, $force_save = false ) {
self::$notices = array_unique( array_merge( self::get_notices(), array( $name ) ) );
if ( $force_save ) {
// Adding early save to prevent more race conditions with notices.
self::store_notices();
}
}
/**
* Remove a notice from being displayed.
*
* @param string $name Notice name.
* @param bool $force_save Force saving inside this method instead of at the 'shutdown'.
*/
public static function remove_notice( $name ) {
public static function remove_notice( $name, $force_save = false ) {
self::$notices = array_diff( self::get_notices(), array( $name ) );
delete_option( 'woocommerce_admin_notice_' . $name );
if ( $force_save ) {
// Adding early save to prevent more race conditions with notices.
self::store_notices();
}
}
/**
@ -164,7 +185,7 @@ class WC_Admin_Notices {
return;
}
wp_enqueue_style( 'woocommerce-activation', plugins_url( '/assets/css/activation.css', WC_PLUGIN_FILE ), array(), WC_VERSION );
wp_enqueue_style( 'woocommerce-activation', plugins_url( '/assets/css/activation.css', WC_PLUGIN_FILE ), array(), Constants::get_constant( 'WC_VERSION' ) );
// Add RTL support.
wp_style_add_data( 'woocommerce-activation', 'rtl', 'replace' );
@ -209,9 +230,15 @@ class WC_Admin_Notices {
}
/**
* If we need to update, include a message with the update button.
* If we need to update the database, include a message with the DB update button.
*/
public static function update_notice() {
$screen = get_current_screen();
$screen_id = $screen ? $screen->id : '';
if ( WC()->is_wc_admin_active() && in_array( $screen_id, wc_get_screen_ids(), true ) ) {
return;
}
if ( WC_Install::needs_db_update() ) {
$next_scheduled_date = WC()->queue()->get_next( 'woocommerce_run_update_callback', null, 'woocommerce-db-updates' );
@ -415,6 +442,18 @@ class WC_Admin_Notices {
$integration_options = get_option( 'woocommerce_maxmind_geolocation_settings' );
if ( empty( $integration_options['license_key'] ) ) {
self::add_notice( 'maxmind_license_key' );
}
}
/**
* Add notice about Redirect-only download method, nudging user to switch to a different method instead.
*/
public static function add_redirect_download_method_notice() {
if ( 'redirect' === get_option( 'woocommerce_file_download_method' ) ) {
self::add_notice( 'redirect_download_method' );
} else {
self::remove_notice( 'redirect_download_method' );
}
}
@ -435,6 +474,20 @@ class WC_Admin_Notices {
include dirname( __FILE__ ) . '/views/html-notice-maxmind-license-key.php';
}
/**
* Notice about Redirect-Only download method.
*
* @since 4.0
*/
public static function redirect_download_method_notice() {
if ( apply_filters( 'woocommerce_hide_redirect_method_nag', get_user_meta( get_current_user_id(), 'dismissed_redirect_download_method_notice', true ) ) ) {
self::remove_notice( 'redirect_download_method' );
return;
}
include dirname( __FILE__ ) . '/views/html-notice-redirect-only-download.php';
}
/**
* Determine if the store is running SSL.
*

View File

@ -6,6 +6,8 @@
* @version 3.3.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -52,6 +54,7 @@ class WC_Admin_Post_Types {
// Uploads.
add_filter( 'upload_dir', array( $this, 'upload_dir' ) );
add_filter( 'wp_unique_filename', array( $this, 'update_filename' ), 10, 3 );
add_action( 'media_upload_downloadable_product', array( $this, 'media_upload_downloadable_product' ) );
// Hide template for CPT archive.
@ -294,7 +297,7 @@ class WC_Admin_Post_Types {
*/
public function bulk_and_quick_edit_save_post( $post_id, $post ) {
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
if ( Constants::is_true( 'DOING_AUTOSAVE' ) ) {
return $post_id;
}
@ -816,6 +819,65 @@ class WC_Admin_Post_Types {
return $pathdata;
}
/**
* Change filename for WooCommerce uploads and prepend unique chars for security.
*
* @param string $full_filename Original filename.
* @param string $ext Extension of file.
* @param string $dir Directory path.
*
* @return string New filename with unique hash.
* @since 4.0
*/
public function update_filename( $full_filename, $ext, $dir ) {
if ( ! isset( $_POST['type'] ) || ! 'downloadable_product' === $_POST['type'] ) { // WPCS: CSRF ok, input var ok.
return $full_filename;
}
if ( ! strpos( $dir, 'woocommerce_uploads' ) ) {
return $full_filename;
}
if ( 'no' === get_option( 'woocommerce_downloads_add_hash_to_filename' ) ) {
return $full_filename;
}
return $this->unique_filename( $full_filename, $ext );
}
/**
* Change filename to append random text.
*
* @param string $full_filename Original filename with extension.
* @param string $ext Extension.
*
* @return string Modified filename.
*/
public function unique_filename( $full_filename, $ext ) {
$ideal_random_char_length = 6; // Not going with a larger length because then downloaded filename will not be pretty.
$max_filename_length = 255; // Max file name length for most file systems.
$length_to_prepend = min( $ideal_random_char_length, $max_filename_length - strlen( $full_filename ) - 1 );
if ( 1 > $length_to_prepend ) {
return $full_filename;
}
$suffix = strtolower( wp_generate_password( $length_to_prepend, false, false ) );
$filename = $full_filename;
if ( strlen( $ext ) > 0 ) {
$filename = substr( $filename, 0, strlen( $filename ) - strlen( $ext ) );
}
$full_filename = str_replace(
$filename,
"$filename-$suffix",
$full_filename
);
return $full_filename;
}
/**
* Run a filter when uploading a downloadable product.
*/

View File

@ -6,6 +6,8 @@
* @version 3.4.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -128,7 +130,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
public static function output() {
global $current_section, $current_tab;
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
$suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min';
do_action( 'woocommerce_settings_start' );

View File

@ -8,6 +8,8 @@
* @version 2.6.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -197,11 +199,12 @@ class WC_Admin_Setup_Wizard {
public function enqueue_scripts() {
// Whether or not there is a pending background install of Jetpack.
$pending_jetpack = ! class_exists( 'Jetpack' ) && get_option( 'woocommerce_setup_background_installing_jetpack' );
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
$suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min';
$version = Constants::get_constant( 'WC_VERSION' );
wp_register_script( 'jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.70', true );
wp_register_script( 'selectWoo', WC()->plugin_url() . '/assets/js/selectWoo/selectWoo.full' . $suffix . '.js', array( 'jquery' ), '1.0.6' );
wp_register_script( 'wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array( 'jquery', 'selectWoo' ), WC_VERSION );
wp_register_script( 'wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array( 'jquery', 'selectWoo' ), $version );
wp_localize_script(
'wc-enhanced-select',
'wc_enhanced_select_params',
@ -221,10 +224,11 @@ class WC_Admin_Setup_Wizard {
'search_customers_nonce' => wp_create_nonce( 'search-customers' ),
)
);
wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_VERSION );
wp_enqueue_style( 'wc-setup', WC()->plugin_url() . '/assets/css/wc-setup.css', array( 'dashicons', 'install' ), WC_VERSION );
wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), $version );
wp_enqueue_style( 'wc-setup', WC()->plugin_url() . '/assets/css/wc-setup.css', array( 'dashicons', 'install' ), $version );
wp_style_add_data( 'wc-setup', 'rtl', 'replace' );
wp_register_script( 'wc-setup', WC()->plugin_url() . '/assets/js/admin/wc-setup' . $suffix . '.js', array( 'jquery', 'wc-enhanced-select', 'jquery-blockui', 'wp-util', 'jquery-tiptip', 'backbone', 'wc-backbone-modal' ), WC_VERSION );
wp_register_script( 'wc-setup', WC()->plugin_url() . '/assets/js/admin/wc-setup' . $suffix . '.js', array( 'jquery', 'wc-enhanced-select', 'jquery-blockui', 'wp-util', 'jquery-tiptip', 'backbone', 'wc-backbone-modal' ), $version );
wp_localize_script(
'wc-setup',
'wc_setup_params',
@ -2425,6 +2429,11 @@ class WC_Admin_Setup_Wizard {
}
Jetpack::maybe_set_version_option();
$jetpack = Jetpack::init();
// Older versions of jetpack may not have this method.
if ( method_exists( $jetpack, 'configure' ) ) {
$jetpack->configure();
}
$register_result = Jetpack::try_registration();
if ( is_wp_error( $register_result ) ) {
@ -2451,15 +2460,13 @@ class WC_Admin_Setup_Wizard {
*/
public function wc_setup_ready() {
// We've made it! Don't prompt the user to run the wizard again.
WC_Admin_Notices::remove_notice( 'install' );
WC_Admin_Notices::remove_notice( 'install', true );
$user_email = $this->get_current_user_email();
$videos_url = 'https://docs.woocommerce.com/document/woocommerce-guided-tour-videos/?utm_source=setupwizard&utm_medium=product&utm_content=videos&utm_campaign=woocommerceplugin';
$docs_url = 'https://docs.woocommerce.com/documentation/plugins/woocommerce/getting-started/?utm_source=setupwizard&utm_medium=product&utm_content=docs&utm_campaign=woocommerceplugin';
$help_text = sprintf(
/* translators: %1$s: link to videos, %2$s: link to docs */
__( 'Watch our <a href="%1$s" target="_blank">guided tour videos</a> to learn more about WooCommerce, and visit WooCommerce.com to learn more about <a href="%2$s" target="_blank">getting started</a>.', 'woocommerce' ),
$videos_url,
/* translators: %1$s: link to docs */
__( 'Visit WooCommerce.com to learn more about <a href="%1$s" target="_blank">getting started</a>.', 'woocommerce' ),
$docs_url
);
?>

View File

@ -6,6 +6,8 @@
* @version 2.2.0
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -95,7 +97,9 @@ class WC_Admin_Status {
* Show the logs page.
*/
public static function status_logs() {
if ( defined( 'WC_LOG_HANDLER' ) && 'WC_Log_Handler_DB' === WC_LOG_HANDLER ) {
$log_handler = Constants::get_constant( 'WC_LOG_HANDLER' );
if ( 'WC_Log_Handler_DB' === $log_handler ) {
self::status_logs_db();
} else {
self::status_logs_file();

View File

@ -127,6 +127,12 @@ class WC_Admin {
* For setup wizard, transient must be present, the user must have access rights, and we must ignore the network/bulk plugin updaters.
*/
public function admin_redirects() {
// Don't run this fn from Action Scheduler requests, as it would clear _wc_activation_redirect transient.
// That means OBW would never be shown.
if ( wc_is_running_from_async_action_scheduler() ) {
return;
}
// phpcs:disable WordPress.Security.NonceVerification.Recommended
// Nonced plugin install redirects (whitelisted).
if ( ! empty( $_GET['wc-install-plugin-redirect'] ) ) {

View File

@ -6,6 +6,8 @@
* @package WooCommerce/Admin
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -468,7 +470,7 @@ class WC_Helper {
$wc_screen_id = sanitize_title( __( 'WooCommerce', 'woocommerce' ) );
if ( $wc_screen_id . '_page_wc-addons' === $screen_id && isset( $_GET['section'] ) && 'helper' === $_GET['section'] ) {
wp_enqueue_style( 'woocommerce-helper', WC()->plugin_url() . '/assets/css/helper.css', array(), WC_VERSION );
wp_enqueue_style( 'woocommerce-helper', WC()->plugin_url() . '/assets/css/helper.css', array(), Constants::get_constant( 'WC_VERSION' ) );
}
}
@ -1582,7 +1584,7 @@ class WC_Helper {
}
$data = $updates->response['woocommerce/woocommerce.php'];
if ( version_compare( WC_VERSION, $data->new_version, '>=' ) ) {
if ( version_compare( Constants::get_constant( 'WC_VERSION' ), $data->new_version, '>=' ) ) {
return false;
}
@ -1665,7 +1667,7 @@ class WC_Helper {
* @param string $level Optional, defaults to info, valid levels: emergency|alert|critical|error|warning|notice|info|debug.
*/
public static function log( $message, $level = 'info' ) {
if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
if ( ! Constants::is_true( 'WP_DEBUG' ) ) {
return;
}

View File

@ -50,7 +50,7 @@ $row_class = apply_filters( 'woocommerce_admin_html_order_item_class', ! empt
<td class="item_cost" width="1%" data-sort-value="<?php echo esc_attr( $order->get_item_subtotal( $item, false, true ) ); ?>">
<div class="view">
<?php
echo wc_price( $order->get_item_total( $item, false, true ), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo wc_price( $order->get_item_subtotal( $item, false, true ), array( 'currency' => $order->get_currency() ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
?>
</div>
</td>

View File

@ -66,6 +66,14 @@ if ( wc_tax_enabled() ) {
do_action( 'woocommerce_admin_order_items_after_line_items', $order->get_id() );
?>
</tbody>
<tbody id="order_fee_line_items">
<?php
foreach ( $line_items_fee as $item_id => $item ) {
include 'html-order-fee.php';
}
do_action( 'woocommerce_admin_order_items_after_fees', $order->get_id() );
?>
</tbody>
<tbody id="order_shipping_line_items">
<?php
$shipping_methods = WC()->shipping() ? WC()->shipping()->load_shipping_methods() : array();
@ -75,14 +83,6 @@ if ( wc_tax_enabled() ) {
do_action( 'woocommerce_admin_order_items_after_shipping', $order->get_id() );
?>
</tbody>
<tbody id="order_fee_line_items">
<?php
foreach ( $line_items_fee as $item_id => $item ) {
include 'html-order-fee.php';
}
do_action( 'woocommerce_admin_order_items_after_fees', $order->get_id() );
?>
</tbody>
<tbody id="order_refunds">
<?php
$refunds = $order->get_refunds();
@ -107,7 +107,7 @@ if ( wc_tax_enabled() ) {
<li><strong><?php esc_html_e( 'Coupon(s)', 'woocommerce' ); ?></strong></li>
<?php
foreach ( $coupons as $item_id => $item ) :
$post_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' LIMIT 1;", $item->get_code() ) ); // phpcs:disable WordPress.WP.GlobalVariablesOverride.OverrideProhibited
$post_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' LIMIT 1;", $item->get_code() ) ); // phpcs:disable WordPress.WP.GlobalVariablesOverride.Prohibited
$class = $order->is_editable() ? 'code editable' : 'code';
?>
<li class="<?php echo esc_attr( $class ); ?>">
@ -143,15 +143,31 @@ if ( wc_tax_enabled() ) {
</div>
<?php endif; ?>
<table class="wc-order-totals">
<?php if ( 0 < $order->get_total_discount() ) : ?>
<tr>
<td class="label"><?php esc_html_e( 'Discount:', 'woocommerce' ); ?></td>
<td class="label"><?php esc_html_e( 'Items Subtotal:', 'woocommerce' ); ?></td>
<td width="1%"></td>
<td class="total">
<?php echo wc_price( $order->get_subtotal(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?>
</td>
</tr>
<?php if ( 0 < $order->get_total_discount() ) : ?>
<tr>
<td class="label"><?php esc_html_e( 'Coupon(s):', 'woocommerce' ); ?></td>
<td width="1%"></td>
<td class="total">-
<?php echo wc_price( $order->get_total_discount(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?>
</td>
</tr>
<?php endif; ?>
<?php if ( 0 < $order->get_total_fees() ) : ?>
<tr>
<td class="label"><?php esc_html_e( 'Fees:', 'woocommerce' ); ?></td>
<td width="1%"></td>
<td class="total">
<?php echo wc_price( $order->get_total_fees(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?>
</td>
</tr>
<?php endif; ?>
<?php do_action( 'woocommerce_admin_order_totals_after_discount', $order->get_id() ); ?>
@ -160,14 +176,7 @@ if ( wc_tax_enabled() ) {
<td class="label"><?php esc_html_e( 'Shipping:', 'woocommerce' ); ?></td>
<td width="1%"></td>
<td class="total">
<?php
$refunded = $order->get_total_shipping_refunded();
if ( $refunded > 0 ) {
echo '<del>' . wp_strip_all_tags( wc_price( $order->get_shipping_total(), array( 'currency' => $order->get_currency() ) ) ) . '</del> <ins>' . wc_price( $order->get_shipping_total() - $refunded, array( 'currency' => $order->get_currency() ) ) . '</ins>'; // WPCS: XSS ok.
} else {
echo wc_price( $order->get_shipping_total(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok.
}
?>
<?php echo wc_price( $order->get_shipping_total(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?>
</td>
</tr>
<?php endif; ?>
@ -180,14 +189,7 @@ if ( wc_tax_enabled() ) {
<td class="label"><?php echo esc_html( $tax_total->label ); ?>:</td>
<td width="1%"></td>
<td class="total">
<?php
$refunded = $order->get_total_tax_refunded_by_rate_id( $tax_total->rate_id );
if ( $refunded > 0 ) {
echo '<del>' . wp_strip_all_tags( $tax_total->formatted_amount ) . '</del> <ins>' . wc_price( WC_Tax::round( $tax_total->amount, wc_get_price_decimals() ) - WC_Tax::round( $refunded, wc_get_price_decimals() ), array( 'currency' => $order->get_currency() ) ) . '</ins>'; // WPCS: XSS ok.
} else {
echo wp_kses_post( $tax_total->formatted_amount );
}
?>
<?php echo wc_price( $tax_total->amount, array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?>
</td>
</tr>
<?php endforeach; ?>
@ -196,26 +198,60 @@ if ( wc_tax_enabled() ) {
<?php do_action( 'woocommerce_admin_order_totals_after_tax', $order->get_id() ); ?>
<tr>
<td class="label"><?php esc_html_e( 'Total', 'woocommerce' ); ?>:</td>
<td class="label"><?php esc_html_e( 'Order Total', 'woocommerce' ); ?>:</td>
<td width="1%"></td>
<td class="total">
<?php echo $order->get_formatted_order_total(); // WPCS: XSS ok. ?>
<?php echo wc_price( $order->get_total(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?>
</td>
</tr>
<?php do_action( 'woocommerce_admin_order_totals_after_total', $order->get_id() ); ?>
</table>
<?php if ( $order->get_total_refunded() ) : ?>
<div class="clear"></div>
<?php if ( in_array( $order->get_status(), array( 'processing', 'completed', 'refunded' ) ) && ! empty( $order->get_date_paid() ) ) : ?>
<table class="wc-order-totals" style="border-top: 1px solid #999; margin-top:12px; padding-top:12px">
<tr>
<td class="label"><?php esc_html_e( 'Paid By Customer', 'woocommerce' ); ?>:</td>
<td width="1%"></td>
<td class="total">
<?php echo wc_price( $order->get_total(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?>
</td>
</tr>
</table>
<div class="clear"></div>
<?php endif; ?>
<?php if ( $order->get_total_refunded() ) : ?>
<table class="wc-order-totals" style="border-top: 1px solid #999; margin-top:12px; padding-top:12px">
<tr>
<td class="label refunded-total"><?php esc_html_e( 'Refunded', 'woocommerce' ); ?>:</td>
<td width="1%"></td>
<td class="total refunded-total">-<?php echo wc_price( $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?></td>
</tr>
<?php endif; ?>
<?php do_action( 'woocommerce_admin_order_totals_after_refunded', $order->get_id() ); ?>
<?php do_action( 'woocommerce_admin_order_totals_after_refunded', $order->get_id() ); ?>
<tr>
<td class="label"><?php esc_html_e( 'Net Total', 'woocommerce' ); ?>:</td>
<td width="1%"></td>
<td class="total">
<?php echo wc_price( $order->get_total() - $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); // WPCS: XSS ok. ?>
</td>
</tr>
</table>
<?php endif; ?>
<div class="clear"></div>
<table class="wc-order-totals">
<?php do_action( 'woocommerce_admin_order_totals_after_total', $order->get_id() ); ?>
</table>
<div class="clear"></div>
</div>
<div class="wc-order-data-row wc-order-bulk-actions wc-order-data-row-toggle">

View File

@ -0,0 +1,294 @@
<?php
/**
* WooCommerce: Db update note.
*
* Adds a note to complete the WooCommerce db update after the upgrade in the WC Admin context.
*
* @package WooCommerce
*/
defined( 'ABSPATH' ) || exit;
use \Automattic\Jetpack\Constants;
use \Automattic\WooCommerce\Admin\Notes\WC_Admin_Note;
/**
* WC_Notes_Run_Db_Update.
*/
class WC_Notes_Run_Db_Update {
const NOTE_NAME = 'wc-update-db-reminder';
/**
* Attach hooks.
*/
public function __construct() {
// If the old notice gets dismissed, also hide this new one.
add_action( 'woocommerce_hide_update_notice', array( __CLASS__, 'set_notice_actioned' ) );
// Not using Jetpack\Constants here as it can run before 'plugin_loaded' is done.
if ( defined( 'DOING_AJAX' ) && DOING_AJAX
|| defined( 'DOING_CRON' ) && DOING_CRON
|| ! is_admin() ) {
return;
}
add_action( 'current_screen', array( __CLASS__, 'show_reminder' ) );
}
/**
* Get current notice id from the database.
*
* Retrieves the first notice of this type.
*
* @return int|void Note id or null in case no note was found.
*/
private static function get_current_notice() {
try {
$data_store = \WC_Data_Store::load( 'admin-note' );
} catch ( Exception $e ) {
return;
}
$note_ids = $data_store->get_notes_with_name( self::NOTE_NAME );
if ( empty( $note_ids ) ) {
return;
}
return current( $note_ids );
}
/**
* Set this notice to an actioned one, so that it's no longer displayed.
*/
public static function set_notice_actioned() {
$note_id = self::get_current_notice();
if ( ! $note_id ) {
return;
}
$note = new WC_Admin_Note( $note_id );
$note->set_status( WC_Admin_Note::E_WC_ADMIN_NOTE_ACTIONED );
$note->save();
}
/**
* Check whether the note is up to date for a fresh display.
*
* The check tests if
* - 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 string $update_url URL to check the note against.
* @return bool
*/
private static function note_up_to_date( $note, $update_url ) {
$actions = $note->get_actions();
if ( 2 === count( array_intersect( wp_list_pluck( $actions, 'name' ), array( 'update-db_run', 'update-db_learn-more' ) ) )
&& in_array( $update_url, wp_list_pluck( $actions, 'query' ) ) ) {
return true;
}
return false;
}
/**
* Create and set up the first (out of 3) 'Database update needed' notice and store it in the database.
*
* If a $note_id is given, the method updates the note instead of creating a new one.
*
* @param integer $note_id Note db record to update.
* @return int Created/Updated note id
*/
private static function update_needed_notice( $note_id = null ) {
$update_url = html_entity_decode(
wp_nonce_url(
add_query_arg( 'do_update_woocommerce', 'true', admin_url( 'admin.php?page=wc-settings' ) ),
'wc_db_update',
'wc_db_update_nonce'
)
);
if ( $note_id ) {
$note = new WC_Admin_Note( $note_id );
} else {
$note = new WC_Admin_Note();
}
// 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, $update_url ) ) {
return $note_id;
}
$note->set_title( __( 'WooCommerce database update required', 'woocommerce' ) );
$note->set_content(
__( 'WooCommerce has been updated! To keep things running smoothly, we have to update your database to the newest version.', 'woocommerce' )
/* 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_icon( 'info' );
$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 );
// Set new actions.
$note->clear_actions();
$note->add_action(
'update-db_run',
__( 'Update WooCommerce Database', 'woocommerce' ),
$update_url,
'unactioned',
true
);
$note->add_action(
'update-db_learn-more',
__( 'Learn more about updates', 'woocommerce' ),
'https://docs.woocommerce.com/document/how-to-update-woocommerce/',
'unactioned',
false
);
return $note->save();
}
/**
* Update the existing note with $note_id with information about the db upgrade being in progress.
*
* This is the second out of 3 notices displayed to the user.
*
* @param int $note_id Note id to update.
*/
private static function update_in_progress_notice( $note_id ) {
// Same actions as in includes/admin/views/html-notice-updating.php.
$pending_actions_url = admin_url( 'admin.php?page=wc-status&tab=action-scheduler&s=woocommerce_run_update&status=pending' );
$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->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' ) );
$note->clear_actions();
$note->add_action(
'update-db_see-progress',
$cron_cta,
$pending_actions_url,
'unactioned',
false
);
$note->save();
}
/**
* Update the existing note with $note_id with information that db upgrade is done.
*
* This is the last notice (3 out of 3 notices) displayed to the user.
*
* @param int $note_id Note id to update.
*/
private static function update_done_notice( $note_id ) {
$hide_notices_url = html_entity_decode( // to convert &amp;s to normal &, otherwise produces invalid link.
wp_nonce_url(
add_query_arg(
'wc-hide-notice',
'update',
admin_url( 'admin.php?page=wc-settings' )
),
'woocommerce_hide_notices_nonce',
'_wc_notice_nonce'
)
);
$note = new WC_Admin_Note( $note_id );
$note->set_title( __( 'WooCommerce database update done', 'woocommerce' ) );
$note->set_content( __( 'WooCommerce database update complete. Thank you for updating to the latest version!', 'woocommerce' ) );
$actions = $note->get_actions();
if ( ! in_array( 'update-db_done', wp_list_pluck( $actions, 'name' ) ) ) {
$note->clear_actions();
$note->add_action(
'update-db_done',
__( 'Thanks!', 'woocommerce' ),
$hide_notices_url,
'actioned',
true
);
$note->save();
}
}
/**
* Return true if db update notice should be shown, false otherwise.
*
* If the db needs an update, the notice should be always shown.
* If the db does not need an update, but the notice has *not* been actioned (i.e. after the db update, when
* store owner hasn't acknowledged the successful db update), still show the notice.
* If the db does not need an update, and the notice has been actioned, then notice should *not* be shown.
* The same is true if the db does not need an update and the notice does not exist.
*
* @return bool
*/
private static function should_show_notice() {
if ( ! \WC_Install::needs_db_update() ) {
try {
$data_store = \WC_Data_Store::load( 'admin-note' );
} catch ( Exception $e ) {
// Bail out in case of incorrect use.
return false;
}
$note_ids = $data_store->get_notes_with_name( self::NOTE_NAME );
if ( ! empty( $note_ids ) ) {
// Db update not needed && note actioned -> don't show it.
$note = new WC_Admin_Note( $note_ids[0] );
if ( $note::E_WC_ADMIN_NOTE_ACTIONED === $note->get_status() ) {
return false;
}
} else {
// Db update not needed && note does not exist -> don't show it.
return false;
}
}
return true;
}
/**
* Prepare the correct content of the db update note to be displayed by WC Admin.
*
* This one gets called on each page load, so try to bail quickly.
*/
public static function show_reminder() {
if ( ! self::should_show_notice() ) {
return;
}
$note_id = self::get_current_notice();
if ( \WC_Install::needs_db_update() && empty( $note_id ) ) {
// Db needs update && no notice exists -> create one.
$note_id = self::update_needed_notice();
}
if ( \WC_Install::needs_db_update() ) {
$next_scheduled_date = WC()->queue()->get_next( 'woocommerce_run_update_callback', null, 'woocommerce-db-updates' );
if ( $next_scheduled_date || ! empty( $_GET['do_update_woocommerce'] ) ) { // WPCS: input var ok, CSRF ok.
self::update_in_progress_notice( $note_id );
} else {
self::update_needed_notice( $note_id );
}
} else {
\WC_Install::update_db_version();
self::update_done_notice( $note_id );
}
}
}

View File

@ -6,6 +6,8 @@
* @version 3.2.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -171,7 +173,7 @@ class WC_Plugin_Updates {
*/
/**
* Get active plugins that have a tested version lower than the input version.
* Get installed plugins that have a tested version lower than the input version.
*
* In case of testing major version compatibility and if current WC version is >= major version part
* of the $new_version, no plugins are returned, even if they don't explicitly declare compatibility
@ -192,7 +194,7 @@ class WC_Plugin_Updates {
}
if ( 'major' === $release ) {
$current_version_parts = explode( '.', WC_VERSION );
$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', '>=' ) ) {

View File

@ -6,6 +6,8 @@
* @version 3.2.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -45,7 +47,7 @@ class WC_Plugins_Screen_Updates extends WC_Plugin_Updates {
$this->major_untested_plugins = $this->get_untested_plugins( $response->new_version, 'major' );
$this->minor_untested_plugins = $this->get_untested_plugins( $response->new_version, 'minor' );
$current_version_parts = explode( '.', WC_VERSION );
$current_version_parts = explode( '.', Constants::get_constant( 'WC_VERSION' ) );
$new_version_parts = explode( '.', $this->new_version );
// If user has already moved to the minor version, we don't need to flag up anything.
@ -109,7 +111,7 @@ class WC_Plugins_Screen_Updates extends WC_Plugin_Updates {
$upgrade_notice = '';
foreach ( $check_for_notices as $check_version ) {
if ( version_compare( WC_VERSION, $check_version, '>' ) ) {
if ( version_compare( Constants::get_constant( 'WC_VERSION' ), $check_version, '>' ) ) {
continue;
}

View File

@ -121,7 +121,7 @@ class WC_Settings_Accounts extends WC_Settings_Page {
array(
'title' => __( 'Personal data removal', 'woocommerce' ),
'desc' => __( 'Allow personal data to be removed in bulk from orders', 'woocommerce' ),
'desc_tip' => __( 'Adds an option to the orders screen for removing personal in bulk. Note that removing personal data cannot be undone.', 'woocommerce' ),
'desc_tip' => __( 'Adds an option to the orders screen for removing personal data in bulk. Note that removing personal data cannot be undone.', 'woocommerce' ),
'id' => 'woocommerce_allow_bulk_remove_personal_data',
'type' => 'checkbox',
'checkboxgroup' => 'start',

View File

@ -8,6 +8,8 @@
* @version 2.1.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
@ -41,7 +43,7 @@ if ( ! class_exists( 'WC_Settings_Integrations', false ) ) :
$sections = array();
if ( ! defined( 'WC_INSTALLING' ) ) {
if ( ! Constants::is_defined( 'WC_INSTALLING' ) ) {
$integrations = WC()->integrations->get_integrations();
if ( ! $current_section && ! empty( $integrations ) ) {

View File

@ -218,7 +218,7 @@ class WC_Settings_Products extends WC_Settings_Page {
array(
'title' => __( 'File download method', 'woocommerce' ),
'desc' => sprintf(
'desc_tip' => sprintf(
/* translators: 1: X-Accel-Redirect 2: X-Sendfile 3: mod_xsendfile */
__( 'Forcing downloads will keep URLs hidden, but some servers may serve large files unreliably. If supported, %1$s / %2$s can be used to serve downloads instead (server requires %3$s).', 'woocommerce' ),
'<code>X-Accel-Redirect</code>',
@ -230,11 +230,15 @@ class WC_Settings_Products extends WC_Settings_Page {
'class' => 'wc-enhanced-select',
'css' => 'min-width:300px;',
'default' => 'force',
'desc_tip' => true,
'desc' => sprintf(
// translators: Link to WooCommerce Docs.
__( "If you are using X-Accel-Redirect download method along with NGINX server, make sure that you have applied settings as described in <a href='%s'>Digital/Downloadable Product Handling</a> guide.", 'woocommerce' ),
'https://docs.woocommerce.com/document/digital-downloadable-product-handling#nginx-setting'
),
'options' => array(
'force' => __( 'Force downloads', 'woocommerce' ),
'xsendfile' => __( 'X-Accel-Redirect/X-Sendfile', 'woocommerce' ),
'redirect' => __( 'Redirect only', 'woocommerce' ),
'redirect' => apply_filters( 'woocommerce_redirect_only_method_is_secure', false ) ? __( 'Redirect only', 'woocommerce' ) : __( 'Redirect only (Insecure)', 'woocommerce' ),
),
'autoload' => false,
),
@ -260,6 +264,19 @@ class WC_Settings_Products extends WC_Settings_Page {
'autoload' => false,
),
array(
'title' => __( 'Filename', 'woocommerce' ),
'desc' => __( 'Append a unique string to filename for security', 'woocommerce' ),
'id' => 'woocommerce_downloads_add_hash_to_filename',
'type' => 'checkbox',
'default' => 'yes',
'desc_tip' => sprintf(
// translators: Link to WooCommerce Docs.
__( "Not required if your download directory is protected. <a href='%s'>See this guide</a> for more details. Files already uploaded will not be affected.", 'woocommerce' ),
'https://docs.woocommerce.com/document/digital-downloadable-product-handling#unique-string'
),
),
array(
'type' => 'sectionend',
'id' => 'digital_download_options',

View File

@ -6,6 +6,8 @@
* @version 2.6.0
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
if ( class_exists( 'WC_Settings_Shipping', false ) ) {
@ -49,7 +51,7 @@ class WC_Settings_Shipping extends WC_Settings_Page {
'classes' => __( 'Shipping classes', 'woocommerce' ),
);
if ( ! defined( 'WC_INSTALLING' ) ) {
if ( ! Constants::is_defined( 'WC_INSTALLING' ) ) {
// Load shipping methods so we can show any global options they may have.
$shipping_methods = WC()->shipping()->load_shipping_methods();

View File

@ -35,8 +35,8 @@ defined( 'ABSPATH' ) || exit;
</th>
<td class="forminp">
<?php
$curent_user_id = get_current_user_id();
$user_id = ! empty( $key_data['user_id'] ) ? absint( $key_data['user_id'] ) : $curent_user_id;
$current_user_id = get_current_user_id();
$user_id = ! empty( $key_data['user_id'] ) ? absint( $key_data['user_id'] ) : $current_user_id;
$user = get_user_by( 'id', $user_id );
$user_string = sprintf(
/* translators: 1: user display name 2: user ID 3: user email */

View File

@ -82,6 +82,94 @@ $untested_plugins = $plugin_updates->get_untested_plugins( WC()->version, 'min
?>
</td>
</tr>
<tr>
<td data-export-label="WC Blocks Version"><?php esc_html_e( 'WooCommerce Blocks package', 'woocommerce' ); ?>:</td>
<td class="help"><?php echo wc_help_tip( esc_html__( 'The WooCommerce Blocks package running on your site.', 'woocommerce' ) ); ?></td>
<td>
<?php
if ( class_exists( '\Automattic\WooCommerce\Blocks\Package' ) ) {
$version = \Automattic\WooCommerce\Blocks\Package::get_version();
$path = \Automattic\WooCommerce\Blocks\Package::get_path(); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
} else {
$version = null;
}
if ( ! is_null( $version ) ) {
echo '<mark class="yes"><span class="dashicons dashicons-yes"></span> ' . esc_html( $version ) . ' <code class="private">' . esc_html( $path ) . '</code></mark> ';
} else {
echo '<mark class="error"><span class="dashicons dashicons-warning"></span> ' . esc_html__( 'Unable to detect the Blocks package.', 'woocommerce' ) . '</mark>';
}
?>
</td>
</tr>
<tr>
<td data-export-label="Action Scheduler Version"><?php esc_html_e( 'Action Scheduler package', 'woocommerce' ); ?>:</td>
<td class="help"><?php echo wc_help_tip( esc_html__( 'Action Scheduler package running on your site.', 'woocommerce' ) ); ?></td>
<td>
<?php
if ( class_exists( 'ActionScheduler_Versions' ) && class_exists( 'ActionScheduler' ) ) {
$version = ActionScheduler_Versions::instance()->latest_version();
$path = ActionScheduler::plugin_path( '' ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
} else {
$version = null;
}
if ( ! is_null( $version ) ) {
echo '<mark class="yes"><span class="dashicons dashicons-yes"></span> ' . esc_html( $version ) . ' <code class="private">' . esc_html( $path ) . '</code></mark> ';
} else {
echo '<mark class="error"><span class="dashicons dashicons-warning"></span> ' . esc_html__( 'Unable to detect the Action Scheduler package.', 'woocommerce' ) . '</mark>';
}
?>
</td>
</tr>
<tr>
<td data-export-label="WC Admin Version"><?php esc_html_e( 'WooCommerce Admin package', 'woocommerce' ); ?>:</td>
<td class="help"><?php echo wc_help_tip( esc_html__( 'The WooCommerce Admin package running on your site.', 'woocommerce' ) ); ?></td>
<td>
<?php
$wc_admin_path = null;
if ( defined( 'WC_ADMIN_VERSION_NUMBER' ) ) {
// Plugin version of WC Admin.
$version = WC_ADMIN_VERSION_NUMBER;
$package_active = false;
} elseif ( class_exists( '\Automattic\WooCommerce\Admin\Composer\Package' ) ) {
if ( WC()->is_wc_admin_active() ) {
// Fully active package version of WC Admin.
$version = \Automattic\WooCommerce\Admin\Composer\Package::get_active_version();
$package_active = \Automattic\WooCommerce\Admin\Composer\Package::is_package_active();
} else {
// with WP version < 5.3, package is present, but inactive.
$version = sprintf(
/* translators: %s: Version number of wc-admin package */
__( 'Inactive %s', 'woocommerce' ),
\Automattic\WooCommerce\Admin\Composer\Package::VERSION
);
$package_active = false;
}
$wc_admin_path = \Automattic\WooCommerce\Admin\Composer\Package::get_path();
} else {
$version = null;
}
if ( ! is_null( $version ) ) {
if ( ! isset( $wc_admin_path ) ) {
if ( defined( 'WC_ADMIN_PLUGIN_FILE' ) ) {
$wc_admin_path = dirname( WC_ADMIN_PLUGIN_FILE );
} else {
$wc_admin_path = __( 'Active Plugin', 'woocommerce' );
}
}
if ( WC()->is_wc_admin_active() ) {
echo '<mark class="yes"><span class="dashicons dashicons-yes"></span> ' . esc_html( $version ) . ' <code class="private">' . esc_html( $wc_admin_path ) . '</code></mark> ';
} else {
echo '<span class="dashicons dashicons-no-alt"></span> ' . esc_html( $version ) . ' <code class="private">' . esc_html( $wc_admin_path ) . '</code> ';
}
} else {
echo '<mark class="error"><span class="dashicons dashicons-warning"></span> ' . esc_html__( 'Unable to detect the WC Admin package.', 'woocommerce' ) . '</mark>';
}
?>
</td>
</tr>
<tr>
<td data-export-label="Log Directory Writable"><?php esc_html_e( 'Log directory writable', 'woocommerce' ); ?>:</td>
<td class="help"><?php echo wc_help_tip( esc_html__( 'Several WooCommerce extensions can write logs which makes debugging problems easier. The directory must be writable for this to happen.', 'woocommerce' ) ); /* phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped */ ?></td>

View File

@ -0,0 +1,31 @@
<?php
/**
* Admin View: Notice - Redirect only download method is selected.
*
* @package WooCommerce\Admin\Notices
*/
defined( 'ABSPATH' ) || exit;
?>
<div class="updated woocommerce-message">
<a class="woocommerce-message-close notice-dismiss" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wc-hide-notice', 'redirect_download_method' ), 'woocommerce_hide_notices_nonce', '_wc_notice_nonce' ) ); ?>"><?php esc_html_e( 'Dismiss', 'woocommerce' ); ?></a>
<p>
<?php
echo wp_kses_post(
sprintf(
/* translators: %s: Link to settings page. */
__( 'Your store is configured to serve digital products using "Redirect only" method. This method is deprecated, <a href="%s">please switch to a different method instead.</a><br><em>If you use a remote server for downloadable files (such as Google Drive, Dropbox, Amazon S3), the right method will automatically be used, so select any of the other options to make this notice go away.</em>', 'woocommerce' ),
add_query_arg(
array(
'page' => 'wc-settings',
'tab' => 'products',
'section' => 'downloadable',
),
admin_url( 'admin.php' )
)
)
);
?>
</p>
</div>

View File

@ -5,10 +5,12 @@
* @package WooCommerce/admin
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
$pending_actions_url = admin_url( 'admin.php?page=wc-status&tab=action-scheduler&s=wc_update_product_lookup_tables&status=pending' );
$cron_disabled = defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON;
$cron_disabled = Constants::is_true( 'DISABLE_WP_CRON' );
$cron_cta = $cron_disabled ? __( 'You can manually run queued updates here.', 'woocommerce' ) : __( 'View progress &rarr;', 'woocommerce' );
?>
<div id="message" class="updated woocommerce-message">

View File

@ -5,12 +5,14 @@
* @package WooCommerce\Admin
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$pending_actions_url = admin_url( 'admin.php?page=wc-status&tab=action-scheduler&s=woocommerce_run_update&status=pending' );
$cron_disabled = defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON;
$cron_disabled = Constants::is_true( 'DISABLE_WP_CRON' );
$cron_cta = $cron_disabled ? __( 'You can manually run queued updates here.', 'woocommerce' ) : __( 'View progress &rarr;', 'woocommerce' );
?>
<div id="message" class="updated woocommerce-message wc-connect">

View File

@ -6,6 +6,8 @@
* @package WooCommerce/Classes
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -62,7 +64,7 @@ class WC_AJAX {
header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
header( 'X-Robots-Tag: noindex' );
status_header( 200 );
} elseif ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
} elseif ( Constants::is_true( 'WP_DEBUG' ) ) {
headers_sent( $file, $line );
trigger_error( "wc_ajax_headers cannot set headers - headers already sent by {$file} on line {$line}", E_USER_NOTICE ); // @codingStandardsIgnoreLine
}
@ -744,7 +746,7 @@ class WC_AJAX {
wp_die();
}
echo esc_html( $data_store->create_all_product_variations( $product, WC_MAX_LINKED_VARIATIONS ) );
echo esc_html( $data_store->create_all_product_variations( $product, Constants::get_constant( 'WC_MAX_LINKED_VARIATIONS' ) ) );
$data_store->sort_all_product_variations( $product->get_id() );
wp_die();

View File

@ -90,6 +90,8 @@ class WC_Autoloader {
$path = $this->include_path . 'log-handlers/';
} elseif ( 0 === strpos( $class, 'wc_integration' ) ) {
$path = $this->include_path . 'integrations/' . substr( str_replace( '_', '-', $class ), 15 ) . '/';
} elseif ( 0 === strpos( $class, 'wc_notes_' ) ) {
$path = $this->include_path . 'admin/notes/';
}
if ( empty( $path ) || ! $this->load_file( $path . $file ) ) {

View File

@ -6,6 +6,8 @@
* @package WooCommerce/Classes
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'WC_Background_Process', false ) ) {
@ -56,7 +58,7 @@ class WC_Background_Emailer extends WC_Background_Process {
try {
WC_Emails::send_queued_transactional_email( $callback['filter'], $callback['args'] );
} catch ( Exception $e ) {
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
if ( Constants::is_true( 'WP_DEBUG' ) ) {
trigger_error( 'Transactional email triggered fatal error for callback ' . esc_html( $callback['filter'] ), E_USER_WARNING ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
}
}

View File

@ -272,7 +272,7 @@ class WC_Checkout {
foreach ( $fields as $single_field_type => $field ) {
if ( empty( $field['label'] ) && ! empty( $field['placeholder'] ) ) {
$this->fields[ $field_type ][ $single_field_type ]['label'] = $field['placeholder'];
$this->fields[ $field_type ][ $single_field_type ]['label_class'] = 'screen-reader-text';
$this->fields[ $field_type ][ $single_field_type ]['label_class'] = array( 'screen-reader-text' );
}
}
}

View File

@ -350,33 +350,47 @@ class WC_Countries {
/**
* Gets an array of countries in the EU.
*
* MC (monaco) and IM (isle of man, part of UK) also use VAT.
*
* @param string $type Type of countries to retrieve. Blank for EU member countries. eu_vat for EU VAT countries.
* @param string $deprecated Function used to return VAT countries based on this.
* @return string[]
*/
public function get_european_union_countries( $type = '' ) {
$countries = array( 'AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GB', 'GR', 'HU', 'HR', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK' );
public function get_european_union_countries( $deprecated = '' ) {
$countries = array( 'AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FI', 'FR', 'GR', 'HU', 'HR', 'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL', 'PL', 'PT', 'RO', 'SE', 'SI', 'SK' );
if ( 'eu_vat' === $type ) {
$countries[] = 'MC';
$countries[] = 'IM';
if ( ! empty( $deprecated ) ) {
wc_deprecated_argument( 'type', '4.0.0', 'Use the WC_Countries::get_vat_countries method instead.' );
$countries = $this->get_vat_countries();
}
return apply_filters( 'woocommerce_european_union_countries', $countries, $type );
return apply_filters( 'woocommerce_european_union_countries', $countries, $deprecated );
}
/**
* Gets an array of Non-EU countries that use VAT as the Local name for their taxes based on this list - https://en.wikipedia.org/wiki/Value-added_tax#Non-European_Union_countries
*
* @deprecated 4.0.0
* @since 3.9.0
* @return string[]
*/
public function countries_using_vat() {
wc_deprecated_function( 'countries_using_vat', '4.0', 'WC_Countries::get_vat_countries' );
$countries = array( 'AL', 'AR', 'AZ', 'BS', 'BH', 'BY', 'BB', 'BO', 'EG', 'ET', 'CL', 'CO', 'EC', 'SV', 'FJ', 'GM', 'GH', 'GT', 'IN', 'IR', 'IL', 'KZ', 'MU', 'MK', 'MX', 'MD', 'MN', 'ME', 'NA', 'NP', 'NG', 'PS', 'PY', 'RU', 'RW', 'KN', 'SA', 'RS', 'ZA', 'KR', 'LK', 'TH', 'TR', 'UA', 'UY', 'UZ', 'VE', 'VN', 'AE' );
return apply_filters( 'woocommerce_countries_using_vat', $countries );
}
/**
* Gets an array of countries using VAT.
*
* @since 4.0.0
* @return string[] of country codes.
*/
public function get_vat_countries() {
$eu_countries = $this->get_european_union_countries();
$vat_countries = array( 'AE', 'AL', 'AR', 'AZ', 'BB', 'BH', 'BO', 'BS', 'BY', 'CL', 'CO', 'EC', 'EG', 'ET', 'FJ', 'GB', 'GH', 'GM', 'GT', 'IL', 'IM', 'IN', 'IR', 'KN', 'KR', 'KZ', 'LK', 'MC', 'MD', 'ME', 'MK', 'MN', 'MU', 'MX', 'NA', 'NG', 'NO', 'NP', 'PS', 'PY', 'RS', 'RU', 'RW', 'SA', 'SV', 'TH', 'TR', 'UA', 'UY', 'UZ', 'VE', 'VN', 'ZA' );
return apply_filters( 'woocommerce_vat_countries', array_merge( $eu_countries, $vat_countries ) );
}
/**
* Gets the correct string for shipping - either 'to the' or 'to'.
*
@ -411,7 +425,7 @@ class WC_Countries {
* @return string
*/
public function tax_or_vat() {
$return = in_array( $this->get_base_country(), array_merge( $this->get_european_union_countries( 'eu_vat' ), array( 'NO' ), $this->countries_using_vat() ), true ) ? __( 'VAT', 'woocommerce' ) : __( 'Tax', 'woocommerce' );
$return = in_array( $this->get_base_country(), $this->get_vat_countries(), true ) ? __( 'VAT', 'woocommerce' ) : __( 'Tax', 'woocommerce' );
return apply_filters( 'woocommerce_countries_tax_or_vat', $return );
}
@ -422,7 +436,7 @@ class WC_Countries {
* @return string
*/
public function inc_tax_or_vat() {
$return = in_array( $this->get_base_country(), array_merge( $this->get_european_union_countries( 'eu_vat' ), array( 'NO' ), $this->countries_using_vat() ), true ) ? __( '(incl. VAT)', 'woocommerce' ) : __( '(incl. tax)', 'woocommerce' );
$return = in_array( $this->get_base_country(), $this->get_vat_countries(), true ) ? __( '(incl. VAT)', 'woocommerce' ) : __( '(incl. tax)', 'woocommerce' );
return apply_filters( 'woocommerce_countries_inc_tax_or_vat', $return );
}
@ -433,7 +447,7 @@ class WC_Countries {
* @return string
*/
public function ex_tax_or_vat() {
$return = in_array( $this->get_base_country(), array_merge( $this->get_european_union_countries( 'eu_vat' ), array( 'NO' ), $this->countries_using_vat() ), true ) ? __( '(ex. VAT)', 'woocommerce' ) : __( '(ex. tax)', 'woocommerce' );
$return = in_array( $this->get_base_country(), $this->get_vat_countries(), true ) ? __( '(ex. VAT)', 'woocommerce' ) : __( '(ex. tax)', 'woocommerce' );
return apply_filters( 'woocommerce_countries_ex_tax_or_vat', $return );
}
@ -458,7 +472,8 @@ class WC_Countries {
echo ' selected="selected"';
}
echo '>' . esc_html( $value ) . ' &mdash; ' . ( $escape ? esc_js( $state_value ) : $state_value ) . '</option>'; // WPCS: XSS ok.
echo '>' . esc_html( $value ) . ' &mdash; ' . ( $escape ? esc_js( $state_value ) : $state_value ) . '</option>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
echo '</optgroup>';
} else {
@ -466,7 +481,7 @@ class WC_Countries {
if ( $selected_country === $key && '*' === $selected_state ) {
echo ' selected="selected"';
}
echo ' value="' . esc_attr( $key ) . '">' . ( $escape ? esc_js( $value ) : $value ) . '</option>'; // WPCS: XSS ok.
echo ' value="' . esc_attr( $key ) . '">' . ( $escape ? esc_js( $value ) : $value ) . '</option>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
}
}
@ -632,9 +647,9 @@ class WC_Countries {
*/
public function get_default_address_fields() {
if ( 'optional' === get_option( 'woocommerce_checkout_address_2_field', 'optional' ) ) {
$address_2_placeholder = __( 'Apartment, suite, unit etc. (optional)', 'woocommerce' );
$address_2_placeholder = __( 'Apartment, suite, unit, etc. (optional)', 'woocommerce' );
} else {
$address_2_placeholder = __( 'Apartment, suite, unit etc.', 'woocommerce' );
$address_2_placeholder = __( 'Apartment, suite, unit, etc.', 'woocommerce' );
}
$fields = array(
@ -848,7 +863,7 @@ class WC_Countries {
'postcode' => array(
'label' => __( 'Postal code', 'woocommerce' ),
),
'state' => array(
'state' => array(
'label' => __( 'Province', 'woocommerce' ),
),
),
@ -1003,7 +1018,7 @@ class WC_Countries {
),
),
'JP' => array(
'last_name' => array(
'last_name' => array(
'class' => array( 'form-row-first' ),
'priority' => 10,
),
@ -1011,22 +1026,22 @@ class WC_Countries {
'class' => array( 'form-row-last' ),
'priority' => 20,
),
'postcode' => array(
'postcode' => array(
'class' => array( 'form-row-first' ),
'priority' => 65,
),
'state' => array(
'state' => array(
'label' => __( 'Prefecture', 'woocommerce' ),
'class' => array( 'form-row-last' ),
'priority' => 66,
),
'city' => array(
'city' => array(
'priority' => 67,
),
'address_1' => array(
'address_1' => array(
'priority' => 68,
),
'address_2' => array(
'address_2' => array(
'priority' => 69,
),
),
@ -1265,7 +1280,7 @@ class WC_Countries {
'VN' => array(
'state' => array(
'required' => false,
'hidden' => true,
'hidden' => true,
),
'postcode' => array(
'priority' => 65,

View File

@ -951,22 +951,22 @@ class WC_Coupon extends WC_Legacy_Coupon {
break;
case self::E_WC_COUPON_NOT_EXIST:
/* translators: %s: coupon code */
$err = sprintf( __( 'Coupon "%s" does not exist!', 'woocommerce' ), $this->get_code() );
$err = sprintf( __( 'Coupon "%s" does not exist!', 'woocommerce' ), esc_html( $this->get_code() ) );
break;
case self::E_WC_COUPON_INVALID_REMOVED:
/* translators: %s: coupon code */
$err = sprintf( __( 'Sorry, it seems the coupon "%s" is invalid - it has now been removed from your order.', 'woocommerce' ), $this->get_code() );
$err = sprintf( __( 'Sorry, it seems the coupon "%s" is invalid - it has now been removed from your order.', 'woocommerce' ), esc_html( $this->get_code() ) );
break;
case self::E_WC_COUPON_NOT_YOURS_REMOVED:
/* translators: %s: coupon code */
$err = sprintf( __( 'Sorry, it seems the coupon "%s" is not yours - it has now been removed from your order.', 'woocommerce' ), $this->get_code() );
$err = sprintf( __( 'Sorry, it seems the coupon "%s" is not yours - it has now been removed from your order.', 'woocommerce' ), esc_html( $this->get_code() ) );
break;
case self::E_WC_COUPON_ALREADY_APPLIED:
$err = __( 'Coupon code already applied!', 'woocommerce' );
break;
case self::E_WC_COUPON_ALREADY_APPLIED_INDIV_USE_ONLY:
/* translators: %s: coupon code */
$err = sprintf( __( 'Sorry, coupon "%s" has already been applied and cannot be used in conjunction with other coupons.', 'woocommerce' ), $this->get_code() );
$err = sprintf( __( 'Sorry, coupon "%s" has already been applied and cannot be used in conjunction with other coupons.', 'woocommerce' ), esc_html( $this->get_code() ) );
break;
case self::E_WC_COUPON_USAGE_LIMIT_REACHED:
$err = __( 'Coupon usage limit has been reached.', 'woocommerce' );

View File

@ -159,7 +159,7 @@ class WC_Discounts {
* @since 3.2.0
* @param string $key name of discount row to return.
* @param bool $in_cents Should the totals be returned in cents, or without precision.
* @return array
* @return float
*/
public function get_discount( $key, $in_cents = false ) {
$item_discount_totals = $this->get_discounts_by_item( $in_cents );
@ -549,10 +549,7 @@ class WC_Discounts {
foreach ( $items_to_apply as $item ) {
for ( $i = 0; $i < $item->quantity; $i ++ ) {
// Find out how much price is available to discount for the item.
$discounted_price = $this->get_discounted_price_in_cents( $item );
// Get the price we actually want to discount, based on settings.
$price_to_discount = ( 'yes' === get_option( 'woocommerce_calc_discounts_sequentially', 'no' ) ) ? $discounted_price : $item->price;
$price_to_discount = $this->get_discounted_price_in_cents( $item );
// Run coupon calculations.
$discount = min( $price_to_discount, 1 );
@ -585,7 +582,7 @@ class WC_Discounts {
protected function validate_coupon_exists( $coupon ) {
if ( ! $coupon->get_id() && ! $coupon->get_virtual() ) {
/* translators: %s: coupon code */
throw new Exception( sprintf( __( 'Coupon "%s" does not exist!', 'woocommerce' ), $coupon->get_code() ), 105 );
throw new Exception( sprintf( __( 'Coupon "%s" does not exist!', 'woocommerce' ), esc_html( $coupon->get_code() ) ), 105 );
}
return true;

View File

@ -31,7 +31,7 @@ class WC_Download_Handler {
* Check if we need to download a file and check validity.
*/
public static function download_product() {
$product_id = absint( $_GET['download_file'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
$product_id = absint( $_GET['download_file'] ); // phpcs:ignore WordPress.VIP.SuperGlobalInputUsage.AccessDetected, WordPress.VIP.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
$product = wc_get_product( $product_id );
$data_store = WC_Data_Store::load( 'customer-download' );
@ -300,6 +300,16 @@ class WC_Download_Handler {
public static function download_file_xsendfile( $file_path, $filename ) {
$parsed_file_path = self::parse_file_path( $file_path );
/**
* Fallback on force download method for remote files. This is because:
* 1. xsendfile needs proxy configuration to work for remote files, which cannot be assumed to be available on most hosts.
* 2. Force download method is more secure than redirect method if `allow_url_fopen` is enabled in `php.ini`. We fallback to redirect method in force download method anyway in case `allow_url_fopen` is not enabled.
*/
if ( $parsed_file_path['remote_file'] && ! apply_filters( 'woocommerce_use_xsendfile_for_remote', false ) ) {
do_action( 'woocommerce_download_file_force', $file_path, $filename );
return;
}
if ( function_exists( 'apache_get_modules' ) && in_array( 'mod_xsendfile', apache_get_modules(), true ) ) {
self::download_headers( $parsed_file_path['file_path'], $filename );
$filepath = apply_filters( 'woocommerce_download_file_xsendfile_file_path', $parsed_file_path['file_path'], $file_path, $filename, $parsed_file_path );

View File

@ -8,6 +8,8 @@
* @version 2.3.0
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -175,7 +177,7 @@ class WC_Emails {
'source' => 'transactional-emails',
)
);
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
if ( Constants::is_true( 'WP_DEBUG' ) ) {
trigger_error( $error, E_USER_WARNING ); // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped, WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
}
}

View File

@ -6,6 +6,8 @@
* @version 2.3.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -51,27 +53,29 @@ class WC_Frontend_Scripts {
* @return array
*/
public static function get_styles() {
$version = Constants::get_constant( 'WC_VERSION' );
return apply_filters(
'woocommerce_enqueue_styles',
array(
'woocommerce-layout' => array(
'src' => self::get_asset_url( 'assets/css/woocommerce-layout.css' ),
'deps' => '',
'version' => WC_VERSION,
'version' => $version,
'media' => 'all',
'has_rtl' => true,
),
'woocommerce-smallscreen' => array(
'src' => self::get_asset_url( 'assets/css/woocommerce-smallscreen.css' ),
'deps' => 'woocommerce-layout',
'version' => WC_VERSION,
'version' => $version,
'media' => 'only screen and (max-width: ' . apply_filters( 'woocommerce_style_smallscreen_breakpoint', '768px' ) . ')',
'has_rtl' => true,
),
'woocommerce-general' => array(
'src' => self::get_asset_url( 'assets/css/woocommerce.css' ),
'deps' => '',
'version' => WC_VERSION,
'version' => $version,
'media' => 'all',
'has_rtl' => true,
),
@ -163,7 +167,9 @@ class WC_Frontend_Scripts {
* Register all WC scripts.
*/
private static function register_scripts() {
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
$suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min';
$version = Constants::get_constant( 'WC_VERSION' );
$register_scripts = array(
'flexslider' => array(
'src' => self::get_asset_url( 'assets/js/flexslider/jquery.flexslider' . $suffix . '.js' ),
@ -208,7 +214,7 @@ class WC_Frontend_Scripts {
'prettyPhoto-init' => array( // deprecated.
'src' => self::get_asset_url( 'assets/js/prettyPhoto/jquery.prettyPhoto.init' . $suffix . '.js' ),
'deps' => array( 'jquery', 'prettyPhoto' ),
'version' => WC_VERSION,
'version' => $version,
),
'select2' => array(
'src' => self::get_asset_url( 'assets/js/select2/select2.full' . $suffix . '.js' ),
@ -223,72 +229,72 @@ class WC_Frontend_Scripts {
'wc-address-i18n' => array(
'src' => self::get_asset_url( 'assets/js/frontend/address-i18n' . $suffix . '.js' ),
'deps' => array( 'jquery', 'wc-country-select' ),
'version' => WC_VERSION,
'version' => $version,
),
'wc-add-payment-method' => array(
'src' => self::get_asset_url( 'assets/js/frontend/add-payment-method' . $suffix . '.js' ),
'deps' => array( 'jquery', 'woocommerce' ),
'version' => WC_VERSION,
'version' => $version,
),
'wc-cart' => array(
'src' => self::get_asset_url( 'assets/js/frontend/cart' . $suffix . '.js' ),
'deps' => array( 'jquery', 'woocommerce', 'wc-country-select', 'wc-address-i18n' ),
'version' => WC_VERSION,
'version' => $version,
),
'wc-cart-fragments' => array(
'src' => self::get_asset_url( 'assets/js/frontend/cart-fragments' . $suffix . '.js' ),
'deps' => array( 'jquery', 'js-cookie' ),
'version' => WC_VERSION,
'version' => $version,
),
'wc-checkout' => array(
'src' => self::get_asset_url( 'assets/js/frontend/checkout' . $suffix . '.js' ),
'deps' => array( 'jquery', 'woocommerce', 'wc-country-select', 'wc-address-i18n' ),
'version' => WC_VERSION,
'version' => $version,
),
'wc-country-select' => array(
'src' => self::get_asset_url( 'assets/js/frontend/country-select' . $suffix . '.js' ),
'deps' => array( 'jquery' ),
'version' => WC_VERSION,
'version' => $version,
),
'wc-credit-card-form' => array(
'src' => self::get_asset_url( 'assets/js/frontend/credit-card-form' . $suffix . '.js' ),
'deps' => array( 'jquery', 'jquery-payment' ),
'version' => WC_VERSION,
'version' => $version,
),
'wc-add-to-cart' => array(
'src' => self::get_asset_url( 'assets/js/frontend/add-to-cart' . $suffix . '.js' ),
'deps' => array( 'jquery', 'jquery-blockui' ),
'version' => WC_VERSION,
'version' => $version,
),
'wc-add-to-cart-variation' => array(
'src' => self::get_asset_url( 'assets/js/frontend/add-to-cart-variation' . $suffix . '.js' ),
'deps' => array( 'jquery', 'wp-util', 'jquery-blockui' ),
'version' => WC_VERSION,
'version' => $version,
),
'wc-geolocation' => array(
'src' => self::get_asset_url( 'assets/js/frontend/geolocation' . $suffix . '.js' ),
'deps' => array( 'jquery' ),
'version' => WC_VERSION,
'version' => $version,
),
'wc-lost-password' => array(
'src' => self::get_asset_url( 'assets/js/frontend/lost-password' . $suffix . '.js' ),
'deps' => array( 'jquery', 'woocommerce' ),
'version' => WC_VERSION,
'version' => $version,
),
'wc-password-strength-meter' => array(
'src' => self::get_asset_url( 'assets/js/frontend/password-strength-meter' . $suffix . '.js' ),
'deps' => array( 'jquery', 'password-strength-meter' ),
'version' => WC_VERSION,
'version' => $version,
),
'wc-single-product' => array(
'src' => self::get_asset_url( 'assets/js/frontend/single-product' . $suffix . '.js' ),
'deps' => array( 'jquery' ),
'version' => WC_VERSION,
'version' => $version,
),
'woocommerce' => array(
'src' => self::get_asset_url( 'assets/js/frontend/woocommerce' . $suffix . '.js' ),
'deps' => array( 'jquery', 'jquery-blockui', 'js-cookie' ),
'version' => WC_VERSION,
'version' => $version,
),
'zoom' => array(
'src' => self::get_asset_url( 'assets/js/zoom/jquery.zoom' . $suffix . '.js' ),
@ -305,29 +311,31 @@ class WC_Frontend_Scripts {
* Register all WC sty;es.
*/
private static function register_styles() {
$version = Constants::get_constant( 'WC_VERSION' );
$register_styles = array(
'photoswipe' => array(
'src' => self::get_asset_url( 'assets/css/photoswipe/photoswipe.min.css' ),
'deps' => array(),
'version' => WC_VERSION,
'version' => $version,
'has_rtl' => false,
),
'photoswipe-default-skin' => array(
'src' => self::get_asset_url( 'assets/css/photoswipe/default-skin/default-skin.min.css' ),
'deps' => array( 'photoswipe' ),
'version' => WC_VERSION,
'version' => $version,
'has_rtl' => false,
),
'select2' => array(
'src' => self::get_asset_url( 'assets/css/select2.css' ),
'deps' => array(),
'version' => WC_VERSION,
'version' => $version,
'has_rtl' => false,
),
'woocommerce_prettyPhoto_css' => array( // deprecated.
'src' => self::get_asset_url( 'assets/css/prettyPhoto.css' ),
'deps' => array(),
'version' => WC_VERSION,
'version' => $version,
'has_rtl' => true,
),
);
@ -513,7 +521,7 @@ class WC_Frontend_Scripts {
'option_guest_checkout' => get_option( 'woocommerce_enable_guest_checkout' ),
'checkout_url' => WC_AJAX::get_endpoint( 'checkout' ),
'is_checkout' => is_checkout() && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) ? 1 : 0,
'debug_mode' => defined( 'WP_DEBUG' ) && WP_DEBUG,
'debug_mode' => Constants::is_true( 'WP_DEBUG' ),
'i18n_checkout_error' => esc_attr__( 'Error processing checkout. Please try again.', 'woocommerce' ),
);
break;

View File

@ -6,6 +6,8 @@
* @version 3.0.0
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -144,6 +146,7 @@ class WC_Install {
'wc_update_product_lookup_tables',
'wc_update_400_increase_size_of_column',
'wc_update_400_db_version',
'wc_reset_action_scheduler_migration_status',
),
);
@ -153,6 +156,7 @@ class WC_Install {
public static function init() {
add_action( 'init', array( __CLASS__, 'check_version' ), 5 );
add_action( 'init', array( __CLASS__, 'manual_database_update' ), 20 );
add_action( 'admin_init', array( __CLASS__, 'wc_admin_db_update_notice' ) );
add_action( 'woocommerce_run_update_callback', array( __CLASS__, 'run_update_callback' ) );
add_action( 'admin_init', array( __CLASS__, 'install_actions' ) );
add_filter( 'plugin_action_links_' . WC_PLUGIN_BASENAME, array( __CLASS__, 'plugin_action_links' ) );
@ -167,7 +171,7 @@ class WC_Install {
* This check is done on all requests and runs if the versions do not match.
*/
public static function check_version() {
if ( ! defined( 'IFRAME_REQUEST' ) && version_compare( get_option( 'woocommerce_version' ), WC()->version, '<' ) ) {
if ( ! Constants::is_defined( 'IFRAME_REQUEST' ) && version_compare( get_option( 'woocommerce_version' ), WC()->version, '<' ) ) {
self::install();
do_action( 'woocommerce_updated' );
}
@ -184,6 +188,20 @@ class WC_Install {
add_action( 'wp_' . $blog_id . '_wc_updater_cron', array( __CLASS__, 'run_manual_database_update' ) );
}
/**
* Add WC Admin based db update notice.
*
* @since 4.0.0
*/
public static function wc_admin_db_update_notice() {
if (
WC()->is_wc_admin_active() &&
false !== get_option( 'woocommerce_admin_install_timestamp' )
) {
new WC_Notes_Run_Db_Update();
}
}
/**
* Run manual database update.
*/
@ -245,7 +263,7 @@ class WC_Install {
if ( ! empty( $_GET['do_update_woocommerce'] ) ) { // WPCS: input var ok.
check_admin_referer( 'wc_db_update', 'wc_db_update_nonce' );
self::update();
WC_Admin_Notices::add_notice( 'update' );
WC_Admin_Notices::add_notice( 'update', true );
}
}
@ -317,7 +335,7 @@ class WC_Install {
* @since 3.2.0
* @return boolean
*/
private static function is_new_install() {
public static function is_new_install() {
$product_count = array_sum( (array) wp_count_posts( 'product' ) );
return is_null( get_option( 'woocommerce_version', null ) ) || ( 0 === $product_count && -1 === wc_get_page_id( 'shop' ) );
@ -345,7 +363,7 @@ class WC_Install {
*/
private static function maybe_enable_setup_wizard() {
if ( apply_filters( 'woocommerce_enable_setup_wizard', true ) && self::is_new_install() ) {
WC_Admin_Notices::add_notice( 'install' );
WC_Admin_Notices::add_notice( 'install', true );
set_transient( '_wc_activation_redirect', 1, 30 );
}
}
@ -360,7 +378,7 @@ class WC_Install {
if ( apply_filters( 'woocommerce_enable_auto_update_db', false ) ) {
self::update();
} else {
WC_Admin_Notices::add_notice( 'update' );
WC_Admin_Notices::add_notice( 'update', true );
}
} else {
self::update_db_version();
@ -460,7 +478,11 @@ class WC_Install {
wp_schedule_single_event( time() + ( absint( $held_duration ) * 60 ), 'woocommerce_cancel_unpaid_orders' );
}
wp_schedule_event( time(), 'daily', 'woocommerce_cleanup_personal_data' );
// Delay the first run of `woocommerce_cleanup_personal_data` by 10 seconds
// so it doesn't occur in the same request. WooCommerce Admin also schedules
// a daily cron that gets lost due to a race condition. WC_Privacy's background
// processing instance updates the cron schedule from within a cron job.
wp_schedule_event( time() + 10, 'daily', 'woocommerce_cleanup_personal_data' );
wp_schedule_event( time() + ( 3 * HOUR_IN_SECONDS ), 'daily', 'woocommerce_cleanup_logs' );
wp_schedule_event( time() + ( 6 * HOUR_IN_SECONDS ), 'twicedaily', 'woocommerce_cleanup_sessions' );
wp_schedule_event( time() + MINUTE_IN_SECONDS, 'fifteendays', 'woocommerce_geoip_updater' );

View File

@ -7,6 +7,8 @@
* @package WooCommerce/Classes
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -61,12 +63,16 @@ class WC_Logger implements WC_Logger_Interface {
}
}
// Support the constant as long as a valid log level has been set for it.
if ( null === $threshold ) {
$threshold = Constants::get_constant( 'WC_LOG_THRESHOLD' );
if ( null !== $threshold && ! WC_Log_Levels::is_valid_level( $threshold ) ) {
$threshold = null;
}
}
if ( null !== $threshold ) {
$threshold = WC_Log_Levels::get_level_severity( $threshold );
} elseif ( defined( 'WC_LOG_THRESHOLD' ) && WC_Log_Levels::is_valid_level( WC_LOG_THRESHOLD ) ) {
$threshold = WC_Log_Levels::get_level_severity( WC_LOG_THRESHOLD );
} else {
$threshold = null;
}
$this->handlers = $register_handlers;

View File

@ -10,6 +10,8 @@
* @package WooCommerce/Classes
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -316,7 +318,7 @@ class WC_Session_Handler extends WC_Session {
public function get_session( $customer_id, $default = false ) {
global $wpdb;
if ( defined( 'WP_SETUP_CONFIG' ) ) {
if ( Constants::is_defined( 'WP_SETUP_CONFIG' ) ) {
return false;
}

View File

@ -8,6 +8,8 @@
* @package WooCommerce/Classes/Shipping
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -163,7 +165,7 @@ class WC_Shipping {
$matched_zone_notice = sprintf( __( 'Customer matched zone "%s"', 'woocommerce' ), $shipping_zone->get_zone_name() );
// Debug output.
if ( $debug_mode && ! defined( 'WOOCOMMERCE_CHECKOUT' ) && ! defined( 'WC_DOING_AJAX' ) && ! wc_has_notice( $matched_zone_notice ) ) {
if ( $debug_mode && ! Constants::is_defined( 'WOOCOMMERCE_CHECKOUT' ) && ! Constants::is_defined( 'WC_DOING_AJAX' ) && ! wc_has_notice( $matched_zone_notice ) ) {
wc_add_notice( $matched_zone_notice );
}
} else {
@ -277,28 +279,19 @@ class WC_Shipping {
/**
* See if package is shippable.
*
* Packages must have a valid destination to be shipped.
* Packages are shippable until proven otherwise e.g. after getting a shipping country.
*
* @param array $package Package of cart items.
* @return bool
*/
public function is_package_shippable( $package ) {
// Packages are shippable until proven otherwise.
if ( empty( $package['destination']['country'] ) ) {
return false;
}
$country = $package['destination']['country'];
$countries = array_keys( WC()->countries->get_shipping_countries() );
if ( ! in_array( $country, $countries, true ) ) {
return false;
return true;
}
$states = WC()->countries->get_states( $country );
if ( is_array( $states ) && ! empty( $states ) && ! isset( $states[ $package['destination']['state'] ] ) ) {
return false;
}
return true;
$allowed = array_keys( WC()->countries->get_shipping_countries() );
return in_array( $package['destination']['country'], $allowed, true );
}
/**

View File

@ -305,7 +305,9 @@ class WC_Structured_Data {
'@type' => 'Review',
'reviewRating' => array(
'@type' => 'Rating',
'bestRating' => '5',
'ratingValue' => get_comment_meta( $comment->comment_ID, 'rating', true ),
'worstRating' => '1',
),
'author' => array(
'@type' => 'Person',
@ -350,7 +352,9 @@ class WC_Structured_Data {
if ( $rating ) {
$markup['reviewRating'] = array(
'@type' => 'Rating',
'bestRating' => '5',
'ratingValue' => $rating,
'worstRating' => '1',
);
} elseif ( $comment->comment_parent ) {
return;

View File

@ -10,6 +10,8 @@
* @package WooCommerce/Classes
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -38,7 +40,7 @@ class WC_Tracker {
*/
public static function send_tracking_data( $override = false ) {
// Don't trigger this on AJAX Requests.
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
if ( Constants::is_true( 'DOING_AJAX' ) ) {
return;
}
@ -84,6 +86,28 @@ class WC_Tracker {
return apply_filters( 'woocommerce_tracker_last_send_time', get_option( 'woocommerce_tracker_last_send', false ) );
}
/**
* Test whether this site is a staging site according to the Jetpack criteria.
*
* With Jetpack 8.1+, Jetpack::is_staging_site has been deprecated.
* \Automattic\Jetpack\Status::is_staging_site is the replacement.
* However, there are version of JP where \Automattic\Jetpack\Status exists, but does *not* contain is_staging_site method,
* so with those, code still needs to use the previous check as a fallback.
*
* @return bool
*/
private static function is_jetpack_staging_site() {
if ( class_exists( '\Automattic\Jetpack\Status' ) ) {
// Preferred way of checking with Jetpack 8.1+.
$jp_status = new \Automattic\Jetpack\Status();
if ( is_callable( array( $jp_status, 'is_staging_site' ) ) ) {
return $jp_status->is_staging_site();
}
}
return ( class_exists( 'Jetpack' ) && is_callable( 'Jetpack::is_staging_site' ) && Jetpack::is_staging_site() );
}
/**
* Get all the tracking data.
*
@ -109,9 +133,10 @@ class WC_Tracker {
$data['inactive_plugins'] = $all_plugins['inactive_plugins'];
// Jetpack & WooCommerce Connect.
$data['jetpack_version'] = defined( 'JETPACK__VERSION' ) ? JETPACK__VERSION : 'none';
$data['jetpack_version'] = Constants::is_defined( 'JETPACK__VERSION' ) ? Constants::get_constant( 'JETPACK__VERSION' ) : 'none';
$data['jetpack_connected'] = ( class_exists( 'Jetpack' ) && is_callable( 'Jetpack::is_active' ) && Jetpack::is_active() ) ? 'yes' : 'no';
$data['jetpack_is_staging'] = ( class_exists( 'Jetpack' ) && is_callable( 'Jetpack::is_staging_site' ) && Jetpack::is_staging_site() ) ? 'yes' : 'no';
$data['jetpack_is_staging'] = self::is_jetpack_staging_site() ? 'yes' : 'no';
$data['connect_installed'] = class_exists( 'WC_Connect_Loader' ) ? 'yes' : 'no';
$data['connect_active'] = ( class_exists( 'WC_Connect_Loader' ) && wp_next_scheduled( 'wc_connect_fetch_service_schemas' ) ) ? 'yes' : 'no';
$data['helper_connected'] = self::get_helper_connected();
@ -138,6 +163,9 @@ class WC_Tracker {
// Template overrides.
$data['admin_user_agents'] = self::get_admin_user_agents();
// Cart & checkout tech (blocks or shortcodes).
$data['cart_checkout'] = self::get_cart_checkout_info();
return apply_filters( 'woocommerce_tracker_data', $data );
}
@ -596,6 +624,63 @@ class WC_Tracker {
return array_merge( $min_max, $processing_min_max );
}
/**
* Search a specific post for text content.
*
* @param integer $post_id The id of the post to search.
* @param string $text The text to search for.
* @return string 'Yes' if post contains $text (otherwise 'No').
*/
public static function post_contains_text( $post_id, $text ) {
global $wpdb;
// Search for the text anywhere in the post.
$wildcarded = "%{$text}%";
$result = $wpdb->get_var(
$wpdb->prepare(
"
SELECT COUNT( * ) FROM {$wpdb->prefix}posts
WHERE ID=%d
AND {$wpdb->prefix}posts.post_content LIKE %s
",
array( $post_id, $wildcarded )
)
);
return ( '0' !== $result ) ? 'Yes' : 'No';
}
/**
* Get info about the cart & checkout pages.
*
* @return array
*/
public static function get_cart_checkout_info() {
global $wpdb;
$cart_page_id = wc_get_page_id( 'cart' );
$checkout_page_id = wc_get_page_id( 'checkout' );
return array(
'cart_page_contains_cart_block' => self::post_contains_text(
$cart_page_id,
'<!-- wp:woocommerce/cart'
),
'cart_page_contains_cart_shortcode' => self::post_contains_text(
$cart_page_id,
'[woocommerce_cart]'
),
'checkout_page_contains_checkout_block' => self::post_contains_text(
$checkout_page_id,
'<!-- wp:woocommerce/checkout'
),
'checkout_page_contains_checkout_shortcode' => self::post_contains_text(
$checkout_page_id,
'[woocommerce_checkout]'
),
);
}
}
WC_Tracker::init();

View File

@ -11,6 +11,8 @@
* @since 2.2.0
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
require_once 'legacy/class-wc-legacy-webhook.php';
@ -20,6 +22,14 @@ require_once 'legacy/class-wc-legacy-webhook.php';
*/
class WC_Webhook extends WC_Legacy_Webhook {
/**
* Store which object IDs this webhook has processed (ie scheduled to be delivered)
* within the current page request.
*
* @var array
*/
protected $processed = array();
/**
* Stores webhook data.
*
@ -103,6 +113,9 @@ class WC_Webhook extends WC_Legacy_Webhook {
return;
}
// Mark this $arg as processed to ensure it doesn't get processed again within the current request.
$this->processed[] = $arg;
/**
* Process webhook delivery.
*
@ -123,7 +136,7 @@ class WC_Webhook extends WC_Legacy_Webhook {
* @return bool True if webhook should be delivered, false otherwise.
*/
private function should_deliver( $arg ) {
$should_deliver = $this->is_active() && $this->is_valid_topic() && $this->is_valid_action( $arg ) && $this->is_valid_resource( $arg );
$should_deliver = $this->is_active() && $this->is_valid_topic() && $this->is_valid_action( $arg ) && $this->is_valid_resource( $arg ) && ! $this->is_already_processed( $arg );
/**
* Let other plugins intercept deliver for some messages queue like rabbit/zeromq.
@ -280,6 +293,19 @@ class WC_Webhook extends WC_Legacy_Webhook {
return true;
}
/**
* Checks if the specified resource has already been queued for delivery within the current request.
*
* Helps avoid duplication of data being sent for topics that have more than one hook defined.
*
* @param mixed $arg First hook argument.
*
* @return bool
*/
protected function is_already_processed( $arg ) {
return false !== array_search( $arg, $this->processed, true );
}
/**
* Deliver the webhook payload using wp_safe_remote_request().
*
@ -297,7 +323,7 @@ class WC_Webhook extends WC_Legacy_Webhook {
'redirection' => 0,
'httpversion' => '1.0',
'blocking' => true,
'user-agent' => sprintf( 'WooCommerce/%s Hookshot (WordPress/%s)', WC_VERSION, $GLOBALS['wp_version'] ),
'user-agent' => sprintf( 'WooCommerce/%s Hookshot (WordPress/%s)', Constants::get_constant( 'WC_VERSION' ), $GLOBALS['wp_version'] ),
'body' => trim( wp_json_encode( $payload ) ),
'headers' => array(
'Content-Type' => 'application/json',
@ -531,7 +557,7 @@ class WC_Webhook extends WC_Legacy_Webhook {
'Body' => $response_body,
);
if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {
if ( ! Constants::is_true( 'WP_DEBUG' ) ) {
$message['Webhook Delivery']['Body'] = 'Webhook body is not logged unless WP_DEBUG mode is turned on. This is to avoid the storing of personal data in the logs.';
$message['Webhook Delivery']['Response']['Body'] = 'Webhook body is not logged unless WP_DEBUG mode is turned on. This is to avoid the storing of personal data in the logs.';
}
@ -610,7 +636,7 @@ class WC_Webhook extends WC_Legacy_Webhook {
*/
public function deliver_ping() {
$args = array(
'user-agent' => sprintf( 'WooCommerce/%s Hookshot (WordPress/%s)', WC_VERSION, $GLOBALS['wp_version'] ),
'user-agent' => sprintf( 'WooCommerce/%s Hookshot (WordPress/%s)', Constants::get_constant( 'WC_VERSION' ), $GLOBALS['wp_version'] ),
'body' => 'webhook_id=' . $this->get_id(),
);

View File

@ -20,7 +20,7 @@ final class WooCommerce {
*
* @var string
*/
public $version = '4.0.0-dev';
public $version = '4.1.0';
/**
* The single instance of the class.
@ -882,4 +882,14 @@ final class WooCommerce {
);
printf( '<div class="error"><p>%s %s</p></div>', $message_one, $message_two ); /* WPCS: xss ok. */
}
/**
* Is the WooCommerce Admin actively included in the WooCommerce core?
* Based on presence of a basic WC Admin function.
*
* @return boolean
*/
public function is_wc_admin_active() {
return function_exists( 'wc_admin_url' );
}
}

View File

@ -5,6 +5,8 @@
* @package WooCommerce\Cli
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -286,11 +288,11 @@ class WC_CLI_REST_Command {
$request->set_param( $key, $value );
}
}
if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
if ( Constants::is_true( 'SAVEQUERIES' ) ) {
$original_queries = is_array( $GLOBALS['wpdb']->queries ) ? array_keys( $GLOBALS['wpdb']->queries ) : array();
}
$response = rest_do_request( $request );
if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
if ( Constants::is_true( 'SAVEQUERIES' ) ) {
$performed_queries = array();
foreach ( (array) $GLOBALS['wpdb']->queries as $key => $query ) {
if ( in_array( $key, $original_queries, true ) ) {

View File

@ -73,7 +73,7 @@ class WC_CLI_Update_Command {
$progress->finish();
WC_Admin_Notices::remove_notice( 'update' );
WC_Admin_Notices::remove_notice( 'update', true );
/* translators: 1: Number of database updates performed 2: Database version number */
WP_CLI::success( sprintf( __( '%1$d update functions completed. Database version is %2$s', 'woocommerce' ), absint( $update_count ), get_option( 'woocommerce_db_version' ) ) );

View File

@ -5,6 +5,8 @@
* @package WooCommerce/Classes
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -54,7 +56,7 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
* @param WC_Order $order Order object.
*/
public function create( &$order ) {
$order->set_version( WC_VERSION );
$order->set_version( Constants::get_constant( 'WC_VERSION' ) );
$order->set_date_created( time() );
$order->set_currency( $order->get_currency() ? $order->get_currency() : get_woocommerce_currency() );
@ -131,7 +133,7 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
*/
public function update( &$order ) {
$order->save_meta_data();
$order->set_version( WC_VERSION );
$order->set_version( Constants::get_constant( 'WC_VERSION' ) );
if ( null === $order->get_date_created( 'edit' ) ) {
$order->set_date_created( time() );

View File

@ -54,6 +54,14 @@ class WC_Coupon_Data_Store_CPT extends WC_Data_Store_WP implements WC_Coupon_Dat
'_edit_last',
);
/**
* The updated coupon properties
*
* @since 4.1.0
* @var array
*/
protected $updated_props = array();
/**
* Method to create a new coupon in the database.
*
@ -501,6 +509,13 @@ class WC_Coupon_Data_Store_CPT extends WC_Data_Store_WP implements WC_Coupon_Dat
return null;
}
// Make sure we have usage_count meta key for this coupon because its required for `$query_for_usages`.
// We are not directly modifying `$query_for_usages` to allow for `usage_count` not present only keep that query simple.
if ( ! metadata_exists( 'post', $coupon->get_id(), 'usage_count' ) ) {
$coupon->set_usage_count( $coupon->get_usage_count() ); // Use `get_usage_count` here to write default value, which may changed by a filter.
$coupon->save();
}
$query_for_usages = $wpdb->prepare(
"
SELECT meta_value from $wpdb->postmeta

View File

@ -274,7 +274,7 @@ class WC_Order_Data_Store_CPT extends Abstract_WC_Order_Data_Store_CPT implement
if ( in_array( 'date_completed', $updated_props, true ) ) {
$value = $order->get_date_completed( 'edit' );
// In 2.6.x date_paid was stored as _paid_date in local mysql format.
// In 2.6.x date_completed was stored as _completed_date in local mysql format.
update_post_meta( $id, '_completed_date', ! is_null( $value ) ? $value->date( 'Y-m-d H:i:s' ) : '' );
}

View File

@ -40,7 +40,11 @@ class WC_Order_Item_Data_Store implements WC_Order_Item_Data_Store_Interface {
)
);
return absint( $wpdb->insert_id );
$item_id = absint( $wpdb->insert_id );
$this->clear_caches( $item_id, $order_id );
return $item_id;
}
/**
@ -53,7 +57,9 @@ class WC_Order_Item_Data_Store implements WC_Order_Item_Data_Store_Interface {
*/
public function update_order_item( $item_id, $item ) {
global $wpdb;
return $wpdb->update( $wpdb->prefix . 'woocommerce_order_items', $item, array( 'order_item_id' => $item_id ) );
$updated = $wpdb->update( $wpdb->prefix . 'woocommerce_order_items', $item, array( 'order_item_id' => $item_id ) );
$this->clear_caches( $item_id, null );
return $updated;
}
/**
@ -63,9 +69,14 @@ class WC_Order_Item_Data_Store implements WC_Order_Item_Data_Store_Interface {
* @param int $item_id Item ID.
*/
public function delete_order_item( $item_id ) {
// Load the order ID before the deletion, since after, it won't exist in the database.
$order_id = $this->get_order_id_by_order_item_id( $item_id );
global $wpdb;
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", $item_id ) );
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id = %d", $item_id ) );
$this->clear_caches( $item_id, $order_id );
}
/**
@ -158,4 +169,21 @@ class WC_Order_Item_Data_Store implements WC_Order_Item_Data_Store_Interface {
return $order_item_type;
}
/**
* Clear meta cache.
*
* @param int $item_id Item ID.
* @param int|null $order_id Order ID. If not set, it will be loaded using the item ID.
*/
protected function clear_caches( $item_id, $order_id ) {
wp_cache_delete( 'item-' . $item_id, 'order-items' );
if ( ! $order_id ) {
$order_id = $this->get_order_id_by_order_item_id( $item_id );
}
if ( $order_id ) {
wp_cache_delete( 'order-items-' . $order_id, 'orders' );
}
}
}

View File

@ -5,6 +5,8 @@
* @package WooCommerce/Classes
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -823,7 +825,7 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
$new_type = $product->get_type();
wp_set_object_terms( $product->get_id(), $new_type, 'product_type' );
update_post_meta( $product->get_id(), '_product_version', WC_VERSION );
update_post_meta( $product->get_id(), '_product_version', Constants::get_constant( 'WC_VERSION' ) );
// Action for the transition.
if ( $old_type !== $new_type ) {

View File

@ -5,6 +5,8 @@
* @package WooCommerce\DataStores
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -333,7 +335,7 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl
*/
protected function update_version_and_type( &$product ) {
wp_set_object_terms( $product->get_id(), '', 'product_type' );
update_post_meta( $product->get_id(), '_product_version', WC_VERSION );
update_post_meta( $product->get_id(), '_product_version', Constants::get_constant( 'WC_VERSION' ) );
}
/**

View File

@ -548,6 +548,7 @@ class WC_Email extends WC_Settings_API {
*
* We only inline CSS for html emails, and to do so we use Emogrifier library (if supported).
*
* @version 4.0.0
* @param string|null $content Content that will receive inline styles.
* @return string
*/
@ -557,13 +558,14 @@ class WC_Email extends WC_Settings_API {
wc_get_template( 'emails/email-styles.php' );
$css = apply_filters( 'woocommerce_email_styles', ob_get_clean(), $this );
if ( $this->supports_emogrifier() ) {
$emogrifier_class = '\\Pelago\\Emogrifier';
if ( ! class_exists( $emogrifier_class ) ) {
include_once dirname( dirname( __FILE__ ) ) . '/libraries/class-emogrifier.php';
}
$emogrifier_class = 'Pelago\\Emogrifier';
if ( $this->supports_emogrifier() && class_exists( $emogrifier_class ) ) {
try {
$emogrifier = new $emogrifier_class( $content, $css );
do_action( 'woocommerce_emogrifier', $emogrifier, $this );
$content = $emogrifier->emogrify();
} catch ( Exception $e ) {
$logger = wc_get_logger();
@ -573,17 +575,19 @@ class WC_Email extends WC_Settings_API {
$content = '<style type="text/css">' . $css . '</style>' . $content;
}
}
return $content;
}
/**
* Return if emogrifier library is supported.
*
* @version 4.0.0
* @since 3.5.0
* @return bool
*/
protected function supports_emogrifier() {
return class_exists( 'DOMDocument' ) && version_compare( PHP_VERSION, '5.5', '>=' );
return class_exists( 'DOMDocument' );
}
/**

View File

@ -5,6 +5,8 @@
* @package WooCommerce\Gateways
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
@ -62,47 +64,6 @@ class WC_Gateway_COD extends WC_Payment_Gateway {
* Initialise Gateway Settings Form Fields.
*/
public function init_form_fields() {
$options = array();
$data_store = WC_Data_Store::load( 'shipping-zone' );
$raw_zones = $data_store->get_zones();
foreach ( $raw_zones as $raw_zone ) {
$zones[] = new WC_Shipping_Zone( $raw_zone );
}
$zones[] = new WC_Shipping_Zone( 0 );
foreach ( WC()->shipping()->load_shipping_methods() as $method ) {
$options[ $method->get_method_title() ] = array();
// Translators: %1$s shipping method name.
$options[ $method->get_method_title() ][ $method->id ] = sprintf( __( 'Any &quot;%1$s&quot; method', 'woocommerce' ), $method->get_method_title() );
foreach ( $zones as $zone ) {
$shipping_method_instances = $zone->get_shipping_methods();
foreach ( $shipping_method_instances as $shipping_method_instance_id => $shipping_method_instance ) {
if ( $shipping_method_instance->id !== $method->id ) {
continue;
}
$option_id = $shipping_method_instance->get_rate_id();
// Translators: %1$s shipping method title, %2$s shipping method id.
$option_instance_title = sprintf( __( '%1$s (#%2$s)', 'woocommerce' ), $shipping_method_instance->get_title(), $shipping_method_instance_id );
// Translators: %1$s zone name, %2$s shipping method instance name.
$option_title = sprintf( __( '%1$s &ndash; %2$s', 'woocommerce' ), $zone->get_id() ? $zone->get_zone_name() : __( 'Other locations', 'woocommerce' ), $option_instance_title );
$options[ $method->get_method_title() ][ $option_id ] = $option_title;
}
}
}
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
@ -139,7 +100,7 @@ class WC_Gateway_COD extends WC_Payment_Gateway {
'css' => 'width: 400px;',
'default' => '',
'description' => __( 'If COD is only available for certain methods, set it up here. Leave blank to enable for all methods.', 'woocommerce' ),
'options' => $options,
'options' => $this->load_shipping_method_options(),
'desc_tip' => true,
'custom_attributes' => array(
'data-placeholder' => __( 'Select shipping methods', 'woocommerce' ),
@ -208,6 +169,92 @@ class WC_Gateway_COD extends WC_Payment_Gateway {
return parent::is_available();
}
/**
* Checks to see whether or not the admin settings are being accessed by the current request.
*
* @return bool
*/
private function is_accessing_settings() {
if ( is_admin() ) {
// phpcs:disable WordPress.Security.NonceVerification
if ( ! isset( $_REQUEST['page'] ) || 'wc-settings' !== $_REQUEST['page'] ) {
return false;
}
if ( ! isset( $_REQUEST['tab'] ) || 'checkout' !== $_REQUEST['tab'] ) {
return false;
}
if ( ! isset( $_REQUEST['section'] ) || 'cod' !== $_REQUEST['section'] ) {
return false;
}
// phpcs:enable WordPress.Security.NonceVerification
return true;
}
if ( Constants::is_true( 'REST_REQUEST' ) ) {
global $wp;
if ( isset( $wp->query_vars['rest_route'] ) && false !== strpos( $wp->query_vars['rest_route'], '/payment_gateways' ) ) {
return true;
}
}
return false;
}
/**
* Loads all of the shipping method options for the enable_for_methods field.
*
* @return array
*/
private function load_shipping_method_options() {
// Since this is expensive, we only want to do it if we're actually on the settings page.
if ( ! $this->is_accessing_settings() ) {
return array();
}
$data_store = WC_Data_Store::load( 'shipping-zone' );
$raw_zones = $data_store->get_zones();
foreach ( $raw_zones as $raw_zone ) {
$zones[] = new WC_Shipping_Zone( $raw_zone );
}
$zones[] = new WC_Shipping_Zone( 0 );
$options = array();
foreach ( WC()->shipping()->load_shipping_methods() as $method ) {
$options[ $method->get_method_title() ] = array();
// Translators: %1$s shipping method name.
$options[ $method->get_method_title() ][ $method->id ] = sprintf( __( 'Any &quot;%1$s&quot; method', 'woocommerce' ), $method->get_method_title() );
foreach ( $zones as $zone ) {
$shipping_method_instances = $zone->get_shipping_methods();
foreach ( $shipping_method_instances as $shipping_method_instance_id => $shipping_method_instance ) {
if ( $shipping_method_instance->id !== $method->id ) {
continue;
}
$option_id = $shipping_method_instance->get_rate_id();
// Translators: %1$s shipping method title, %2$s shipping method id.
$option_instance_title = sprintf( __( '%1$s (#%2$s)', 'woocommerce' ), $shipping_method_instance->get_title(), $shipping_method_instance_id );
// Translators: %1$s zone name, %2$s shipping method instance name.
$option_title = sprintf( __( '%1$s &ndash; %2$s', 'woocommerce' ), $zone->get_id() ? $zone->get_zone_name() : __( 'Other locations', 'woocommerce' ), $option_instance_title );
$options[ $method->get_method_title() ][ $option_id ] = $option_title;
}
}
}
return $options;
}
/**
* Converts the chosen rate IDs generated by Shipping Methods to a canonical 'method_id:instance_id' format.
*
@ -319,7 +366,6 @@ class WC_Gateway_COD extends WC_Payment_Gateway {
/**
* Add content to the WC emails.
*
* @access public
* @param WC_Order $order Order object.
* @param bool $sent_to_admin Sent to admin.
* @param bool $plain_text Email format: plain text or HTML.

View File

@ -10,6 +10,8 @@
* @package WooCommerce/Classes/Payment
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -450,9 +452,10 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway {
return;
}
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
$suffix = Constants::is_true( 'SCRIPT_DEBUG' ) ? '' : '.min';
$version = Constants::get_constant( 'WC_VERSION' );
wp_enqueue_script( 'woocommerce_paypal_admin', WC()->plugin_url() . '/includes/gateways/paypal/assets/js/paypal-admin' . $suffix . '.js', array(), WC_VERSION, true );
wp_enqueue_script( 'woocommerce_paypal_admin', WC()->plugin_url() . '/includes/gateways/paypal/assets/js/paypal-admin' . $suffix . '.js', array(), $version, true );
}
/**

View File

@ -5,6 +5,8 @@
* @package WooCommerce\Gateways
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -51,7 +53,7 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response {
),
'timeout' => 60,
'httpversion' => '1.1',
'user-agent' => 'WooCommerce/' . WC_VERSION,
'user-agent' => 'WooCommerce/' . Constants::get_constant( 'WC_VERSION' ),
);
// Post back to get a response.

View File

@ -88,7 +88,7 @@ class WC_Integration_MaxMind_Database_Service {
$download_uri = add_query_arg(
array(
'edition_id' => self::DATABASE,
'license_key' => wc_clean( $license_key ),
'license_key' => urlencode( wc_clean( $license_key ) ),
'suffix' => 'tar.gz',
),
'https://download.maxmind.com/app/geoip_download'
@ -97,7 +97,7 @@ class WC_Integration_MaxMind_Database_Service {
// Needed for the download_url call right below.
require_once ABSPATH . 'wp-admin/includes/file.php';
$tmp_archive_path = download_url( $download_uri );
$tmp_archive_path = download_url( esc_url_raw( $download_uri ) );
if ( is_wp_error( $tmp_archive_path ) ) {
// Transform the error into something more informative.
$error_data = $tmp_archive_path->get_error_data();

View File

@ -1,154 +0,0 @@
<?php
namespace Pelago\Emogrifier;
/**
* Facilitates building a CSS string by appending rule blocks one at a time, checking whether the media query,
* selectors, or declarations block are the same as those from the preceding block and combining blocks in such cases.
*
* Example:
* $concatenator = new CssConcatenator();
* $concatenator->append(['body'], 'color: blue;');
* $concatenator->append(['body'], 'font-size: 16px;');
* $concatenator->append(['p'], 'margin: 1em 0;');
* $concatenator->append(['ul', 'ol'], 'margin: 1em 0;');
* $concatenator->append(['body'], 'font-size: 14px;', '@media screen and (max-width: 400px)');
* $concatenator->append(['ul', 'ol'], 'margin: 0.75em 0;', '@media screen and (max-width: 400px)');
* $css = $concatenator->getCss();
*
* `$css` (if unminified) would contain the following CSS:
* ` body {
* ` color: blue;
* ` font-size: 16px;
* ` }
* ` p, ul, ol {
* ` margin: 1em 0;
* ` }
* ` @media screen and (max-width: 400px) {
* ` body {
* ` font-size: 14px;
* ` }
* ` ul, ol {
* ` margin: 0.75em 0;
* ` }
* ` }
*
* @author Jake Hotson <jake.github@qzdesign.co.uk>
*/
class CssConcatenator
{
/**
* Array of media rules in order. Each element is an object with the following properties:
* - string `media` - The media query string, e.g. "@media screen and (max-width:639px)", or an empty string for
* rules not within a media query block;
* - \stdClass[] `ruleBlocks` - Array of rule blocks in order, where each element is an object with the following
* properties:
* - mixed[] `selectorsAsKeys` - Array whose keys are selectors for the rule block (values are of no
* significance);
* - string `declarationsBlock` - The property declarations, e.g. "margin-top: 0.5em; padding: 0".
*
* @var \stdClass[]
*/
private $mediaRules = [];
/**
* Appends a declaration block to the CSS.
*
* @param string[] $selectors Array of selectors for the rule, e.g. ["ul", "ol", "p:first-child"].
* @param string $declarationsBlock The property declarations, e.g. "margin-top: 0.5em; padding: 0".
* @param string $media The media query for the rule, e.g. "@media screen and (max-width:639px)",
* or an empty string if none.
*/
public function append(array $selectors, $declarationsBlock, $media = '')
{
$selectorsAsKeys = \array_flip($selectors);
$mediaRule = $this->getOrCreateMediaRuleToAppendTo($media);
$lastRuleBlock = \end($mediaRule->ruleBlocks);
$hasSameDeclarationsAsLastRule = $lastRuleBlock !== false
&& $declarationsBlock === $lastRuleBlock->declarationsBlock;
if ($hasSameDeclarationsAsLastRule) {
$lastRuleBlock->selectorsAsKeys += $selectorsAsKeys;
} else {
$hasSameSelectorsAsLastRule = $lastRuleBlock !== false
&& static::hasEquivalentSelectors($selectorsAsKeys, $lastRuleBlock->selectorsAsKeys);
if ($hasSameSelectorsAsLastRule) {
$lastDeclarationsBlockWithoutSemicolon = \rtrim(\rtrim($lastRuleBlock->declarationsBlock), ';');
$lastRuleBlock->declarationsBlock = $lastDeclarationsBlockWithoutSemicolon . ';' . $declarationsBlock;
} else {
$mediaRule->ruleBlocks[] = (object)\compact('selectorsAsKeys', 'declarationsBlock');
}
}
}
/**
* @return string
*/
public function getCss()
{
return \implode('', \array_map([$this, 'getMediaRuleCss'], $this->mediaRules));
}
/**
* @param string $media The media query for rules to be appended, e.g. "@media screen and (max-width:639px)",
* or an empty string if none.
*
* @return \stdClass Object with properties as described for elements of `$mediaRules`.
*/
private function getOrCreateMediaRuleToAppendTo($media)
{
$lastMediaRule = \end($this->mediaRules);
if ($lastMediaRule !== false && $media === $lastMediaRule->media) {
return $lastMediaRule;
}
$newMediaRule = (object)[
'media' => $media,
'ruleBlocks' => [],
];
$this->mediaRules[] = $newMediaRule;
return $newMediaRule;
}
/**
* Tests if two sets of selectors are equivalent (i.e. the same selectors, possibly in a different order).
*
* @param mixed[] $selectorsAsKeys1 Array in which the selectors are the keys, and the values are of no
* significance.
* @param mixed[] $selectorsAsKeys2 Another such array.
*
* @return bool
*/
private static function hasEquivalentSelectors(array $selectorsAsKeys1, array $selectorsAsKeys2)
{
return \count($selectorsAsKeys1) === \count($selectorsAsKeys2)
&& \count($selectorsAsKeys1) === \count($selectorsAsKeys1 + $selectorsAsKeys2);
}
/**
* @param \stdClass $mediaRule Object with properties as described for elements of `$mediaRules`.
*
* @return string CSS for the media rule.
*/
private static function getMediaRuleCss(\stdClass $mediaRule)
{
$css = \implode('', \array_map([static::class, 'getRuleBlockCss'], $mediaRule->ruleBlocks));
if ($mediaRule->media !== '') {
$css = $mediaRule->media . '{' . $css . '}';
}
return $css;
}
/**
* @param \stdClass $ruleBlock Object with properties as described for elements of the `ruleBlocks` property of
* elements of `$mediaRules`.
*
* @return string CSS for the rule block.
*/
private static function getRuleBlockCss(\stdClass $ruleBlock)
{
$selectors = \array_keys($ruleBlock->selectorsAsKeys);
return \implode(',', $selectors) . '{' . $ruleBlock->declarationsBlock . '}';
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,263 +0,0 @@
<?php
namespace Pelago\Emogrifier\HtmlProcessor;
/**
* Base class for HTML processor that e.g., can remove, add or modify nodes or attributes.
*
* The "vanilla" subclass is the HtmlNormalizer.
*
* @internal This class currently is a new technology preview, and its API is still in flux. Don't use it in production.
*
* @author Oliver Klee <github@oliverklee.de>
*/
abstract class AbstractHtmlProcessor
{
/**
* @var string
*/
const DEFAULT_DOCUMENT_TYPE = '<!DOCTYPE html>';
/**
* @var string
*/
const CONTENT_TYPE_META_TAG = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
/**
* @var string Regular expression part to match tag names that PHP's DOMDocument implementation is not aware are
* self-closing. These are mostly HTML5 elements, but for completeness <command> (obsolete) and <keygen>
* (deprecated) are also included.
*
* @see https://bugs.php.net/bug.php?id=73175
*/
const PHP_UNRECOGNIZED_VOID_TAGNAME_MATCHER = '(?:command|embed|keygen|source|track|wbr)';
/**
* @var \DOMDocument
*/
protected $domDocument = null;
/**
* @param string $unprocessedHtml raw HTML, must be UTF-encoded, must not be empty
*
* @throws \InvalidArgumentException if $unprocessedHtml is anything other than a non-empty string
*/
public function __construct($unprocessedHtml)
{
if (!\is_string($unprocessedHtml)) {
throw new \InvalidArgumentException('The provided HTML must be a string.', 1515459744);
}
if ($unprocessedHtml === '') {
throw new \InvalidArgumentException('The provided HTML must not be empty.', 1515763647);
}
$this->setHtml($unprocessedHtml);
}
/**
* Sets the HTML to process.
*
* @param string $html the HTML to process, must be UTF-8-encoded
*
* @return void
*/
private function setHtml($html)
{
$this->createUnifiedDomDocument($html);
}
/**
* Provides access to the internal DOMDocument representation of the HTML in its current state.
*
* @return \DOMDocument
*/
public function getDomDocument()
{
return $this->domDocument;
}
/**
* Renders the normalized and processed HTML.
*
* @return string
*/
public function render()
{
$htmlWithPossibleErroneousClosingTags = $this->domDocument->saveHTML();
return $this->removeSelfClosingTagsClosingTags($htmlWithPossibleErroneousClosingTags);
}
/**
* Renders the content of the BODY element of the normalized and processed HTML.
*
* @return string
*/
public function renderBodyContent()
{
$htmlWithPossibleErroneousClosingTags = $this->domDocument->saveHTML($this->getBodyElement());
$bodyNodeHtml = $this->removeSelfClosingTagsClosingTags($htmlWithPossibleErroneousClosingTags);
return \str_replace(['<body>', '</body>'], '', $bodyNodeHtml);
}
/**
* Eliminates any invalid closing tags for void elements from the given HTML.
*
* @param string $html
*
* @return string
*/
private function removeSelfClosingTagsClosingTags($html)
{
return \preg_replace('%</' . static::PHP_UNRECOGNIZED_VOID_TAGNAME_MATCHER . '>%', '', $html);
}
/**
* Returns the BODY element.
*
* This method assumes that there always is a BODY element.
*
* @return \DOMElement
*/
private function getBodyElement()
{
return $this->domDocument->getElementsByTagName('body')->item(0);
}
/**
* Creates a DOM document from the given HTML and stores it in $this->domDocument.
*
* The DOM document will always have a BODY element and a document type.
*
* @param string $html
*
* @return void
*/
private function createUnifiedDomDocument($html)
{
$this->createRawDomDocument($html);
$this->ensureExistenceOfBodyElement();
}
/**
* Creates a DOMDocument instance from the given HTML and stores it in $this->domDocument.
*
* @param string $html
*
* @return void
*/
private function createRawDomDocument($html)
{
$domDocument = new \DOMDocument();
$domDocument->strictErrorChecking = false;
$domDocument->formatOutput = true;
$libXmlState = \libxml_use_internal_errors(true);
$domDocument->loadHTML($this->prepareHtmlForDomConversion($html));
\libxml_clear_errors();
\libxml_use_internal_errors($libXmlState);
$this->domDocument = $domDocument;
}
/**
* Returns the HTML with added document type, Content-Type meta tag, and self-closing slashes, if needed,
* ensuring that the HTML will be good for creating a DOM document from it.
*
* @param string $html
*
* @return string the unified HTML
*/
private function prepareHtmlForDomConversion($html)
{
$htmlWithSelfClosingSlashes = $this->ensurePhpUnrecognizedSelfClosingTagsAreXml($html);
$htmlWithDocumentType = $this->ensureDocumentType($htmlWithSelfClosingSlashes);
return $this->addContentTypeMetaTag($htmlWithDocumentType);
}
/**
* Makes sure that the passed HTML has a document type.
*
* @param string $html
*
* @return string HTML with document type
*/
private function ensureDocumentType($html)
{
$hasDocumentType = \stripos($html, '<!DOCTYPE') !== false;
if ($hasDocumentType) {
return $html;
}
return static::DEFAULT_DOCUMENT_TYPE . $html;
}
/**
* Adds a Content-Type meta tag for the charset.
*
* This method also ensures that there is a HEAD element.
*
* @param string $html
*
* @return string the HTML with the meta tag added
*/
private function addContentTypeMetaTag($html)
{
$hasContentTypeMetaTag = \stripos($html, 'Content-Type') !== false;
if ($hasContentTypeMetaTag) {
return $html;
}
// We are trying to insert the meta tag to the right spot in the DOM.
// If we just prepended it to the HTML, we would lose attributes set to the HTML tag.
$hasHeadTag = \stripos($html, '<head') !== false;
$hasHtmlTag = \stripos($html, '<html') !== false;
if ($hasHeadTag) {
$reworkedHtml = \preg_replace('/<head(.*?)>/i', '<head$1>' . static::CONTENT_TYPE_META_TAG, $html);
} elseif ($hasHtmlTag) {
$reworkedHtml = \preg_replace(
'/<html(.*?)>/i',
'<html$1><head>' . static::CONTENT_TYPE_META_TAG . '</head>',
$html
);
} else {
$reworkedHtml = static::CONTENT_TYPE_META_TAG . $html;
}
return $reworkedHtml;
}
/**
* Makes sure that any self-closing tags not recognized as such by PHP's DOMDocument implementation have a
* self-closing slash.
*
* @param string $html
*
* @return string HTML with problematic tags converted.
*/
private function ensurePhpUnrecognizedSelfClosingTagsAreXml($html)
{
return \preg_replace(
'%<' . static::PHP_UNRECOGNIZED_VOID_TAGNAME_MATCHER . '\\b[^>]*+(?<!/)(?=>)%',
'$0/',
$html
);
}
/**
* Checks that $this->domDocument has a BODY element and adds it if it is missing.
*
* @return void
*/
private function ensureExistenceOfBodyElement()
{
if ($this->domDocument->getElementsByTagName('body')->item(0) !== null) {
return;
}
$htmlElement = $this->domDocument->getElementsByTagName('html')->item(0);
$htmlElement->appendChild($this->domDocument->createElement('body'));
}
}

View File

@ -1,320 +0,0 @@
<?php
namespace Pelago\Emogrifier\HtmlProcessor;
/**
* This HtmlProcessor can convert style HTML attributes to the corresponding other visual HTML attributes,
* e.g. it converts style="width: 100px" to width="100".
*
* It will only add attributes, but leaves the style attribute untouched.
*
* To trigger the conversion, call the convertCssToVisualAttributes method.
*
* @internal This class currently is a new technology preview, and its API is still in flux. Don't use it in production.
*
* @author Oliver Klee <github@oliverklee.de>
*/
class CssToAttributeConverter extends AbstractHtmlProcessor
{
/**
* This multi-level array contains simple mappings of CSS properties to
* HTML attributes. If a mapping only applies to certain HTML nodes or
* only for certain values, the mapping is an object with a whitelist
* of nodes and values.
*
* @var mixed[][]
*/
private $cssToHtmlMap = [
'background-color' => [
'attribute' => 'bgcolor',
],
'text-align' => [
'attribute' => 'align',
'nodes' => ['p', 'div', 'td'],
'values' => ['left', 'right', 'center', 'justify'],
],
'float' => [
'attribute' => 'align',
'nodes' => ['table', 'img'],
'values' => ['left', 'right'],
],
'border-spacing' => [
'attribute' => 'cellspacing',
'nodes' => ['table'],
],
];
/**
* @var string[][]
*/
private static $parsedCssCache = [];
/**
* Maps the CSS from the style nodes to visual HTML attributes.
*
* @return CssToAttributeConverter fluent interface
*/
public function convertCssToVisualAttributes()
{
/** @var \DOMElement $node */
foreach ($this->getAllNodesWithStyleAttribute() as $node) {
$inlineStyleDeclarations = $this->parseCssDeclarationsBlock($node->getAttribute('style'));
$this->mapCssToHtmlAttributes($inlineStyleDeclarations, $node);
}
return $this;
}
/**
* Returns a list with all DOM nodes that have a style attribute.
*
* @return \DOMNodeList
*/
private function getAllNodesWithStyleAttribute()
{
$xPath = new \DOMXPath($this->domDocument);
return $xPath->query('//*[@style]');
}
/**
* Parses a CSS declaration block into property name/value pairs.
*
* Example:
*
* The declaration block
*
* "color: #000; font-weight: bold;"
*
* will be parsed into the following array:
*
* "color" => "#000"
* "font-weight" => "bold"
*
* @param string $cssDeclarationsBlock the CSS declarations block without the curly braces, may be empty
*
* @return string[]
* the CSS declarations with the property names as array keys and the property values as array values
*/
private function parseCssDeclarationsBlock($cssDeclarationsBlock)
{
if (isset(self::$parsedCssCache[$cssDeclarationsBlock])) {
return self::$parsedCssCache[$cssDeclarationsBlock];
}
$properties = [];
$declarations = \preg_split('/;(?!base64|charset)/', $cssDeclarationsBlock);
foreach ($declarations as $declaration) {
$matches = [];
if (!\preg_match('/^([A-Za-z\\-]+)\\s*:\\s*(.+)$/s', \trim($declaration), $matches)) {
continue;
}
$propertyName = \strtolower($matches[1]);
$propertyValue = $matches[2];
$properties[$propertyName] = $propertyValue;
}
self::$parsedCssCache[$cssDeclarationsBlock] = $properties;
return $properties;
}
/**
* Applies $styles to $node.
*
* This method maps CSS styles to HTML attributes and adds those to the
* node.
*
* @param string[] $styles the new CSS styles taken from the global styles to be applied to this node
* @param \DOMElement $node node to apply styles to
*
* @return void
*/
private function mapCssToHtmlAttributes(array $styles, \DOMElement $node)
{
foreach ($styles as $property => $value) {
// Strip !important indicator
$value = \trim(\str_replace('!important', '', $value));
$this->mapCssToHtmlAttribute($property, $value, $node);
}
}
/**
* Tries to apply the CSS style to $node as an attribute.
*
* This method maps a CSS rule to HTML attributes and adds those to the node.
*
* @param string $property the name of the CSS property to map
* @param string $value the value of the style rule to map
* @param \DOMElement $node node to apply styles to
*
* @return void
*/
private function mapCssToHtmlAttribute($property, $value, \DOMElement $node)
{
if (!$this->mapSimpleCssProperty($property, $value, $node)) {
$this->mapComplexCssProperty($property, $value, $node);
}
}
/**
* Looks up the CSS property in the mapping table and maps it if it matches the conditions.
*
* @param string $property the name of the CSS property to map
* @param string $value the value of the style rule to map
* @param \DOMElement $node node to apply styles to
*
* @return bool true if the property can be mapped using the simple mapping table
*/
private function mapSimpleCssProperty($property, $value, \DOMElement $node)
{
if (!isset($this->cssToHtmlMap[$property])) {
return false;
}
$mapping = $this->cssToHtmlMap[$property];
$nodesMatch = !isset($mapping['nodes']) || \in_array($node->nodeName, $mapping['nodes'], true);
$valuesMatch = !isset($mapping['values']) || \in_array($value, $mapping['values'], true);
if (!$nodesMatch || !$valuesMatch) {
return false;
}
$node->setAttribute($mapping['attribute'], $value);
return true;
}
/**
* Maps CSS properties that need special transformation to an HTML attribute.
*
* @param string $property the name of the CSS property to map
* @param string $value the value of the style rule to map
* @param \DOMElement $node node to apply styles to
*
* @return void
*/
private function mapComplexCssProperty($property, $value, \DOMElement $node)
{
switch ($property) {
case 'background':
$this->mapBackgroundProperty($node, $value);
break;
case 'width':
// intentional fall-through
case 'height':
$this->mapWidthOrHeightProperty($node, $value, $property);
break;
case 'margin':
$this->mapMarginProperty($node, $value);
break;
case 'border':
$this->mapBorderProperty($node, $value);
break;
default:
}
}
/**
* @param \DOMElement $node node to apply styles to
* @param string $value the value of the style rule to map
*
* @return void
*/
private function mapBackgroundProperty(\DOMElement $node, $value)
{
// parse out the color, if any
$styles = \explode(' ', $value);
$first = $styles[0];
if (!\is_numeric($first[0]) && \strpos($first, 'url') !== 0) {
// as this is not a position or image, assume it's a color
$node->setAttribute('bgcolor', $first);
}
}
/**
* @param \DOMElement $node node to apply styles to
* @param string $value the value of the style rule to map
* @param string $property the name of the CSS property to map
*
* @return void
*/
private function mapWidthOrHeightProperty(\DOMElement $node, $value, $property)
{
// only parse values in px and %, but not values like "auto"
if (!\preg_match('/^(\\d+)(px|%)$/', $value)) {
return;
}
$number = \preg_replace('/[^0-9.%]/', '', $value);
$node->setAttribute($property, $number);
}
/**
* @param \DOMElement $node node to apply styles to
* @param string $value the value of the style rule to map
*
* @return void
*/
private function mapMarginProperty(\DOMElement $node, $value)
{
if (!$this->isTableOrImageNode($node)) {
return;
}
$margins = $this->parseCssShorthandValue($value);
if ($margins['left'] === 'auto' && $margins['right'] === 'auto') {
$node->setAttribute('align', 'center');
}
}
/**
* @param \DOMElement $node node to apply styles to
* @param string $value the value of the style rule to map
*
* @return void
*/
private function mapBorderProperty(\DOMElement $node, $value)
{
if (!$this->isTableOrImageNode($node)) {
return;
}
if ($value === 'none' || $value === '0') {
$node->setAttribute('border', '0');
}
}
/**
* @param \DOMElement $node
*
* @return bool
*/
private function isTableOrImageNode(\DOMElement $node)
{
return $node->nodeName === 'table' || $node->nodeName === 'img';
}
/**
* Parses a shorthand CSS value and splits it into individual values
*
* @param string $value a string of CSS value with 1, 2, 3 or 4 sizes
* For example: padding: 0 auto;
* '0 auto' is split into top: 0, left: auto, bottom: 0,
* right: auto.
*
* @return string[] an array of values for top, right, bottom and left (using these as associative array keys)
*/
private function parseCssShorthandValue($value)
{
$values = \preg_split('/\\s+/', $value);
$css = [];
$css['top'] = $values[0];
$css['right'] = (\count($values) > 1) ? $values[1] : $css['top'];
$css['bottom'] = (\count($values) > 2) ? $values[2] : $css['top'];
$css['left'] = (\count($values) > 3) ? $values[3] : $css['right'];
return $css;
}
}

View File

@ -1,18 +0,0 @@
<?php
namespace Pelago\Emogrifier\HtmlProcessor;
/**
* Normalizes HTML:
* - add a document type (HTML5) if missing
* - disentangle incorrectly nested tags
* - add HEAD and BODY elements (if they are missing)
* - reformat the HTML
*
* @internal This class currently is a new technology preview, and its API is still in flux. Don't use it in production.
*
* @author Oliver Klee <github@oliverklee.de>
*/
class HtmlNormalizer extends AbstractHtmlProcessor
{
}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,7 @@
<?php
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -315,7 +318,7 @@ if ( ! class_exists( 'WC_Eval_Math', false ) ) {
*/
private static function trigger( $msg ) {
self::$last_error = $msg;
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
if ( ! Constants::is_true( 'DOING_AJAX' ) && Constants::is_true( 'WP_DEBUG' ) ) {
echo "\nError found in:";
self::debugPrintCallingFunction();
trigger_error( $msg, E_USER_WARNING );

View File

@ -5,6 +5,8 @@
* @package WooCommerce\Log Handlers
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
@ -165,7 +167,7 @@ class WC_Log_Handler_DB extends WC_Log_Handler {
*
* @see http://php.net/manual/en/function.debug-backtrace.php#refsect1-function.debug-backtrace-parameters
*/
if ( defined( 'DEBUG_BACKTRACE_IGNORE_ARGS' ) ) {
if ( Constants::is_defined( 'DEBUG_BACKTRACE_IGNORE_ARGS' ) ) {
$debug_backtrace_arg = DEBUG_BACKTRACE_IGNORE_ARGS; // phpcs:ignore PHPCompatibility.Constants.NewConstants.debug_backtrace_ignore_argsFound
} else {
$debug_backtrace_arg = false;

View File

@ -5,6 +5,8 @@
* @package WooCommerce\Log Handlers
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
@ -146,7 +148,7 @@ class WC_Log_Handler_File extends WC_Log_Handler {
$temphandle = @fopen( $file, 'w+' ); // @codingStandardsIgnoreLine.
@fclose( $temphandle ); // @codingStandardsIgnoreLine.
if ( defined( 'FS_CHMOD_FILE' ) ) {
if ( Constants::is_defined( 'FS_CHMOD_FILE' ) ) {
@chmod( $file, FS_CHMOD_FILE ); // @codingStandardsIgnoreLine.
}
}

View File

@ -55,10 +55,15 @@ class WC_Shipping_Flat_Rate extends WC_Shipping_Method {
* Evaluate a cost from a sum/string.
*
* @param string $sum Sum of shipping.
* @param array $args Args.
* @param array $args Args, must contain `cost` and `qty` keys. Having `array()` as default is for back compat reasons.
* @return string
*/
protected function evaluate_cost( $sum, $args = array() ) {
// Add warning for subclasses.
if ( ! is_array( $args ) || ! array_key_exists( 'qty', $args ) || ! array_key_exists( 'cost', $args ) ) {
wc_doing_it_wrong( __FUNCTION__, '$args must contain `cost` and `qty` keys.', '4.0.1' );
}
include_once WC()->plugin_path() . '/includes/libraries/class-wc-eval-math.php';
// Allow 3rd parties to process shipping cost arguments.
@ -264,7 +269,14 @@ class WC_Shipping_Flat_Rate extends WC_Shipping_Method {
$value = wp_kses_post( trim( wp_unslash( $value ) ) );
$value = str_replace( array( get_woocommerce_currency_symbol(), html_entity_decode( get_woocommerce_currency_symbol() ) ), '', $value );
// Thrown an error on the front end if the evaluate_cost will fail.
if ( false === $this->evaluate_cost( $value ) ) {
$dummy_cost = $this->evaluate_cost(
$value,
array(
'cost' => 1,
'qty' => 1,
)
);
if ( false === $dummy_cost ) {
throw new Exception( WC_Eval_Math::$last_error );
}
return $value;

View File

@ -62,9 +62,10 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
$this->init_settings();
// Define user set variables.
$this->title = $this->get_option( 'title' );
$this->min_amount = $this->get_option( 'min_amount', 0 );
$this->requires = $this->get_option( 'requires' );
$this->title = $this->get_option( 'title' );
$this->min_amount = $this->get_option( 'min_amount', 0 );
$this->requires = $this->get_option( 'requires' );
$this->ignore_discounts = $this->get_option( 'ignore_discounts' );
// Actions.
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
@ -104,6 +105,13 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
'default' => '0',
'desc_tip' => true,
),
'ignore_discounts' => array(
'title' => __( 'Ignore coupons discounts', 'woocommerce' ),
'type' => 'checkbox',
'description' => __( 'Discounts will not be applied to the minimum order amount.', 'woocommerce' ),
'default' => 'no',
'desc_tip' => true,
),
);
}
@ -143,11 +151,15 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
$total = WC()->cart->get_displayed_subtotal();
if ( WC()->cart->display_prices_including_tax() ) {
$total = round( $total - ( WC()->cart->get_discount_total() + WC()->cart->get_discount_tax() ), wc_get_price_decimals() );
} else {
$total = round( $total - WC()->cart->get_discount_total(), wc_get_price_decimals() );
$total = $total - WC()->cart->get_discount_tax();
}
if ( 'no' === $this->ignore_discounts ) {
$total = $total - WC()->cart->get_discount_total();
}
$total = round( $total, wc_get_price_decimals() );
if ( $total >= $this->min_amount ) {
$has_met_min_amount = true;
}
@ -203,10 +215,13 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
function wcFreeShippingShowHideMinAmountField( el ) {
var form = $( el ).closest( 'form' );
var minAmountField = $( '#woocommerce_free_shipping_min_amount', form ).closest( 'tr' );
var ignoreDiscountField = $( '#woocommerce_free_shipping_ignore_discounts', form ).closest( 'tr' );
if ( 'coupon' === $( el ).val() || '' === $( el ).val() ) {
minAmountField.hide();
ignoreDiscountField.hide();
} else {
minAmountField.show();
ignoreDiscountField.show();
}
}

View File

@ -104,6 +104,14 @@ class WC_Shortcode_Checkout {
return;
}
// Add notice if logged in customer is trying to pay for guest order.
if ( ! $order->get_user_id() && is_user_logged_in() ) {
// If order has does not have same billing email then current logged in user then show warning.
if ( $order->get_billing_email() !== wp_get_current_user()->user_email ) {
wc_print_notice( __( 'You are paying for a guest order. Please continue with payment only if you recognize this order.', 'woocommerce' ), 'error' );
}
}
// Logged in customer trying to pay for someone else's order.
if ( ! current_user_can( 'pay_for_order', $order_id ) ) {
throw new Exception( __( 'This order cannot be paid for. Please contact us if you need assistance.', 'woocommerce' ) );

View File

@ -593,7 +593,14 @@ class WC_Shortcode_Products {
// Remove ordering query arguments which may have been added by get_catalog_ordering_args.
WC()->query->remove_ordering_args();
return $results;
/**
* Filter shortcode products query results.
*
* @since 4.0.0
* @param stdClass $results Query results.
* @param WC_Shortcode_Products $this WC_Shortcode_Products instance.
*/
return apply_filters( 'woocommerce_shortcode_products_query_results', $results, $this );
}
/**

View File

@ -6,6 +6,8 @@
* @package WooCommerce/Classes
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -78,7 +80,7 @@ class WC_Twenty_Nineteen {
$styles['woocommerce-general'] = array(
'src' => str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/css/twenty-nineteen.css',
'deps' => '',
'version' => WC_VERSION,
'version' => Constants::get_constant( 'WC_VERSION' ),
'media' => 'all',
'has_rtl' => true,
);

View File

@ -6,6 +6,8 @@
* @package WooCommerce/Classes
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -49,7 +51,7 @@ class WC_Twenty_Seventeen {
$styles['woocommerce-general'] = array(
'src' => str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/css/twenty-seventeen.css',
'deps' => '',
'version' => WC_VERSION,
'version' => Constants::get_constant( 'WC_VERSION' ),
'media' => 'all',
'has_rtl' => true,
);

View File

@ -6,6 +6,8 @@
* @package WooCommerce/Classes
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -92,7 +94,7 @@ class WC_Twenty_Twenty {
$styles['woocommerce-general'] = array(
'src' => str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/css/twenty-twenty.css',
'deps' => '',
'version' => WC_VERSION,
'version' => Constants::get_constant( 'WC_VERSION' ),
'media' => 'all',
'has_rtl' => true,
);

View File

@ -5,6 +5,8 @@
* @package WooCommerce\Tracks
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -44,7 +46,7 @@ class WC_Tracks_Client {
*/
public static function maybe_set_identity_cookie() {
// Do not set on AJAX requests.
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
if ( Constants::is_true( 'DOING_AJAX' ) ) {
return;
}
@ -69,10 +71,7 @@ class WC_Tracks_Client {
}
// Don't set cookie on API requests.
if (
! ( defined( 'REST_REQUEST' ) && REST_REQUEST ) &&
! ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST )
) {
if ( ! Constants::is_true( 'REST_REQUEST' ) && ! Constants::is_true( 'XMLRPC_REQUEST' ) ) {
wc_setcookie( 'tk_ai', $anon_id );
}
}
@ -144,8 +143,8 @@ class WC_Tracks_Client {
public static function get_identity( $user_id ) {
$jetpack_lib = '/tracks/client.php';
if ( class_exists( 'Jetpack' ) && defined( 'JETPACK__VERSION' ) ) {
if ( version_compare( JETPACK__VERSION, '7.5', '<' ) ) {
if ( class_exists( 'Jetpack' ) && Constants::is_defined( 'JETPACK__VERSION' ) ) {
if ( version_compare( Constants::get_constant( 'JETPACK__VERSION' ), '7.5', '<' ) ) {
if ( file_exists( jetpack_require_lib_dir() . $jetpack_lib ) ) {
include_once jetpack_require_lib_dir() . $jetpack_lib;
if ( function_exists( 'jetpack_tracks_get_identity' ) ) {

View File

@ -5,6 +5,8 @@
* @package WooCommerce\Tracks
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -52,10 +54,7 @@ class WC_Tracks_Event {
* @return bool Always returns true.
*/
public function record() {
if (
wp_doing_ajax() ||
( defined( 'REST_REQUEST' ) && REST_REQUEST )
) {
if ( wp_doing_ajax() || Constants::is_true( 'REST_REQUEST' ) ) {
return WC_Tracks_Client::record_event( $this );
}

View File

@ -5,6 +5,8 @@
* @package WooCommerce\Tracks
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -71,7 +73,7 @@ class WC_Products_Tracking {
// Only track category creation from the edit product screen or the
// category management screen (which both occur via AJAX).
if (
! defined( 'DOING_AJAX' ) ||
! Constants::is_defined( 'DOING_AJAX' ) ||
empty( $_POST['action'] ) ||
(
// Product Categories screen.

View File

@ -8,6 +8,8 @@
* @version 2.5.0
*/
use Automattic\Jetpack\Constants;
defined( 'ABSPATH' ) || exit;
/**
@ -288,7 +290,7 @@ function wc_cart_totals_coupon_html( $coupon ) {
}
$discount_amount_html = apply_filters( 'woocommerce_coupon_discount_amount_html', $discount_amount_html, $coupon );
$coupon_html = $discount_amount_html . ' <a href="' . esc_url( add_query_arg( 'remove_coupon', rawurlencode( $coupon->get_code() ), defined( 'WOOCOMMERCE_CHECKOUT' ) ? wc_get_checkout_url() : wc_get_cart_url() ) ) . '" class="woocommerce-remove-coupon" data-coupon="' . esc_attr( $coupon->get_code() ) . '">' . __( '[Remove]', 'woocommerce' ) . '</a>';
$coupon_html = $discount_amount_html . ' <a href="' . esc_url( add_query_arg( 'remove_coupon', rawurlencode( $coupon->get_code() ), Constants::is_defined( 'WOOCOMMERCE_CHECKOUT' ) ? wc_get_checkout_url() : wc_get_cart_url() ) ) . '" class="woocommerce-remove-coupon" data-coupon="' . esc_attr( $coupon->get_code() ) . '">' . __( '[Remove]', 'woocommerce' ) . '</a>';
echo wp_kses( apply_filters( 'woocommerce_cart_totals_coupon_html', $coupon_html, $coupon, $discount_amount_html ), array_replace_recursive( wp_kses_allowed_html( 'post' ), array( 'a' => array( 'data-coupon' => true ) ) ) ); // phpcs:ignore PHPCompatibility.PHP.NewFunctions.array_replace_recursiveFound
}

View File

@ -8,6 +8,8 @@
* @version 2.3.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -93,7 +95,7 @@ if ( ! function_exists( 'is_cart' ) ) {
function is_cart() {
$page_id = wc_get_page_id( 'cart' );
return ( $page_id && is_page( $page_id ) ) || defined( 'WOOCOMMERCE_CART' ) || wc_post_content_has_shortcode( 'woocommerce_cart' );
return ( $page_id && is_page( $page_id ) ) || Constants::is_defined( 'WOOCOMMERCE_CART' ) || wc_post_content_has_shortcode( 'woocommerce_cart' );
}
}
@ -107,7 +109,7 @@ if ( ! function_exists( 'is_checkout' ) ) {
function is_checkout() {
$page_id = wc_get_page_id( 'checkout' );
return ( $page_id && is_page( $page_id ) ) || wc_post_content_has_shortcode( 'woocommerce_checkout' ) || apply_filters( 'woocommerce_is_checkout', false ) || defined( 'WOOCOMMERCE_CHECKOUT' );
return ( $page_id && is_page( $page_id ) ) || wc_post_content_has_shortcode( 'woocommerce_checkout' ) || apply_filters( 'woocommerce_is_checkout', false ) || Constants::is_defined( 'WOOCOMMERCE_CHECKOUT' );
}
}
@ -262,7 +264,7 @@ if ( ! function_exists( 'is_ajax' ) ) {
* @return bool
*/
function is_ajax() {
return function_exists( 'wp_doing_ajax' ) ? wp_doing_ajax() : defined( 'DOING_AJAX' );
return function_exists( 'wp_doing_ajax' ) ? wp_doing_ajax() : Constants::is_defined( 'DOING_AJAX' );
}
}

View File

@ -8,6 +8,8 @@
* @version 3.3.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -157,7 +159,7 @@ function wc_update_order( $args ) {
* @param string $name Template name (default: '').
*/
function wc_get_template_part( $slug, $name = '' ) {
$cache_key = sanitize_key( implode( '-', array( 'template-part', $slug, $name, WC_VERSION ) ) );
$cache_key = sanitize_key( implode( '-', array( 'template-part', $slug, $name, Constants::get_constant( 'WC_VERSION' ) ) ) );
$template = (string) wp_cache_get( $cache_key, 'woocommerce' );
if ( ! $template ) {
@ -205,7 +207,7 @@ function wc_get_template_part( $slug, $name = '' ) {
* @param string $default_path Default path. (default: '').
*/
function wc_get_template( $template_name, $args = array(), $template_path = '', $default_path = '' ) {
$cache_key = sanitize_key( implode( '-', array( 'template', $template_name, $template_path, $default_path, WC_VERSION ) ) );
$cache_key = sanitize_key( implode( '-', array( 'template', $template_name, $template_path, $default_path, Constants::get_constant( 'WC_VERSION' ) ) ) );
$template = (string) wp_cache_get( $cache_key, 'woocommerce' );
if ( ! $template ) {
@ -320,7 +322,7 @@ function get_woocommerce_currency() {
/**
* Get full list of currency codes.
*
* Currency Symbols and mames should follow the Unicode CLDR recommendation (http://cldr.unicode.org/translation/currency-names)
* Currency symbols and names should follow the Unicode CLDR recommendation (http://cldr.unicode.org/translation/currency-names)
*
* @return array
*/
@ -503,21 +505,17 @@ function get_woocommerce_currencies() {
return $currencies;
}
/**
* Get Currency symbol.
* Get all available Currency symbols.
*
* Currency Symbols and mames should follow the Unicode CLDR recommendation (http://cldr.unicode.org/translation/currency-names)
* Currency symbols and names should follow the Unicode CLDR recommendation (http://cldr.unicode.org/translation/currency-names)
*
* @param string $currency Currency. (default: '').
* @return string
* @since 4.1.0
* @return array
*/
function get_woocommerce_currency_symbol( $currency = '' ) {
if ( ! $currency ) {
$currency = get_woocommerce_currency();
}
function get_woocommerce_currency_symbols() {
$symbols = apply_filters(
$symbols = apply_filters(
'woocommerce_currency_symbols',
array(
'AED' => '&#x62f;.&#x625;',
@ -602,7 +600,7 @@ function get_woocommerce_currency_symbol( $currency = '' ) {
'KRW' => '&#8361;',
'KWD' => '&#x62f;.&#x643;',
'KYD' => '&#36;',
'KZT' => 'KZT',
'KZT' => '&#8376;',
'LAK' => '&#8365;',
'LBP' => '&#x644;.&#x644;',
'LKR' => '&#xdbb;&#xdd4;',
@ -641,7 +639,7 @@ function get_woocommerce_currency_symbol( $currency = '' ) {
'QAR' => '&#x631;.&#x642;',
'RMB' => '&yen;',
'RON' => 'lei',
'RSD' => '&#x434;&#x438;&#x43d;.',
'RSD' => '&#1088;&#1089;&#1076;',
'RUB' => '&#8381;',
'RWF' => 'Fr',
'SAR' => '&#x631;.&#x633;',
@ -686,6 +684,25 @@ function get_woocommerce_currency_symbol( $currency = '' ) {
'ZMW' => 'ZK',
)
);
return $symbols;
}
/**
* Get Currency symbol.
*
* Currency symbols and names should follow the Unicode CLDR recommendation (http://cldr.unicode.org/translation/currency-names)
*
* @param string $currency Currency. (default: '').
* @return string
*/
function get_woocommerce_currency_symbol( $currency = '' ) {
if ( ! $currency ) {
$currency = get_woocommerce_currency();
}
$symbols = get_woocommerce_currency_symbols();
$currency_symbol = isset( $symbols[ $currency ] ) ? $symbols[ $currency ] : '';
return apply_filters( 'woocommerce_currency_symbol', $currency_symbol, $currency );
@ -887,7 +904,7 @@ function wc_print_js() {
function wc_setcookie( $name, $value, $expire = 0, $secure = false, $httponly = false ) {
if ( ! headers_sent() ) {
setcookie( $name, $value, $expire, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN, $secure, apply_filters( 'woocommerce_cookie_httponly', $httponly, $name, $value, $expire, $secure ) );
} elseif ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
} elseif ( Constants::is_true( 'WP_DEBUG' ) ) {
headers_sent( $file, $line );
trigger_error( "{$name} cookie cannot be set - headers already sent by {$file} on line {$line}", E_USER_NOTICE ); // @codingStandardsIgnoreLine
}
@ -901,7 +918,11 @@ function wc_setcookie( $name, $value, $expire = 0, $secure = false, $httponly =
* @return string the URL.
*/
function get_woocommerce_api_url( $path ) {
$version = defined( 'WC_API_REQUEST_VERSION' ) ? WC_API_REQUEST_VERSION : substr( WC_API::VERSION, 0, 1 );
if ( Constants::is_defined( 'WC_API_REQUEST_VERSION' ) ) {
$version = Constants::get_constant( 'WC_API_REQUEST_VERSION' );
} else {
$version = substr( WC_API::VERSION, 0, 1 );
}
$url = get_home_url( null, "wc-api/v{$version}/", is_ssl() ? 'https' : 'http' );
@ -1262,7 +1283,7 @@ function wc_transaction_query( $type = 'start', $force = false ) {
wc_maybe_define_constant( 'WC_USE_TRANSACTIONS', true );
if ( WC_USE_TRANSACTIONS || $force ) {
if ( Constants::is_true( 'WC_USE_TRANSACTIONS' ) || $force ) {
switch ( $type ) {
case 'commit':
$wpdb->query( 'COMMIT' );
@ -1817,14 +1838,12 @@ function wc_print_r( $expression, $return = false ) {
* @return array
*/
function wc_register_default_log_handler( $handlers ) {
if ( defined( 'WC_LOG_HANDLER' ) && class_exists( WC_LOG_HANDLER ) ) {
$handler_class = WC_LOG_HANDLER;
$default_handler = new $handler_class();
} else {
$default_handler = new WC_Log_Handler_File();
$handler_class = Constants::get_constant( 'WC_LOG_HANDLER' );
if ( ! class_exists( $handler_class ) ) {
$handler_class = WC_Log_Handler_File::class;
}
array_push( $handlers, $default_handler );
array_push( $handlers, new $handler_class() );
return $handlers;
}
@ -2269,3 +2288,13 @@ function wc_load_cart() {
WC()->initialize_session();
WC()->initialize_cart();
}
/**
* Test whether the context of execution comes from async action scheduler.
*
* @since 4.0.0
* @return bool
*/
function wc_is_running_from_async_action_scheduler() {
return isset( $_REQUEST['action'] ) && 'as_async_request_queue_runner' === $_REQUEST['action'];
}

View File

@ -10,6 +10,8 @@
* @version 3.3.0
*/
use Automattic\Jetpack\Constants;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -897,7 +899,7 @@ function woocommerce_compile_less_styles() {
* @return string
*/
function woocommerce_calc_shipping_backwards_compatibility( $value ) {
if ( defined( 'WC_UPDATING' ) ) {
if ( Constants::is_defined( 'WC_UPDATING' ) ) {
return $value;
}
return 'disabled' === get_option( 'woocommerce_ship_to_countries' ) ? 'no' : 'yes';

View File

@ -683,6 +683,10 @@ function wc_refund_payment( $order, $amount, $reason = '' ) {
* @param array $refunded_line_items Refunded items list.
*/
function wc_restock_refunded_items( $order, $refunded_line_items ) {
if ( ! apply_filters( 'woocommerce_can_restock_refunded_items', true, $order, $refunded_line_items ) ) {
return;
}
$line_items = $order->get_items();
foreach ( $line_items as $item_id => $item ) {

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