Merge branch 'master' of github.com:woocommerce/woocommerce into feature/webhook-delivery-logging

This commit is contained in:
Gerhard Potgieter 2017-11-15 14:28:14 +02:00
commit 3524ed2cf0
107 changed files with 7029 additions and 6019 deletions

4
.gitignore vendored
View File

@ -6,6 +6,10 @@ project.properties
.project
.settings*
.idea
.vscode
*.sublime-project
*.sublime-workspace
.sublimelinterrc
# Grunt
/node_modules/

View File

@ -9,17 +9,21 @@ php:
- 7.1
env:
- WP_VERSION=latest WP_MULTISITE=0 PHP_LATEST_STABLE=7.1
- WP_VERSION=latest WP_MULTISITE=0
# Additional tests against stable PHP (min recommended version is 5.6) and past supported versions of WP.
# Additional tests against stable PHP (min recommended version is 5.6) and past supported versions of WP
# and code coverage report.
matrix:
fast_finish: true
include:
- php: 5.3
env: WP_VERSION=latest WP_MULTISITE=0 PHP_LATEST_STABLE=7.1
dist: precise
- php: 5.2
env: WP_VERSION=latest WP_MULTISITE=0 PHP_LATEST_STABLE=7.1
dist: precise
- php: 7.1
env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1
allow_failures:
- env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1
before_script:
- export PATH="$HOME/.composer/vendor/bin:$PATH"

View File

@ -31,7 +31,7 @@
* Tweak - On checkout, improved the field locale logic to work without clearing default values.
* Tweak - Change title of customer invoice email for clarity.
* Tweak - Use custom event instead of blur to trigger validation.
* Tweak - Various selectWoo usibility improvements and better support for keyboard controls on AJAX multiselect elements.
* Tweak - Various selectWoo usability improvements and better support for keyboard controls on AJAX multiselect elements.
* Tweak - Various setup Wizard improvements.
* Dev - Fixed orders date query when querying by meta data.
* Dev - In the CSV exporter, added a filter to process meta values before export.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -3139,6 +3139,10 @@ img.help_tip {
box-sizing: border-box;
}
input[size] {
width: auto !important;
}
// Ignore nested inputs.
table {
select,
@ -3265,6 +3269,105 @@ img.help_tip {
.wc_emails_wrapper {
padding: 0 15px 10px 0;
}
.woocommerce-thumbnail-cropping {
margin: 0 40px 1em 0;
padding: 0;
display:inline-block;
vertical-align: top;
input[type=radio] {
vertical-align: top;
margin-top: 2px;
}
label {
display: inline-block;
span.description {
margin-top: .5em;
display:block;
color: #999;
}
span.woocommerce-thumbnail-cropping-aspect-ratio {
margin-top: .5em;
display:block;
}
}
li {
margin: 5px 0 1.5em;
padding: 0;
}
}
.woocommerce-thumbnail-preview {
display:inline-block;
width: 320px;
vertical-align: top;
h4 {
margin-top: 0;
}
.woocommerce-thumbnail-preview-block {
text-align: center;
width: 100px;
margin: 0 10px 0 0;
float: left;
.woocommerce-thumbnail-preview-block__image {
width: 90px;
height: 90px;
border: 5px solid #fff;
background: #eee;
box-shadow: 0 1px 1px #ccc;
margin: 0 0 10px;
position: relative;
overflow: hidden;
&:before,
&:after {
content: "";
display: block;
width: 30px;
height: 30px;
background: rgba(0,0,0,.1);
position: absolute;
top: 50%;
left: 50%;
margin-left: -20px;
margin-top: -20px;
}
&:before {
margin-top: -10px;
margin-left: -10px;
background: rgba(0,0,0,.1);
}
}
.woocommerce-thumbnail-preview-block__text {
width: 50%;
background: #ddd;
margin: 0 auto 10px;
height: 6px;
}
.woocommerce-thumbnail-preview-block__button {
width: 30px;
height: 5px;
border: 8px solid #fff;
background: #ededed;
box-shadow: 0 0 0 1px #ddd;
margin: 0 auto;
border-radius: 2px;
}
&:nth-child(3) {
.woocommerce-thumbnail-preview-block__text {
width: 75%;
}
}
&:nth-child(4) {
.woocommerce-thumbnail-preview-block__text {
width: 35%;
}
}
}
.woocommerce-thumbnail-preview-block:last-child {
margin: 0;
}
}
}
}
@ -4555,6 +4658,10 @@ img.ui-datepicker-trigger {
/**
* Reports
*/
.woocommerce-reports-remove-filter {
color: red;
text-decoration: none;
}
.woocommerce-reports-wrap,
.woocommerce-reports-wide {
&.woocommerce-reports-wrap {
@ -4568,6 +4675,10 @@ img.ui-datepicker-trigger {
zoom: 1;
}
.widefat th {
padding: 7px;
}
.widefat td {
vertical-align: top;
padding: 7px;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -102,6 +102,7 @@
div.summary {
float: right;
width: 48%;
clear: none;
}
.woocommerce-tabs {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -9,8 +9,7 @@
*/
$.fn.WCBackboneModal = function( options ) {
return this.each( function() {
var WCeachBackboneModal = new $.WCBackboneModal( $( this ), options )
( WCeachBackboneModal() );
( new $.WCBackboneModal( $( this ), options ) );
});
};
@ -25,12 +24,10 @@
var settings = $.extend( {}, $.WCBackboneModal.defaultOptions, options );
if ( settings.template ) {
var BackboneModal = new $.WCBackboneModal.View({
target: settings.template,
string: settings.variable
});
BackboneModal();
new $.WCBackboneModal.View({
target: settings.template,
string: settings.variable
});
}
};

View File

@ -743,12 +743,8 @@ jQuery( function ( $ ) {
$.post( woocommerce_admin_meta_boxes.ajax_url, data, function( response ) {
if ( true === response.success ) {
wc_meta_boxes_order_items.reload_items();
if ( 'fully_refunded' === response.data.status ) {
// Redirect to same page for show the refunded status
window.location.href = window.location.href;
}
// Redirect to same page for show the refunded status
window.location.href = window.location.href;
} else {
window.alert( response.data.error );
wc_meta_boxes_order_items.reload_items();

View File

@ -124,4 +124,43 @@
$( this ).closest( 'td' ).find( 'select' ).trigger( 'change' );
return false;
});
// Thumbnail cropping option updates and preview.
$( '.woocommerce-thumbnail-cropping' )
.on( 'change input', 'input', function() {
var value = $( '.woocommerce-thumbnail-cropping input:checked' ).val(),
$preview_images = $( '.woocommerce-thumbnail-preview-block__image' );
if ( 'custom' === value ) {
var width_ratio = Math.max( parseInt( $( 'input[name="thumbnail_cropping_aspect_ratio_width"]' ).val(), 10 ), 1 ),
height_ratio = Math.max( parseInt( $( 'input[name="thumbnail_cropping_aspect_ratio_height"]' ).val(), 10 ), 1 ),
height = ( 90 / width_ratio ) * height_ratio;
$preview_images.animate( { height: height + 'px' }, 200 );
$( '.woocommerce-thumbnail-cropping-aspect-ratio' ).slideDown( 200 );
} else if ( 'uncropped' === value ) {
var heights = [ '120', '60', '80' ];
$preview_images.each( function( index, element ) {
var height = heights[ index ];
$( element ).animate( { height: height + 'px' }, 200 );
} );
$( '.woocommerce-thumbnail-cropping-aspect-ratio' ).hide();
} else {
$preview_images.animate( { height: '90px' }, 200 );
$( '.woocommerce-thumbnail-cropping-aspect-ratio' ).hide();
}
return false;
});
$( '.woocommerce-thumbnail-cropping' ).find( 'input' ).change();
})( jQuery );

View File

@ -1 +1 @@
!function(t){t("select#woocommerce_allowed_countries").change(function(){"specific"===t(this).val()?(t(this).closest("tr").next("tr").hide(),t(this).closest("tr").next().next("tr").show()):"all_except"===t(this).val()?(t(this).closest("tr").next("tr").show(),t(this).closest("tr").next().next("tr").hide()):(t(this).closest("tr").next("tr").hide(),t(this).closest("tr").next().next("tr").hide())}).change(),t("select#woocommerce_ship_to_countries").change(function(){"specific"===t(this).val()?t(this).closest("tr").next("tr").show():t(this).closest("tr").next("tr").hide()}).change(),t("input#woocommerce_manage_stock").change(function(){t(this).is(":checked")?t(this).closest("tbody").find(".manage_stock_field").closest("tr").show():t(this).closest("tbody").find(".manage_stock_field").closest("tr").hide()}).change(),t(".colorpick").iris({change:function(e,i){t(this).parent().find(".colorpickpreview").css({backgroundColor:i.color.toString()})},hide:!0,border:!0}).on("click focus",function(e){e.stopPropagation(),t(".iris-picker").hide(),t(this).closest("td").find(".iris-picker").show(),t(this).data("original-value",t(this).val())}).on("change",function(){t(this).is(".iris-error")&&(t(this).data("original-value").match(/^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/)?t(this).val(t(this).data("original-value")).change():t(this).val("").change())}),t("body").on("click",function(){t(".iris-picker").hide()}),t(function(){var e=!1;t("input, textarea, select, checkbox").change(function(){e=!0}),t(".woo-nav-tab-wrapper a").click(function(){window.onbeforeunload=e?function(){return woocommerce_settings_params.i18n_nav_warning}:""}),t(".submit input").click(function(){window.onbeforeunload=""})}),t("table.wc_gateways tbody, table.wc_shipping tbody").sortable({items:"tr",cursor:"move",axis:"y",handle:"td.sort",scrollSensitivity:40,helper:function(e,i){return i.children().each(function(){t(this).width(t(this).width())}),i.css("left","0"),i},start:function(t,e){e.item.css("background-color","#f6f6f6")},stop:function(t,e){e.item.removeAttr("style")}}),t(".woocommerce").on("click",".select_all",function(){return t(this).closest("td").find("select option").attr("selected","selected"),t(this).closest("td").find("select").trigger("change"),!1}),t(".woocommerce").on("click",".select_none",function(){return t(this).closest("td").find("select option").removeAttr("selected"),t(this).closest("td").find("select").trigger("change"),!1})}(jQuery);
!function(t){t("select#woocommerce_allowed_countries").change(function(){"specific"===t(this).val()?(t(this).closest("tr").next("tr").hide(),t(this).closest("tr").next().next("tr").show()):"all_except"===t(this).val()?(t(this).closest("tr").next("tr").show(),t(this).closest("tr").next().next("tr").hide()):(t(this).closest("tr").next("tr").hide(),t(this).closest("tr").next().next("tr").hide())}).change(),t("select#woocommerce_ship_to_countries").change(function(){"specific"===t(this).val()?t(this).closest("tr").next("tr").show():t(this).closest("tr").next("tr").hide()}).change(),t("input#woocommerce_manage_stock").change(function(){t(this).is(":checked")?t(this).closest("tbody").find(".manage_stock_field").closest("tr").show():t(this).closest("tbody").find(".manage_stock_field").closest("tr").hide()}).change(),t(".colorpick").iris({change:function(e,i){t(this).parent().find(".colorpickpreview").css({backgroundColor:i.color.toString()})},hide:!0,border:!0}).on("click focus",function(e){e.stopPropagation(),t(".iris-picker").hide(),t(this).closest("td").find(".iris-picker").show(),t(this).data("original-value",t(this).val())}).on("change",function(){t(this).is(".iris-error")&&(t(this).data("original-value").match(/^\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/)?t(this).val(t(this).data("original-value")).change():t(this).val("").change())}),t("body").on("click",function(){t(".iris-picker").hide()}),t(function(){var e=!1;t("input, textarea, select, checkbox").change(function(){e=!0}),t(".woo-nav-tab-wrapper a").click(function(){window.onbeforeunload=e?function(){return woocommerce_settings_params.i18n_nav_warning}:""}),t(".submit input").click(function(){window.onbeforeunload=""})}),t("table.wc_gateways tbody, table.wc_shipping tbody").sortable({items:"tr",cursor:"move",axis:"y",handle:"td.sort",scrollSensitivity:40,helper:function(e,i){return i.children().each(function(){t(this).width(t(this).width())}),i.css("left","0"),i},start:function(t,e){e.item.css("background-color","#f6f6f6")},stop:function(t,e){e.item.removeAttr("style")}}),t(".woocommerce").on("click",".select_all",function(){return t(this).closest("td").find("select option").attr("selected","selected"),t(this).closest("td").find("select").trigger("change"),!1}),t(".woocommerce").on("click",".select_none",function(){return t(this).closest("td").find("select option").removeAttr("selected"),t(this).closest("td").find("select").trigger("change"),!1}),t(".woocommerce-thumbnail-cropping").on("change","input",function(){var e=t(".woocommerce-thumbnail-cropping input:checked").val(),i=t(".woocommerce-thumbnail-preview-block__image");if("custom"===e){var o=90/Math.max(parseInt(t('input[name="thumbnail_cropping_aspect_ratio_width"]').val(),10),1)*Math.max(parseInt(t('input[name="thumbnail_cropping_aspect_ratio_height"]').val(),10),1);i.animate({height:o+"px"},200),t(".woocommerce-thumbnail-cropping-aspect-ratio").slideDown(200)}else if("uncropped"===e){var c=["120","60","80"];i.each(function(e,i){var o=c[e];t(i).animate({height:o+"px"},200)}),t(".woocommerce-thumbnail-cropping-aspect-ratio").hide()}else i.animate({height:"90px"},200),t(".woocommerce-thumbnail-cropping-aspect-ratio").hide();return!1}),t(".woocommerce-thumbnail-cropping").find("input").change()}(jQuery);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -185,12 +185,10 @@ jQuery( function( $ ) {
* @param {Object} evt The JQuery event.
*/
shipping_method_selected: function( evt ) {
var target = evt.currentTarget;
var shipping_methods = {};
$( 'select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]' ).each( function() {
shipping_methods[ $( target ).data( 'index' ) ] = $( target ).val();
shipping_methods[ $( this ).data( 'index' ) ] = $( this ).val();
} );
block( $( 'div.cart_totals' ) );

View File

@ -391,11 +391,7 @@ jQuery( function( $ ) {
// Lose focus for all fields
$form.find( '.input-text, select, input:checkbox' ).trigger( 'validate' ).blur();
// Scroll to top
$( 'html, body' ).animate( {
scrollTop: ( $( 'form.checkout' ).offset().top - 100 )
}, 1000 );
wc_checkout_form.scroll_to_notices();
}
// Re-init methods
@ -512,10 +508,28 @@ jQuery( function( $ ) {
wc_checkout_form.$checkout_form.prepend( '<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">' + error_message + '</div>' );
wc_checkout_form.$checkout_form.removeClass( 'processing' ).unblock();
wc_checkout_form.$checkout_form.find( '.input-text, select, input:checkbox' ).trigger( 'validate' ).blur();
$( 'html, body' ).animate({
scrollTop: ( $( 'form.checkout' ).offset().top - 100 )
}, 1000 );
wc_checkout_form.scroll_to_notices();
$( document.body ).trigger( 'checkout_error' );
},
scroll_to_notices: function() {
var scrollElement = $( '.woocommerce-NoticeGroup-updateOrderReview, .woocommerce-NoticeGroup-checkout' ),
isSmoothScrollSupported = 'scrollBehavior' in document.documentElement.style;
if ( ! scrollElement.length ) {
scrollElement = $( '.form.checkout' );
}
if ( scrollElement.length ) {
if ( isSmoothScrollSupported ) {
scrollElement[0].scrollIntoView({
behavior: 'smooth'
});
} else {
$( 'html, body' ).animate( {
scrollTop: ( scrollElement.offset().top - 100 )
}, 1000 );
}
}
}
};

File diff suppressed because one or more lines are too long

View File

@ -11,7 +11,9 @@
"squizlabs/php_codesniffer": "*",
"wp-coding-standards/wpcs": "0.13.1",
"phpunit/phpunit": "6.2.3",
"woocommerce/woocommerce-git-hooks": "1.0.2"
"woocommerce/woocommerce-git-hooks": "1.0.3",
"wimg/php-compatibility": "^8.0",
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.3"
},
"scripts": {
"pre-update-cmd": [
@ -21,11 +23,9 @@
"WooCommerce\\GitHooks\\Hooks::preHooks"
],
"post-install-cmd": [
"\"vendor/bin/phpcs\" --config-set installed_paths vendor/wp-coding-standards/wpcs",
"WooCommerce\\GitHooks\\Hooks::postHooks"
],
"post-update-cmd": [
"\"vendor/bin/phpcs\" --config-set installed_paths vendor/wp-coding-standards/wpcs",
"WooCommerce\\GitHooks\\Hooks::postHooks"
]
}

189
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "5268174ad56d2293f14e24b931afeb63",
"content-hash": "9a9c7e81cc3a30935c03b1b2d64c201c",
"packages": [
{
"name": "composer/installers",
@ -125,6 +125,74 @@
}
],
"packages-dev": [
{
"name": "dealerdirect/phpcodesniffer-composer-installer",
"version": "v0.4.3",
"source": {
"type": "git",
"url": "https://github.com/DealerDirect/phpcodesniffer-composer-installer.git",
"reference": "63c0ec0ac286d31651d3c70e5bf76ad87db3ba23"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/DealerDirect/phpcodesniffer-composer-installer/zipball/63c0ec0ac286d31651d3c70e5bf76ad87db3ba23",
"reference": "63c0ec0ac286d31651d3c70e5bf76ad87db3ba23",
"shasum": ""
},
"require": {
"composer-plugin-api": "^1.0",
"php": "^5.3|^7",
"squizlabs/php_codesniffer": "*"
},
"require-dev": {
"composer/composer": "*",
"wimg/php-compatibility": "^8.0"
},
"suggest": {
"dealerdirect/qa-tools": "All the PHP QA tools you'll need"
},
"type": "composer-plugin",
"extra": {
"class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin"
},
"autoload": {
"psr-4": {
"Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Franck Nijhof",
"email": "f.nijhof@dealerdirect.nl",
"homepage": "http://workingatdealerdirect.eu",
"role": "Developer"
}
],
"description": "PHP_CodeSniffer Standards Composer Installer Plugin",
"homepage": "http://workingatdealerdirect.eu",
"keywords": [
"PHPCodeSniffer",
"PHP_CodeSniffer",
"code quality",
"codesniffer",
"composer",
"installer",
"phpcs",
"plugin",
"qa",
"quality",
"standard",
"standards",
"style guide",
"stylecheck",
"tests"
],
"time": "2017-09-18T07:49:36+00:00"
},
{
"name": "doctrine/instantiator",
"version": "1.1.0",
@ -181,37 +249,40 @@
},
{
"name": "myclabs/deep-copy",
"version": "1.6.1",
"version": "1.7.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102"
"reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/8e6e04167378abf1ddb4d3522d8755c5fd90d102",
"reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
"reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
"php": "^5.6 || ^7.0"
},
"require-dev": {
"doctrine/collections": "1.*",
"phpunit/phpunit": "~4.1"
"doctrine/collections": "^1.0",
"doctrine/common": "^2.6",
"phpunit/phpunit": "^4.1"
},
"type": "library",
"autoload": {
"psr-4": {
"DeepCopy\\": "src/DeepCopy/"
}
},
"files": [
"src/DeepCopy/deep_copy.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "Create deep copies (clones) of your objects",
"homepage": "https://github.com/myclabs/DeepCopy",
"keywords": [
"clone",
"copy",
@ -219,7 +290,7 @@
"object",
"object graph"
],
"time": "2017-04-12T18:52:22+00:00"
"time": "2017-10-19T19:58:43+00:00"
},
{
"name": "phar-io/manifest",
@ -534,16 +605,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "5.2.2",
"version": "5.2.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "8ed1902a57849e117b5651fc1a5c48110946c06b"
"reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/8ed1902a57849e117b5651fc1a5c48110946c06b",
"reference": "8ed1902a57849e117b5651fc1a5c48110946c06b",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d",
"reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d",
"shasum": ""
},
"require": {
@ -552,7 +623,7 @@
"php": "^7.0",
"phpunit/php-file-iterator": "^1.4.2",
"phpunit/php-text-template": "^1.2.1",
"phpunit/php-token-stream": "^1.4.11 || ^2.0",
"phpunit/php-token-stream": "^2.0",
"sebastian/code-unit-reverse-lookup": "^1.0.1",
"sebastian/environment": "^3.0",
"sebastian/version": "^2.0.1",
@ -594,7 +665,7 @@
"testing",
"xunit"
],
"time": "2017-08-03T12:40:43+00:00"
"time": "2017-11-03T13:47:33+00:00"
},
{
"name": "phpunit/php-file-iterator",
@ -972,30 +1043,30 @@
},
{
"name": "sebastian/comparator",
"version": "2.0.2",
"version": "2.1.0",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "ae068fede81d06e7bb9bb46a367210a3d3e1fe6a"
"reference": "1174d9018191e93cb9d719edec01257fc05f8158"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/ae068fede81d06e7bb9bb46a367210a3d3e1fe6a",
"reference": "ae068fede81d06e7bb9bb46a367210a3d3e1fe6a",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1174d9018191e93cb9d719edec01257fc05f8158",
"reference": "1174d9018191e93cb9d719edec01257fc05f8158",
"shasum": ""
},
"require": {
"php": "^7.0",
"sebastian/diff": "^2.0",
"sebastian/exporter": "^3.0"
"sebastian/exporter": "^3.1"
},
"require-dev": {
"phpunit/phpunit": "^6.0"
"phpunit/phpunit": "^6.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
"dev-master": "2.1.x-dev"
}
},
"autoload": {
@ -1026,13 +1097,13 @@
}
],
"description": "Provides the functionality to compare PHP values for equality",
"homepage": "http://www.github.com/sebastianbergmann/comparator",
"homepage": "https://github.com/sebastianbergmann/comparator",
"keywords": [
"comparator",
"compare",
"equality"
],
"time": "2017-08-03T07:14:59+00:00"
"time": "2017-11-03T07:16:52+00:00"
},
{
"name": "sebastian/diff",
@ -1626,17 +1697,69 @@
"time": "2016-11-23T20:04:58+00:00"
},
{
"name": "woocommerce/woocommerce-git-hooks",
"version": "1.0.2",
"name": "wimg/php-compatibility",
"version": "8.0.1",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-git-hooks.git",
"reference": "f0eea8aa392c822f0f3b9cd0b31f92bfa4de6a0c"
"url": "https://github.com/wimg/PHPCompatibility.git",
"reference": "4c4385fb891dff0501009670f988d4fe36785249"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-git-hooks/zipball/f0eea8aa392c822f0f3b9cd0b31f92bfa4de6a0c",
"reference": "f0eea8aa392c822f0f3b9cd0b31f92bfa4de6a0c",
"url": "https://api.github.com/repos/wimg/PHPCompatibility/zipball/4c4385fb891dff0501009670f988d4fe36785249",
"reference": "4c4385fb891dff0501009670f988d4fe36785249",
"shasum": ""
},
"require": {
"php": ">=5.3",
"squizlabs/php_codesniffer": "^2.2 || ^3.0.2"
},
"conflict": {
"squizlabs/php_codesniffer": "2.6.2"
},
"require-dev": {
"phpunit/phpunit": "^4.0 || ^5.0 || ^6.0"
},
"suggest": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.1"
},
"type": "phpcodesniffer-standard",
"autoload": {
"psr-4": {
"PHPCompatibility\\": "PHPCompatibility/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"authors": [
{
"name": "Wim Godden",
"role": "lead"
}
],
"description": "A set of sniffs for PHP_CodeSniffer that checks for PHP version compatibility.",
"homepage": "http://techblog.wimgodden.be/tag/codesniffer/",
"keywords": [
"compatibility",
"phpcs",
"standards"
],
"time": "2017-08-07T19:39:05+00:00"
},
{
"name": "woocommerce/woocommerce-git-hooks",
"version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-git-hooks.git",
"reference": "a9ea000877a996c57862aa81f0e61c04d8973d7e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-git-hooks/zipball/a9ea000877a996c57862aa81f0e61c04d8973d7e",
"reference": "a9ea000877a996c57862aa81f0e61c04d8973d7e",
"shasum": ""
},
"type": "scripts",
@ -1656,7 +1779,7 @@
}
],
"description": "WooCommerce Git Hooks",
"time": "2017-09-27T16:03:36+00:00"
"time": "2017-11-09T18:27:22+00:00"
},
{
"name": "wp-coding-standards/wpcs",

View File

@ -1,21 +1,26 @@
ID,Type,SKU,Name,Published,Is featured?,Visibility in catalog,Short description,Description,Date sale price starts,Date sale price ends,Tax status,Tax class,In stock?,Stock,Backorders allowed?,Sold individually?,Weight (kg),Length (cm),Width (cm),Height (cm),Allow customer reviews?,Purchase note,Sale price,Regular price,Categories,Tags,Shipping class,Images,Download limit,Download expiry days,Parent,Grouped products,Upsells,Cross-sells,External URL,Button text,Attribute 1 name,Attribute 1 value(s),Attribute 1 visible,Attribute 1 global
,simple,woo-beanie,Beanie,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,18,20,Accessories,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/beanie.jpg,,,,,,,,,Color,Red,1,1
,simple,woo-belt,Belt,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,55,65,Accessories,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/belt.jpg,,,,,,,,,,,,
,simple,woo-cap,Cap,1,1,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,16,18,Accessories,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/cap.jpg,,,,,,,,,Color,Yellow,1,1
,simple,woo-sunglasses,Sunglasses,1,1,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,90,Accessories,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/sunglasses.jpg,,,,,,,,,,,,
,simple,woo-hoodie-with-logo,Hoodie with Logo,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,45,Hoodies,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-logo.jpg,,,,,,,,,Color,Blue,1,1
,simple,woo-hoodie-with-pocket,Hoodie with Pocket,1,1,hidden,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,35,45,Hoodies,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-pocket.jpg,,,,,,,,,Color,Gray,1,1
,simple,woo-hoodie-with-zipper,Hoodie with Zipper,1,1,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,45,Hoodies,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-zipper.jpg,,,,,,,,,,,,
,variable,woo-hoodie,Hoodie,1,0,visible,This is a variable product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,42,45,Hoodies,,,"https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-blue.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-green.jpg",,,,,,,,,Color,"Blue, Green, Red",1,1
,simple,woo-long-sleeve-tee,Long Sleeve Tee,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,25,T-Shirts,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/long-sleeve-tee.jpg,,,,,,,,,Color,Green,1,1
,simple,woo-polo,Polo,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,20,T-Shirts,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/polo.jpg,,,,,,,,,Color,Blue,1,1
,simple,woo-tshirt,T-Shirt,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,18,T-Shirts,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/tshirt.jpg,,,,,,,,,Color,Gray,1,1
,variable,woo-vneck-tee,V-Neck T-Shirt,1,1,visible,This is a variable product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,18,T-Shirts,,,"https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vneck-tee.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-green.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-blue.jpg",,,,,,,,,Color,"Blue, Green, Red",1,1
,"simple, downloadable, virtual",woo-album,Album,1,0,visible,"This is a simple, virtual product.","Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,1,,,15,Music,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/album.jpg,-1,-1,,,,,,,,,,
,"simple, downloadable, virtual",woo-single,Single,1,0,visible,"This is a simple, virtual product.","Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,1,,2,3,Music,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg,-1,-1,,,,,,,,,,
,variation,woo-vneck-tee-red,V-Neck T-Shirt - Red,1,0,visible,This is a product variation.,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,20,,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vneck-tee.jpg,,,woo-vneck-tee,,,,,,Color,Red,,1
,variation,woo-vneck-tee-green,V-Neck T-Shirt - Green,1,0,visible,This is a product variation.,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,20,,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-green.jpg,,,woo-vneck-tee,,,,,,Color,Green,,1
,variation,woo-vneck-tee-blue,V-Neck T-Shirt - Blue,1,0,visible,This is a product variation.,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,15,,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-blue.jpg,,,woo-vneck-tee,,,,,,Color,Blue,,1
,variation,woo-hoodie-red,Hoodie - Red,1,0,visible,This is a product variation.,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,42,45,,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie.jpg,,,woo-hoodie,,,,,,Color,Red,,1
,variation,woo-hoodie-green,Hoodie - Green,1,0,visible,This is a product variation.,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,45,,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-green.jpg,,,woo-hoodie,,,,,,Color,Green,,1
,variation,woo-hoodie-blue,Hoodie - Blue,1,0,visible,This is a product variation.,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,45,,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-blue.jpg,,,woo-hoodie,,,,,,Color,Blue,,1
Type,SKU,Name,Published,Is featured?,Visibility in catalog,Short description,Description,Date sale price starts,Date sale price ends,Tax status,Tax class,In stock?,Stock,Backorders allowed?,Sold individually?,Weight (kg),Length (cm),Width (cm),Height (cm),Allow customer reviews?,Purchase note,Sale price,Regular price,Categories,Tags,Shipping class,Images,Download limit,Download expiry days,Parent,Grouped products,Upsells,Cross-sells,External URL,Button text,Position,Attribute 1 name,Attribute 1 value(s),Attribute 1 visible,Attribute 1 global,Attribute 2 name,Attribute 2 value(s),Attribute 2 visible,Attribute 2 global,Download 1 name,Download 1 URL,Download 2 name,Download 2 URL
variable,woo-vneck-tee,V-Neck T-Shirt,1,1,visible,This is a variable product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,,T-Shirts,,,"https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vneck-tee.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-green.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-blue.jpg",,,,,,,,,0,Color,"Blue, Green, Red",1,1,Size,"Large, Medium, Small",1,1,,,,
variable,woo-hoodie,Hoodie,1,0,visible,This is a variable product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,,Hoodies,,,"https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-blue.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-green.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-logo.jpg",,,,,,,,,0,Color,"Blue, Green, Red",1,1,Logo,"Yes, No",1,0,,,,
simple,woo-beanie,Beanie,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,18,20,Accessories,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/beanie.jpg,,,,,,,,,0,Color,Red,1,1,,,,,,,,
simple,woo-belt,Belt,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,55,65,Accessories,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/belt.jpg,,,,,,,,,0,,,,,,,,,,,,
simple,woo-cap,Cap,1,1,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,16,18,Accessories,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/cap.jpg,,,,,,,,,0,Color,Yellow,1,1,,,,,,,,
simple,woo-sunglasses,Sunglasses,1,1,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,90,Accessories,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/sunglasses.jpg,,,,,,,,,0,,,,,,,,,,,,
simple,woo-hoodie-with-logo,Hoodie with Logo,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,45,Hoodies,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-logo.jpg,,,,,,,,,0,Color,Blue,1,1,,,,,,,,
simple,woo-hoodie-with-pocket,Hoodie with Pocket,1,1,hidden,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,35,45,Hoodies,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-pocket.jpg,,,,,,,,,0,Color,Gray,1,1,,,,,,,,
simple,woo-hoodie-with-zipper,Hoodie with Zipper,1,1,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,45,Hoodies,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-zipper.jpg,,,,,,,,,0,,,,,,,,,,,,
simple,woo-long-sleeve-tee,Long Sleeve Tee,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,25,T-Shirts,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/long-sleeve-tee.jpg,,,,,,,,,0,Color,Green,1,1,,,,,,,,
simple,woo-polo,Polo,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,20,T-Shirts,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/polo.jpg,,,,,,,,,0,Color,Blue,1,1,,,,,,,,
simple,woo-tshirt,T-Shirt,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,18,T-Shirts,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/tshirt.jpg,,,,,,,,,0,Color,Gray,1,1,,,,,,,,
"simple, downloadable, virtual",woo-album,Album,1,0,visible,"This is a simple, virtual product.","Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,1,,,15,Music,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/album.jpg,1,1,,,,,,,0,,,,,,,,,Single 1,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg,Single 2,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/album.jpg
"simple, downloadable, virtual",woo-single,Single,1,0,visible,"This is a simple, virtual product.","Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,1,,2,3,Music,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg,1,1,,,,,,,0,,,,,,,,,Single,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg,,
variation,woo-vneck-tee-red,V-Neck T-Shirt - Red,1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,20,,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vneck-tee.jpg,,,woo-vneck-tee,,,,,,0,Color,Red,,1,Size,,,1,,,,
variation,woo-vneck-tee-green,V-Neck T-Shirt - Green,1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,20,,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-green.jpg,,,woo-vneck-tee,,,,,,0,Color,Green,,1,Size,,,1,,,,
variation,woo-vneck-tee-blue,V-Neck T-Shirt - Blue,1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,15,,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-blue.jpg,,,woo-vneck-tee,,,,,,0,Color,Blue,,1,Size,,,1,,,,
variation,woo-hoodie-red,"Hoodie - Red, No",1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,42,45,,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie.jpg,,,woo-hoodie,,,,,,1,Color,Red,,1,Logo,No,,0,,,,
variation,woo-hoodie-green,"Hoodie - Green, No",1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,45,,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-green.jpg,,,woo-hoodie,,,,,,2,Color,Green,,1,Logo,No,,0,,,,
variation,woo-hoodie-blue,"Hoodie - Blue, No",1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,45,,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-blue.jpg,,,woo-hoodie,,,,,,3,Color,Blue,,1,Logo,No,,0,,,,
simple,Woo-tshirt-logo,T-Shirt with Logo,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,18,T-Shirts,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/11/t-shirt-with-logo.jpg,,,,,,,,,0,Color,Gray,1,1,,,,,,,,
simple,Woo-beanie-logo,Beanie with Logo,1,0,visible,This is a simple product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,18,20,Accessories,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/11/beanie-with-logo.jpg,,,,,,,,,0,Color,Red,1,1,,,,,,,,
grouped,logo-collection,Logo Collection,1,0,visible,This is a grouped product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,,,,,"https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/11/logo.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/11/beanie-with-logo.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/11/t-shirt-with-logo.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-logo.jpg",,,,"woo-hoodie-with-logo, woo-tshirt, woo-beanie",,,,,0,,,,,,,,,,,,
external,wp-pennant,WordPress Pennant,1,0,visible,This is an external product.,"Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.",,,taxable,,1,,0,0,,,,,1,,,11.05,Accessories,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/11/pennant.jpg,,,,,,,https://mercantile.wordpress.org/product/wordpress-pennant/,Buy on the WordPress swag store!,0,,,,,,,,,,,,
variation,woo-hoodie-blue-logo,"Hoodie - Blue, Yes",1,0,visible,,"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa.",,,taxable,,1,,0,0,,,,,0,,,45,,,,https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-logo.jpg,,,woo-hoodie,,,,,,0,Color,Blue,,1,Logo,Yes,,0,,,,

1 Type SKU Name Published Is featured? Visibility in catalog Short description Description Date sale price starts Date sale price ends Tax status Tax class In stock? Stock Backorders allowed? Sold individually? Weight (kg) Length (cm) Width (cm) Height (cm) Allow customer reviews? Purchase note Sale price Regular price Categories Tags Shipping class Images Download limit Download expiry days Parent Grouped products Upsells Cross-sells External URL Button text Position Attribute 1 name Attribute 1 value(s) Attribute 1 visible Attribute 1 global Attribute 2 name Attribute 2 value(s) Attribute 2 visible Attribute 2 global ID Download 1 name Download 1 URL Download 2 name Download 2 URL
2 simple variable woo-beanie woo-vneck-tee Beanie V-Neck T-Shirt 1 0 1 visible This is a simple product. This is a variable product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 18 20 Accessories T-Shirts https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/beanie.jpg https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vneck-tee.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-green.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-blue.jpg 0 Color Red Blue, Green, Red 1 1 Size Large, Medium, Small 1 1
3 simple variable woo-belt woo-hoodie Belt Hoodie 1 0 visible This is a simple product. This is a variable product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 55 65 Accessories Hoodies https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/belt.jpg https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-blue.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-green.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-logo.jpg 0 Color Blue, Green, Red 1 1 Logo Yes, No 1 0
4 simple woo-cap woo-beanie Cap Beanie 1 1 0 visible This is a simple product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 16 18 18 20 Accessories https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/cap.jpg https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/beanie.jpg 0 Color Yellow Red 1 1
5 simple woo-sunglasses woo-belt Sunglasses Belt 1 1 0 visible This is a simple product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 55 90 65 Accessories https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/sunglasses.jpg https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/belt.jpg 0
6 simple woo-hoodie-with-logo woo-cap Hoodie with Logo Cap 1 0 1 visible This is a simple product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 16 45 18 Hoodies Accessories https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-logo.jpg https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/cap.jpg 0 Color Blue Yellow 1 1
7 simple woo-hoodie-with-pocket woo-sunglasses Hoodie with Pocket Sunglasses 1 1 hidden visible This is a simple product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 35 45 90 Hoodies Accessories https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-pocket.jpg https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/sunglasses.jpg 0 Color Gray 1 1
8 simple woo-hoodie-with-zipper woo-hoodie-with-logo Hoodie with Zipper Hoodie with Logo 1 1 0 visible This is a simple product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 45 Hoodies https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-zipper.jpg https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-logo.jpg 0 Color Blue 1 1
9 variable simple woo-hoodie woo-hoodie-with-pocket Hoodie Hoodie with Pocket 1 0 1 visible hidden This is a variable product. This is a simple product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 42 35 45 Hoodies https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-blue.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-green.jpg https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-pocket.jpg 0 Color Blue, Green, Red Gray 1 1
10 simple woo-long-sleeve-tee woo-hoodie-with-zipper Long Sleeve Tee Hoodie with Zipper 1 0 1 visible This is a simple product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 25 45 T-Shirts Hoodies https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/long-sleeve-tee.jpg https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-zipper.jpg 0 Color Green 1 1
11 simple woo-polo woo-long-sleeve-tee Polo Long Sleeve Tee 1 0 visible This is a simple product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 20 25 T-Shirts https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/polo.jpg https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/long-sleeve-tee.jpg 0 Color Blue Green 1 1
12 simple woo-tshirt woo-polo T-Shirt Polo 1 0 visible This is a simple product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 18 20 T-Shirts https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/tshirt.jpg https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/polo.jpg 0 Color Gray Blue 1 1
13 variable simple woo-vneck-tee woo-tshirt V-Neck T-Shirt T-Shirt 1 1 0 visible This is a variable product. This is a simple product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 18 T-Shirts https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vneck-tee.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-green.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-blue.jpg https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/tshirt.jpg 0 Color Blue, Green, Red Gray 1 1
14 simple, downloadable, virtual woo-album Album 1 0 visible This is a simple, virtual product. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa. taxable 1 0 0 1 15 Music https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/album.jpg -1 1 -1 1 0 Single 1 https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg Single 2 https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/album.jpg
15 simple, downloadable, virtual woo-single Single 1 0 visible This is a simple, virtual product. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa. taxable 1 0 0 1 2 3 Music https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg -1 1 -1 1 0 Single https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg
16 variation woo-vneck-tee-red V-Neck T-Shirt - Red 1 0 visible This is a product variation. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa. taxable 1 0 0 0 20 https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vneck-tee.jpg woo-vneck-tee 0 Color Red 1 Size 1
17 variation woo-vneck-tee-green V-Neck T-Shirt - Green 1 0 visible This is a product variation. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa. taxable 1 0 0 0 20 https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-green.jpg woo-vneck-tee 0 Color Green 1 Size 1
18 variation woo-vneck-tee-blue V-Neck T-Shirt - Blue 1 0 visible This is a product variation. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa. taxable 1 0 0 0 15 https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/vnech-tee-blue.jpg woo-vneck-tee 0 Color Blue 1 Size 1
19 variation woo-hoodie-red Hoodie - Red Hoodie - Red, No 1 0 visible This is a product variation. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa. taxable 1 0 0 0 42 45 https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie.jpg woo-hoodie 1 Color Red 1 Logo No 0
20 variation woo-hoodie-green Hoodie - Green Hoodie - Green, No 1 0 visible This is a product variation. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa. taxable 1 0 0 0 45 https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-green.jpg woo-hoodie 2 Color Green 1 Logo No 0
21 variation woo-hoodie-blue Hoodie - Blue Hoodie - Blue, No 1 0 visible This is a product variation. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa. taxable 1 0 0 0 45 https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/05/hoodie-blue.jpg woo-hoodie 3 Color Blue 1 Logo No 0
22 simple Woo-tshirt-logo T-Shirt with Logo 1 0 visible This is a simple product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 18 T-Shirts https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/11/t-shirt-with-logo.jpg 0 Color Gray 1 1
23 simple Woo-beanie-logo Beanie with Logo 1 0 visible This is a simple product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 18 20 Accessories https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/11/beanie-with-logo.jpg 0 Color Red 1 1
24 grouped logo-collection Logo Collection 1 0 visible This is a grouped product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/11/logo.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/11/beanie-with-logo.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/11/t-shirt-with-logo.jpg, https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-logo.jpg woo-hoodie-with-logo, woo-tshirt, woo-beanie 0
25 external wp-pennant WordPress Pennant 1 0 visible This is an external product. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. taxable 1 0 0 1 11.05 Accessories https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/11/pennant.jpg https://mercantile.wordpress.org/product/wordpress-pennant/ Buy on the WordPress swag store! 0
26 variation woo-hoodie-blue-logo Hoodie - Blue, Yes 1 0 visible Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sagittis orci ac odio dictum tincidunt. Donec ut metus leo. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed luctus, dui eu sagittis sodales, nulla nibh sagittis augue, vel porttitor diam enim non metus. Vestibulum aliquam augue neque. Phasellus tincidunt odio eget ullamcorper efficitur. Cras placerat ut turpis pellentesque vulputate. Nam sed consequat tortor. Curabitur finibus sapien dolor. Ut eleifend tellus nec erat pulvinar dignissim. Nam non arcu purus. Vivamus et massa massa. taxable 1 0 0 0 45 https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/hoodie-with-logo.jpg woo-hoodie 0 Color Blue 1 Logo Yes 0

File diff suppressed because it is too large Load Diff

View File

@ -842,17 +842,17 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
/**
* Remove item from the order.
*
* @param int $item_id
* @param int $item_id Item ID to delete.
* @return false|void
*/
public function remove_item( $item_id ) {
$item = $this->get_item( $item_id );
$item = $this->get_item( $item_id, false );
if ( ! $item || ! ( $items_key = $this->get_items_key( $item ) ) ) {
return false;
}
// Unset and remove later
// Unset and remove later.
$this->items_to_delete[] = $item;
unset( $this->items[ $items_key ][ $item->get_id() ] );
}

View File

@ -1172,13 +1172,15 @@ class WC_Product extends WC_Abstract_Legacy_Product {
$download_object = $download;
} else {
$download_object = new WC_Product_Download();
$download['previous_hash'] = isset( $download['previous_hash'] ) ? $download['previous_hash'] : '';
$file_hash = apply_filters( 'woocommerce_downloadable_file_hash', md5( $download['file'] ), $this->get_id(), $download['name'], $download['file'], $download['previous_hash'] );
$download_object->set_id( $file_hash );
// If we don't have a previous hash, generate UUID for download.
if ( empty( $download['download_id'] ) ) {
$download['download_id'] = wp_generate_uuid4();
}
$download_object->set_id( $download['download_id'] );
$download_object->set_name( $download['name'] );
$download_object->set_file( $download['file'] );
$download_object->set_previous_hash( $download['previous_hash'] );
}
// Validate the file extension.
@ -1763,12 +1765,12 @@ class WC_Product extends WC_Abstract_Legacy_Product {
/**
* Returns the main product image.
*
* @param string $size (default: 'shop_thumbnail').
* @param string $size (default: 'woocommerce_thumbnail').
* @param array $attr Image attributes.
* @param bool $placeholder True to return $placeholder if no image is found, or false to return an empty string.
* @return string
*/
public function get_image( $size = 'shop_thumbnail', $attr = array(), $placeholder = true ) {
public function get_image( $size = 'woocommerce_thumbnail', $attr = array(), $placeholder = true ) {
if ( has_post_thumbnail( $this->get_id() ) ) {
$image = get_the_post_thumbnail( $this->get_id(), $size, $attr );
} elseif ( ( $parent_id = wp_get_post_parent_id( $this->get_id() ) ) && has_post_thumbnail( $parent_id ) ) {

View File

@ -334,6 +334,10 @@ class WC_Admin_Log_Table_List extends WP_List_Table {
$where_conditions[] = 'source = %s';
$where_values[] = wc_clean( $_REQUEST['source'] );
}
if ( ! empty( $_REQUEST['s'] ) ) {
$where_conditions[] = 'message like %s';
$where_values[] = '%' . $wpdb->esc_like( wc_clean( wp_unslash( $_REQUEST['s'] ) ) ) . '%';
}
if ( ! empty( $where_conditions ) ) {
return $wpdb->prepare( 'WHERE 1 = 1 AND ' . implode( ' AND ', $where_conditions ), $where_values );

View File

@ -79,7 +79,7 @@ class WC_Admin_Notices {
* Reset notices for themes when switched or a new version of WC is installed.
*/
public static function reset_admin_notices() {
if ( ! current_theme_supports( 'woocommerce' ) && ! in_array( get_option( 'template' ), wc_get_core_supported_themes() ) ) {
if ( ! current_theme_supports( 'woocommerce' ) ) {
self::add_notice( 'theme_support' );
}
@ -216,7 +216,7 @@ class WC_Admin_Notices {
* Show the Theme Check notice.
*/
public static function theme_check_notice() {
if ( ! current_theme_supports( 'woocommerce' ) && ! in_array( get_option( 'template' ), wc_get_core_supported_themes() ) ) {
if ( ! current_theme_supports( 'woocommerce' ) ) {
include( 'views/html-notice-theme-support.php' );
} else {
self::remove_notice( 'theme_support' );

File diff suppressed because it is too large Load Diff

View File

@ -11,10 +11,12 @@
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
exit;
}
if ( ! class_exists( 'WC_Admin_Reports', false ) ) :
if ( class_exists( 'WC_Admin_Reports', false ) ) {
return;
}
/**
* WC_Admin_Reports Class.
@ -44,42 +46,48 @@ class WC_Admin_Reports {
'orders' => array(
'title' => __( 'Orders', 'woocommerce' ),
'reports' => array(
"sales_by_date" => array(
'sales_by_date' => array(
'title' => __( 'Sales by date', 'woocommerce' ),
'description' => '',
'hide_title' => true,
'callback' => array( __CLASS__, 'get_report' ),
),
"sales_by_product" => array(
'sales_by_product' => array(
'title' => __( 'Sales by product', 'woocommerce' ),
'description' => '',
'hide_title' => true,
'callback' => array( __CLASS__, 'get_report' ),
),
"sales_by_category" => array(
'sales_by_category' => array(
'title' => __( 'Sales by category', 'woocommerce' ),
'description' => '',
'hide_title' => true,
'callback' => array( __CLASS__, 'get_report' ),
),
"coupon_usage" => array(
'coupon_usage' => array(
'title' => __( 'Coupons by date', 'woocommerce' ),
'description' => '',
'hide_title' => true,
'callback' => array( __CLASS__, 'get_report' ),
),
'downloads' => array(
'title' => __( 'Customer downloads', 'woocommerce' ),
'description' => '',
'hide_title' => true,
'callback' => array( __CLASS__, 'get_report' ),
),
),
),
'customers' => array(
'title' => __( 'Customers', 'woocommerce' ),
'reports' => array(
"customers" => array(
'customers' => array(
'title' => __( 'Customers vs. guests', 'woocommerce' ),
'description' => '',
'hide_title' => true,
'callback' => array( __CLASS__, 'get_report' ),
),
"customer_list" => array(
'customer_list' => array(
'title' => __( 'Customer list', 'woocommerce' ),
'description' => '',
'hide_title' => true,
@ -90,20 +98,20 @@ class WC_Admin_Reports {
'stock' => array(
'title' => __( 'Stock', 'woocommerce' ),
'reports' => array(
"low_in_stock" => array(
'low_in_stock' => array(
'title' => __( 'Low in stock', 'woocommerce' ),
'description' => '',
'hide_title' => true,
'callback' => array( __CLASS__, 'get_report' ),
),
"out_of_stock" => array(
'out_of_stock' => array(
'title' => __( 'Out of stock', 'woocommerce' ),
'description' => '',
'hide_title' => true,
'callback' => array( __CLASS__, 'get_report' ),
),
"most_stocked" => array(
'title' => __( 'Most Stocked', 'woocommerce' ),
'most_stocked' => array(
'title' => __( 'Most stocked', 'woocommerce' ),
'description' => '',
'hide_title' => true,
'callback' => array( __CLASS__, 'get_report' ),
@ -116,13 +124,13 @@ class WC_Admin_Reports {
$reports['taxes'] = array(
'title' => __( 'Taxes', 'woocommerce' ),
'reports' => array(
"taxes_by_code" => array(
'taxes_by_code' => array(
'title' => __( 'Taxes by code', 'woocommerce' ),
'description' => '',
'hide_title' => true,
'callback' => array( __CLASS__, 'get_report' ),
),
"taxes_by_date" => array(
'taxes_by_date' => array(
'title' => __( 'Taxes by date', 'woocommerce' ),
'description' => '',
'hide_title' => true,
@ -169,5 +177,3 @@ class WC_Admin_Reports {
$report->output_report();
}
}
endif;

View File

@ -225,6 +225,9 @@ class WC_Admin_Settings {
if ( ! isset( $value['placeholder'] ) ) {
$value['placeholder'] = '';
}
if ( ! isset( $value['suffix'] ) ) {
$value['suffix'] = '';
}
// Custom attribute handling
$custom_attributes = array();
@ -289,7 +292,7 @@ class WC_Admin_Settings {
class="<?php echo esc_attr( $value['class'] ); ?>"
placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>"
<?php echo implode( ' ', $custom_attributes ); ?>
/> <?php echo $description; ?>
/><?php echo esc_html( $value['suffix'] ); ?> <?php echo $description; ?>
</td>
</tr><?php
break;
@ -491,7 +494,7 @@ class WC_Admin_Settings {
}
break;
// Image width settings
// Image width settings. @todo deprecate and remove in 4.0. No longer needed by core.
case 'image_width' :
$image_size = str_replace( '_image_size', '', $value['id'] );
@ -519,6 +522,62 @@ class WC_Admin_Settings {
</tr><?php
break;
// Thumbnail cropping setting. DEVELOPERS: This is private. Re-use at your own risk.
case 'thumbnail_cropping' :
$option_value = self::get_option( $value['id'], $value['default'] );
if ( strstr( $option_value, ':' ) ) {
$cropping_split = explode( ':', $option_value );
$width = max( 1, current( $cropping_split ) );
$height = max( 1, end( $cropping_split ) );
} else {
$width = 4;
$height = 3;
}
?><tr valign="top">
<th scope="row" class="titledesc"><?php echo esc_html( $value['title'] ) ?> <?php echo $tooltip_html; ?></th>
<td class="forminp">
<ul class="woocommerce-thumbnail-cropping">
<li>
<input type="radio" name="woocommerce_thumbnail_cropping" id="thumbnail_cropping_1_1" value="1:1" <?php checked( $option_value, '1:1' ); ?> />
<label for="thumbnail_cropping_1_1">1:1<br/><span class="description"><?php esc_html_e( 'Images will be cropped into a square', 'woocommerce' ); ?></span></label>
</li>
<li>
<input type="radio" name="woocommerce_thumbnail_cropping" id="thumbnail_cropping_custom" value="custom" <?php checked( ! in_array( $option_value, array( '1:1', 'uncropped' ), true ), true ); ?> />
<label for="thumbnail_cropping_custom">
<?php esc_html_e( 'Custom', 'woocommerce' ); ?><br/><span class="description"><?php esc_html_e( 'Images will be cropped to a custom aspect ratio', 'woocommerce' ); ?></span>
<span class="woocommerce-thumbnail-cropping-aspect-ratio">
<input name="thumbnail_cropping_aspect_ratio_width" type="text" pattern="\d*" size="3" value="<?php echo $width; ?>" /> : <input name="thumbnail_cropping_aspect_ratio_height" type="text" pattern="\d*" size="3" value="<?php echo $height; ?>" />
</span>
</label>
</li>
<li>
<input type="radio" name="woocommerce_thumbnail_cropping" id="thumbnail_cropping_uncropped" value="uncropped" <?php checked( $option_value, 'uncropped' ); ?> />
<label for="thumbnail_cropping_uncropped"><?php esc_html_e( 'Uncropped', 'woocommerce' ); ?><br/><span class="description"><?php esc_html_e( 'Images will display using the aspect ratio in which they were uploaded', 'woocommerce' ); ?></span></label>
</li>
</ul>
<div class="woocommerce-thumbnail-preview hide-if-no-js">
<h4><?php esc_html_e( 'Preview', 'woocommerce' ); ?></h4>
<div class="woocommerce-thumbnail-preview-block">
<div class="woocommerce-thumbnail-preview-block__image"></div>
<div class="woocommerce-thumbnail-preview-block__text"></div>
<div class="woocommerce-thumbnail-preview-block__button"></div>
</div>
<div class="woocommerce-thumbnail-preview-block">
<div class="woocommerce-thumbnail-preview-block__image"></div>
<div class="woocommerce-thumbnail-preview-block__text"></div>
<div class="woocommerce-thumbnail-preview-block__button"></div>
</div>
<div class="woocommerce-thumbnail-preview-block">
<div class="woocommerce-thumbnail-preview-block__image"></div>
<div class="woocommerce-thumbnail-preview-block__text"></div>
<div class="woocommerce-thumbnail-preview-block__button"></div>
</div>
</div>
</td>
</tr><?php
break;
// Single page selects
case 'single_select_page' :
@ -711,6 +770,15 @@ class WC_Admin_Settings {
$value['crop'] = $option['default']['crop'];
}
break;
case 'thumbnail_cropping' :
$value = wc_clean( $raw_value );
if ( 'custom' === $value ) {
$width_ratio = wc_clean( wp_unslash( $_POST['thumbnail_cropping_aspect_ratio_width'] ) );
$height_ratio = wc_clean( wp_unslash( $_POST['thumbnail_cropping_aspect_ratio_height'] ) );
$value = $width_ratio . ':' . $height_ratio;
}
break;
case 'select':
$allowed_values = empty( $option['options'] ) ? array() : array_keys( $option['options'] );
if ( empty( $option['default'] ) && empty( $allowed_values ) ) {

View File

@ -191,7 +191,7 @@ class WC_Meta_Box_Product_Data {
$downloads[] = array(
'name' => wc_clean( $file_names[ $i ] ),
'file' => wp_unslash( trim( $file_urls[ $i ] ) ),
'previous_hash' => wc_clean( $file_hashes[ $i ] ),
'download_id' => wc_clean( $file_hashes[ $i ] ),
);
}
}

View File

@ -22,16 +22,16 @@ if ( ! defined( 'ABSPATH' ) ) {
<tbody>
<tr>
<td>
<label><?php _e( 'Downloads remaining', 'woocommerce' ); ?></label>
<label><?php esc_html_e( 'Downloads remaining', 'woocommerce' ); ?></label>
<input type="hidden" name="permission_id[<?php echo $loop; ?>]" value="<?php echo esc_attr( $download->get_id() ); ?>" />
<input type="number" step="1" min="0" class="short" name="downloads_remaining[<?php echo $loop; ?>]" value="<?php echo esc_attr( $download->get_downloads_remaining() ); ?>" placeholder="<?php esc_attr_e( 'Unlimited', 'woocommerce' ); ?>" />
</td>
<td>
<label><?php _e( 'Access expires', 'woocommerce' ); ?></label>
<label><?php esc_html_e( 'Access expires', 'woocommerce' ); ?></label>
<input type="text" class="short date-picker" name="access_expires[<?php echo $loop; ?>]" value="<?php echo ! is_null( $download->get_access_expires() ) ? date_i18n( 'Y-m-d', $download->get_access_expires()->getTimestamp() ) : ''; ?>" maxlength="10" placeholder="<?php esc_attr_e( 'Never', 'woocommerce' ); ?>" pattern="<?php echo esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ); ?>" />
</td>
<td>
<label><?php _e( 'Customer download link', 'woocommerce' ); ?></label>
<label><?php esc_html_e( 'Customer download link', 'woocommerce' ); ?></label>
<?php
$download_link = add_query_arg( array(
'download_file' => $download->get_product_id(),
@ -43,6 +43,19 @@ if ( ! defined( 'ABSPATH' ) ) {
echo '<a href="' . esc_url( $download_link ) . '">' . esc_html( $file_count ) . '</a>';
?>
</td>
<td>
<label><?php esc_html_e( 'Downloads completed', 'woocommerce' ); ?></label>
<?php
$report_url = add_query_arg(
'permission_id',
rawurlencode( $download->get_id() ),
admin_url( 'admin.php?page=wc-reports&tab=orders&report=downloads' )
);
echo '<a href="' . esc_url( $report_url ) . '">';
echo esc_html( number_format_i18n( $download->get_download_count() ) );
echo '</a>';
?>
</td>
</tr>
</tbody>
</table>

View File

@ -18,7 +18,7 @@ $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnai
</td>
<td class="name" data-sort-value="<?php echo esc_attr( $item->get_name() ); ?>">
<?php
echo $product_link ? '<a href="' . esc_url( $product_link ) . '" class="wc-order-item-name">' . esc_html( $item->get_name() ) . '</a>' : '<div class="class="wc-order-item-name"">' . esc_html( $item->get_name() ) . '</div>';
echo $product_link ? '<a href="' . esc_url( $product_link ) . '" class="wc-order-item-name">' . esc_html( $item->get_name() ) . '</a>' : '<div class=""wc-order-item-name">' . esc_html( $item->get_name() ) . '</div>';
if ( $product && $product->get_sku() ) {
echo '<div class="wc-order-item-sku"><strong>' . __( 'SKU:', 'woocommerce' ) . '</strong> ' . esc_html( $product->get_sku() ) . '</div>';

View File

@ -0,0 +1,324 @@
<?php
/**
* Download report.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Reports
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WP_List_Table' ) ) {
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
}
/**
* WC_Report_Downloads.
*/
class WC_Report_Downloads extends WP_List_Table {
/**
* Max items.
*
* @var int
*/
protected $max_items;
/**
* Constructor.
*/
public function __construct() {
parent::__construct( array(
'singular' => 'download',
'plural' => 'downloads',
'ajax' => false,
) );
}
/**
* Don't need this.
*
* @param string $position Top or bottom.
*/
public function display_tablenav( $position ) {
if ( 'top' !== $position ) {
parent::display_tablenav( $position );
}
}
/**
* Output the report.
*/
public function output_report() {
$this->prepare_items();
// Subtitle for permission if set.
if ( ! empty( $_GET['permission_id'] ) ) { // WPCS: input var ok.
$permission_id = absint( $_GET['permission_id'] ); // WPCS: input var ok.
// Load the permission, order, etc. so we can render more information.
$permission = null;
$product = null;
try {
$permission = new WC_Customer_Download( $permission_id );
$product = wc_get_product( $permission->product_id );
} catch ( Exception $e ) {
wp_die( sprintf( esc_html__( 'Permission #%d not found.', 'woocommerce' ), esc_html( $permission_id ) ) );
}
}
echo '<h1>' . esc_html__( 'Customer downloads', 'woocommerce' );
$filters = $this->get_filter_vars();
$filter_list = array();
$filter_names = array(
'product_id' => __( 'Product', 'woocommerce' ),
'download_id' => __( 'File ID', 'woocommerce' ),
'permission_id' => __( 'Permission ID', 'woocommerce' ),
'order_id' => __( 'Order', 'woocommerce' ),
'user_id' => __( 'User', 'woocommerce' ),
'user_ip_address' => __( 'IP address', 'woocommerce' ),
);
foreach ( $filters as $key => $value ) {
if ( is_null( $value ) ) {
continue;
}
switch ( $key ) {
case 'order_id' :
$order = wc_get_order( $value );
if ( $order ) {
$display_value = _x( '#', 'hash before order number', 'woocommerce' ) . $order->get_order_number();
} else {
break 2;
}
break;
case 'product_id' :
$product = wc_get_product( $value );
if ( $product ) {
$display_value = $product->get_formatted_name();
} else {
break 2;
}
break;
default :
$display_value = $value;
break;
}
$filter_list[] = $filter_names[ $key ] . ' ' . $display_value . ' <a href="' . esc_url( remove_query_arg( $key ) ) . '" class="woocommerce-reports-remove-filter">&times;</a>';
}
echo $filter_list ? ' - ' . wp_kses_post( implode( ', ', $filter_list ) ) : '';
echo '</h1>';
echo '<div id="poststuff" class="woocommerce-reports-wide">';
$this->display();
echo '</div>';
}
/**
* Get column value.
*
* @param mixed $item Item being displayed.
* @param string $column_name Column name.
*/
public function column_default( $item, $column_name ) {
$permission = null;
$product = null;
try {
$permission = new WC_Customer_Download( $item->permission_id );
$product = wc_get_product( $permission->product_id );
} catch ( Exception $e ) {
// Ok to continue rendering other information even if permission and/or product is not found.
return;
}
switch ( $column_name ) {
case 'timestamp' :
echo esc_html( $item->timestamp );
break;
case 'product' :
if ( ! empty( $product ) ) {
edit_post_link( esc_html( $product->get_formatted_name() ), '', '', $product->get_id(), 'view-link' );
echo '<div class="row-actions">';
echo '<a href="' . esc_url( add_query_arg( 'product_id', $product->get_id() ) ) . '">' . esc_html__( 'Filter by product', 'woocommerce' ) . '</a>';
echo '</div>';
}
break;
case 'file' :
if ( ! empty( $permission ) && ! empty( $product ) ) {
// File information.
$file = $product->get_file( $permission->get_download_id() );
echo esc_html( $file->get_name() . ' - ' . basename( $file->get_file() ) );
echo '<div class="row-actions">';
echo '<a href="' . esc_url( add_query_arg( 'download_id', $permission->get_download_id() ) ) . '">' . esc_html__( 'Filter by file', 'woocommerce' ) . '</a>';
echo '</div>';
}
break;
case 'order' :
if ( ! empty( $permission ) && ( $order = wc_get_order( $permission->order_id ) ) ) {
edit_post_link( esc_html( _x( '#', 'hash before order number', 'woocommerce' ) . $order->get_order_number() ), '', '', $permission->order_id, 'view-link' );
echo '<div class="row-actions">';
echo '<a href="' . esc_url( add_query_arg( 'order_id', $order->get_id() ) ) . '">' . esc_html__( 'Filter by order', 'woocommerce' ) . '</a>';
echo '</div>';
}
break;
case 'user' :
if ( $item->user_id > 0 ) {
$user = get_user_by( 'id', $item->user_id );
if ( ! empty( $user ) ) {
echo '<a href="' . esc_url( get_edit_user_link( $item->user_id ) ) . '">' . esc_html( $user->display_name ) . '</a>';
echo '<div class="row-actions">';
echo '<a href="' . esc_url( add_query_arg( 'user_id', $item->user_id ) ) . '">' . esc_html__( 'Filter by user', 'woocommerce' ) . '</a>';
echo '</div>';
}
} else {
esc_html_e( 'Guest', 'woocommerce' );
}
break;
case 'user_ip_address' :
echo esc_html( $item->user_ip_address );
echo '<div class="row-actions">';
echo '<a href="' . esc_url( add_query_arg( 'user_ip_address', $item->user_ip_address ) ) . '">' . esc_html__( 'Filter by IP address', 'woocommerce' ) . '</a>';
echo '</div>';
break;
}
}
/**
* Get columns.
*
* @return array
*/
public function get_columns() {
$columns = array(
'timestamp' => __( 'Timestamp', 'woocommerce' ),
'product' => __( 'Product', 'woocommerce' ),
'file' => __( 'File', 'woocommerce' ),
'order' => __( 'Order', 'woocommerce' ),
'user' => __( 'User', 'woocommerce' ),
'user_ip_address' => __( 'IP address', 'woocommerce' ),
);
return $columns;
}
/**
* Prepare download list items.
*/
public function prepare_items() {
$this->_column_headers = array( $this->get_columns(), array(), $this->get_sortable_columns() );
$current_page = absint( $this->get_pagenum() );
// Allow filtering per_page value, but ensure it's at least 1.
$per_page = max( 1, apply_filters( 'woocommerce_admin_downloads_report_downloads_per_page', 20 ) );
$this->get_items( $current_page, $per_page );
/**
* Pagination.
*/
$this->set_pagination_args( array(
'total_items' => $this->max_items,
'per_page' => $per_page,
'total_pages' => ceil( $this->max_items / $per_page ),
) );
}
/**
* No items found text.
*/
public function no_items() {
esc_html_e( 'No customer downloads found.', 'woocommerce' );
}
/**
* Get filters from querystring.
*
* @return object
*/
protected function get_filter_vars() {
$product_id = ! empty( $_GET['product_id'] ) ? absint( wp_unslash( $_GET['product_id'] ) ) : null; // WPCS: input var ok.
$download_id = ! empty( $_GET['download_id'] ) ? wc_clean( wp_unslash( $_GET['download_id'] ) ) : null; // WPCS: input var ok.
$permission_id = ! empty( $_GET['permission_id'] ) ? absint( wp_unslash( $_GET['permission_id'] ) ) : null; // WPCS: input var ok.
$order_id = ! empty( $_GET['order_id'] ) ? absint( wp_unslash( $_GET['order_id'] ) ) : null; // WPCS: input var ok.
$user_id = ! empty( $_GET['user_id'] ) ? absint( wp_unslash( $_GET['user_id'] ) ) : null; // WPCS: input var ok.
$user_ip_address = ! empty( $_GET['user_ip_address'] ) ? wc_clean( wp_unslash( $_GET['user_ip_address'] ) ): null; // WPCS: input var ok.
return (object) array(
'product_id' => $product_id,
'download_id' => $download_id,
'permission_id' => $permission_id,
'order_id' => $order_id,
'user_id' => $user_id,
'user_ip_address' => $user_ip_address,
);
}
/**
* Get downloads matching criteria.
*
* @param int $current_page Current viewed page.
* @param int $per_page How many results to show per page.
*/
public function get_items( $current_page, $per_page ) {
global $wpdb;
$this->max_items = 0;
$this->items = array();
$filters = $this->get_filter_vars();
// Get downloads from database.
$table = $wpdb->prefix . WC_Customer_Download_Log_Data_Store::get_table_name();
$query_from = " FROM {$table} as downloads ";
if ( ! is_null( $filters->product_id ) || ! is_null( $filters->download_id ) || ! is_null( $filters->order_id ) ) {
$query_from .= " LEFT JOIN {$wpdb->prefix}woocommerce_downloadable_product_permissions as permissions on downloads.permission_id = permissions.permission_id ";
}
$query_from .= ' WHERE 1=1 ';
if ( ! is_null( $filters->product_id ) ) {
$query_from .= $wpdb->prepare( ' AND product_id = %d ', $filters->product_id );
}
if ( ! is_null( $filters->download_id ) ) {
$query_from .= $wpdb->prepare( ' AND download_id = %s ', $filters->download_id );
}
if ( ! is_null( $filters->order_id ) ) {
$query_from .= $wpdb->prepare( ' AND order_id = %d ', $filters->order_id );
}
if ( ! is_null( $filters->permission_id ) ) {
$query_from .= $wpdb->prepare( ' AND downloads.permission_id = %d ', $filters->permission_id );
}
if ( ! is_null( $filters->user_id ) ) {
$query_from .= $wpdb->prepare( ' AND downloads.user_id = %d ', $filters->user_id );
}
if ( ! is_null( $filters->user_ip_address ) ) {
$query_from .= $wpdb->prepare( ' AND user_ip_address = %s ', $filters->user_ip_address );
}
$query_from = apply_filters( 'woocommerce_report_downloads_query_from', $query_from );
$query_order = $wpdb->prepare( 'ORDER BY timestamp DESC LIMIT %d, %d;', ( $current_page - 1 ) * $per_page, $per_page );
$this->items = $wpdb->get_results( "SELECT * {$query_from} {$query_order}" ); // WPCS: cache ok, db call ok, unprepared SQL ok.
$this->max_items = $wpdb->get_var( "SELECT COUNT( DISTINCT download_log_id ) {$query_from};" ); // WPCS: cache ok, db call ok, unprepared SQL ok.
}
}

View File

@ -9,10 +9,12 @@
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
exit;
}
if ( ! class_exists( 'WC_Settings_Products', false ) ) :
if ( class_exists( 'WC_Settings_Products', false ) ) {
return new WC_Settings_Products();
}
/**
* WC_Settings_Products.
@ -35,7 +37,6 @@ class WC_Settings_Products extends WC_Settings_Page {
* @return array
*/
public function get_sections() {
$sections = array(
'' => __( 'General', 'woocommerce' ),
'display' => __( 'Display', 'woocommerce' ),
@ -70,22 +71,18 @@ class WC_Settings_Products extends WC_Settings_Page {
/**
* Get settings array.
*
* @param string $current_section
*
* @param string $current_section Current section name.
* @return array
*/
public function get_settings( $current_section = '' ) {
if ( 'display' == $current_section ) {
$settings = apply_filters( 'woocommerce_product_settings', array(
if ( 'display' === $current_section ) {
$settings = array(
array(
'title' => __( 'Shop &amp; product pages', 'woocommerce' ),
'type' => 'title',
'desc' => '',
'id' => 'catalog_options',
),
array(
'title' => __( 'Shop page', 'woocommerce' ),
'desc' => '<br/>' . sprintf( __( 'The base page can also be used in your <a href="%s">product permalinks</a>.', 'woocommerce' ), admin_url( 'options-permalink.php' ) ),
@ -96,7 +93,6 @@ class WC_Settings_Products extends WC_Settings_Page {
'css' => 'min-width:300px;',
'desc_tip' => __( 'This sets the base page of your shop - this is where your product archive will be.', 'woocommerce' ),
),
array(
'title' => __( 'Shop page display', 'woocommerce' ),
'desc' => __( 'This controls what is shown on the product archive.', 'woocommerce' ),
@ -112,7 +108,6 @@ class WC_Settings_Products extends WC_Settings_Page {
),
'desc_tip' => true,
),
array(
'title' => __( 'Default category display', 'woocommerce' ),
'desc' => __( 'This controls what is shown on category archives.', 'woocommerce' ),
@ -128,7 +123,6 @@ class WC_Settings_Products extends WC_Settings_Page {
),
'desc_tip' => true,
),
array(
'title' => __( 'Default product sorting', 'woocommerce' ),
'desc' => __( 'This controls the default sort order of the catalog.', 'woocommerce' ),
@ -147,7 +141,6 @@ class WC_Settings_Products extends WC_Settings_Page {
) ),
'desc_tip' => true,
),
array(
'title' => __( 'Add to cart behaviour', 'woocommerce' ),
'desc' => __( 'Redirect to the cart page after successful addition', 'woocommerce' ),
@ -156,7 +149,6 @@ class WC_Settings_Products extends WC_Settings_Page {
'type' => 'checkbox',
'checkboxgroup' => 'start',
),
array(
'desc' => __( 'Enable AJAX add to cart buttons on archives', 'woocommerce' ),
'id' => 'woocommerce_enable_ajax_add_to_cart',
@ -164,68 +156,73 @@ class WC_Settings_Products extends WC_Settings_Page {
'type' => 'checkbox',
'checkboxgroup' => 'end',
),
array(
'type' => 'sectionend',
'id' => 'catalog_options',
),
);
$theme_support = get_theme_support( 'woocommerce' );
$theme_support = is_array( $theme_support ) ? $theme_support[0]: false;
$image_settings = array(
array(
'title' => __( 'Product images', 'woocommerce' ),
'type' => 'title',
'desc' => sprintf( __( 'These settings affect the display and dimensions of images in your catalog - the display on the front-end will still be affected by CSS styles. After changing these settings you may need to <a target="_blank" href="%s">regenerate your thumbnails</a>.', 'woocommerce' ), 'https://wordpress.org/plugins/regenerate-thumbnails/' ),
'desc' => __( 'These settings change how product images are displayed in your catalog.', 'woocommerce' ),
'id' => 'image_options',
),
array(
'title' => __( 'Catalog images', 'woocommerce' ),
'desc' => __( 'This size is usually used in product listings. (W x H)', 'woocommerce' ),
'id' => 'shop_catalog_image_size',
'single_image_width' => array(
'title' => __( 'Main image width', 'woocommerce' ),
'desc' => __( 'This is the width used by the main image on single product pages. These images will be uncropped.', 'woocommerce' ),
'id' => 'woocommerce_single_image_width',
'css' => '',
'type' => 'image_width',
'default' => array(
'width' => '300',
'height' => '300',
'crop' => 1,
'type' => 'text',
'custom_attributes' => array(
'size' => 3,
),
'suffix' => 'px',
'default' => 600,
'desc_tip' => true,
),
array(
'title' => __( 'Single product image', 'woocommerce' ),
'desc' => __( 'This is the size used by the main image on the product page. (W x H)', 'woocommerce' ),
'id' => 'shop_single_image_size',
'thumbnail_image_width' => array(
'title' => __( 'Thumbnail width', 'woocommerce' ),
'desc' => __( 'This size is used for product archives and product listings.', 'woocommerce' ),
'id' => 'woocommerce_thumbnail_image_width',
'css' => '',
'type' => 'image_width',
'default' => array(
'width' => '600',
'height' => '600',
'crop' => 1,
'type' => 'text',
'custom_attributes' => array(
'size' => 3,
),
'suffix' => 'px',
'default' => 300,
'desc_tip' => true,
),
array(
'title' => __( 'Product thumbnails', 'woocommerce' ),
'desc' => __( 'This size is usually used for the gallery of images on the product page. (W x H)', 'woocommerce' ),
'id' => 'shop_thumbnail_image_size',
'title' => __( 'Thumbnail cropping', 'woocommerce' ),
'desc' => __( 'This determines how thumbnails appear. Widths will be fixed, whilst heights may vary.', 'woocommerce' ),
'id' => 'woocommerce_thumbnail_cropping',
'css' => '',
'type' => 'image_width',
'default' => array(
'width' => '180',
'height' => '180',
'crop' => 1,
),
'desc_tip' => true,
'type' => 'thumbnail_cropping',
'default' => '1:1',
'desc_tip' => false,
),
array(
'type' => 'sectionend',
'id' => 'image_options',
),
);
));
} elseif ( 'inventory' == $current_section ) {
if ( isset( $theme_support['single_image_width'] ) ) {
unset( $image_settings['single_image_width'] );
}
if ( isset( $theme_support['thumbnail_image_width'] ) ) {
unset( $image_settings['thumbnail_image_width'] );
}
$settings = apply_filters( 'woocommerce_product_settings', array_merge( $settings, $image_settings ) );
} elseif ( 'inventory' === $current_section ) {
$settings = apply_filters( 'woocommerce_inventory_settings', array(
@ -354,7 +351,7 @@ class WC_Settings_Products extends WC_Settings_Page {
));
} elseif ( 'downloadable' == $current_section ) {
} elseif ( 'downloadable' === $current_section ) {
$settings = apply_filters( 'woocommerce_downloadable_products_settings', array(
array(
'title' => __( 'Downloadable products', 'woocommerce' ),
@ -530,6 +527,4 @@ class WC_Settings_Products extends WC_Settings_Page {
}
}
endif;
return new WC_Settings_Products();

View File

@ -1,14 +1,17 @@
<?php
/**
* Admin View: Page - Status Database Logs
*
* @package WooCommerce/Admin/Logs
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<form method="get" id="mainform" action="">
?>
<form method="post" id="mainform" action="">
<?php $log_table_list->search_box( __( 'Search logs', 'woocommerce' ), 'log' ); ?>
<?php $log_table_list->display(); ?>
<input type="hidden" name="page" value="wc-status" />

View File

@ -171,7 +171,7 @@ $untested_plugins = $plugin_updates->get_untested_plugins( WC()->version, 'minor
if ( $wpdb->use_mysqli ) {
$ver = mysqli_get_server_info( $wpdb->dbh );
} else {
$ver = mysql_get_server_info();
$ver = mysql_get_server_info(); // @codingStandardsIgnoreLine
}
if ( ! empty( $wpdb->is_mysql ) && ! stristr( $ver, 'MariaDB' ) ) : ?>
<tr>

View File

@ -11,7 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<div id="message" class="updated woocommerce-message wc-connect">
<a class="woocommerce-message-close notice-dismiss" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wc-hide-notice', 'theme_support' ), 'woocommerce_hide_notices_nonce', '_wc_notice_nonce' ) ); ?>"><?php _e( 'Dismiss', 'woocommerce' ); ?></a>
<p><?php printf( __( '<strong>Your theme does not declare WooCommerce support</strong> &#8211; Please read our <a href="%1$s" target="_blank">integration</a> guide or check out our <a href="%2$s" target="_blank">Storefront</a> theme which is totally free to download and designed specifically for use with WooCommerce.', 'woocommerce' ), esc_url( apply_filters( 'woocommerce_docs_url', 'https://docs.woocommerce.com/document/third-party-custom-theme-compatibility/', 'theme-compatibility' ) ), esc_url( admin_url( 'theme-install.php?theme=storefront' ) ) ); ?></p>
<p><?php printf( __( '<strong>Your theme does not declare WooCommerce support</strong> &#8211; Please read our <a href="%1$s" target="_blank">integration</a> guide or check out our <a href="%2$s" target="_blank">Storefront</a> theme which is totally free to download and designed specifically for use with WooCommerce.', 'woocommerce' ), esc_url( apply_filters( 'woocommerce_docs_url', 'https://docs.woocommerce.com/document/third-party-custom-theme-compatibility/', 'theme-compatibility' ) ), esc_url( self_admin_url( 'theme-install.php?theme=storefront' ) ) ); ?></p>
<p class="submit">
<a href="https://woocommerce.com/storefront/?utm_source=notice&amp;utm_medium=product&amp;utm_content=storefront&amp;utm_campaign=woocommerceplugin" class="button-primary" target="_blank"><?php _e( 'Read more about Storefront', 'woocommerce' ); ?></a>
<a href="<?php echo esc_url( apply_filters( 'woocommerce_docs_url', 'http://docs.woocommerce.com/document/third-party-custom-theme-compatibility/?utm_source=notice&utm_medium=product&utm_content=themecompatibility&utm_campaign=woocommerceplugin' ) ); ?>" class="button-secondary" target="_blank"><?php _e( 'Theme integration guide', 'woocommerce' ); ?></a>

View File

@ -82,7 +82,7 @@ class WC_REST_Customer_Downloads_Controller extends WC_REST_Customer_Downloads_V
'type' => 'object',
'properties' => array(
'download_id' => array(
'description' => __( 'Download ID (MD5).', 'woocommerce' ),
'description' => __( 'Download ID.', 'woocommerce' ),
'type' => 'string',
'context' => array( 'view' ),
'readonly' => true,

View File

@ -181,8 +181,9 @@ class WC_REST_Order_Refunds_Controller extends WC_REST_Orders_Controller {
* @return WP_Error|WP_REST_Response
*/
public function prepare_object_for_response( $object, $request ) {
$this->request = $request;
$order = wc_get_order( (int) $request['order_id'] );
$this->request = $request;
$this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] );
$order = wc_get_order( (int) $request['order_id'] );
if ( ! $order ) {
return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 );

View File

@ -281,12 +281,13 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
* @return WP_REST_Response
*/
public function prepare_object_for_response( $object, $request ) {
$this->request = $request;
$data = $this->get_formatted_item_data( $object );
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
$data = $this->add_additional_fields_to_object( $data, $request );
$data = $this->filter_response_by_context( $data, $context );
$response = rest_ensure_response( $data );
$this->request = $request;
$this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] );
$data = $this->get_formatted_item_data( $object );
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
$data = $this->add_additional_fields_to_object( $data, $request );
$data = $this->filter_response_by_context( $data, $context );
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $object, $request ) );
/**
@ -606,14 +607,14 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
/**
* Create or update a line item.
*
* @param array $posted Line item data.
* @param array $posted Line item data.
* @param string $action 'create' to add line item or 'update' to update it.
*
* @param object $item Passed when updating an item. Null during creation.
* @return WC_Order_Item_Product
* @throws WC_REST_Exception Invalid data, server error.
*/
protected function prepare_line_items( $posted, $action = 'create' ) {
$item = new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' );
protected function prepare_line_items( $posted, $action = 'create', $item = null ) {
$item = is_null( $item ) ? new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item;
$product = wc_get_product( $this->get_product_id( $posted ) );
if ( $product !== $item->get_product() ) {
@ -636,14 +637,14 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
/**
* Create or update an order shipping method.
*
* @param $posted $shipping Item data.
* @param array $posted $shipping Item data.
* @param string $action 'create' to add shipping or 'update' to update it.
*
* @param object $item Passed when updating an item. Null during creation.
* @return WC_Order_Item_Shipping
* @throws WC_REST_Exception Invalid data, server error.
*/
protected function prepare_shipping_lines( $posted, $action ) {
$item = new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' );
protected function prepare_shipping_lines( $posted, $action = 'create', $item = null ) {
$item = is_null( $item ) ? new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item;
if ( 'create' === $action ) {
if ( empty( $posted['method_id'] ) ) {
@ -660,14 +661,14 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
/**
* Create or update an order fee.
*
* @param array $posted Item data.
* @param array $posted Item data.
* @param string $action 'create' to add fee or 'update' to update it.
*
* @param object $item Passed when updating an item. Null during creation.
* @return WC_Order_Item_Fee
* @throws WC_REST_Exception Invalid data, server error.
*/
protected function prepare_fee_lines( $posted, $action ) {
$item = new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' );
protected function prepare_fee_lines( $posted, $action = 'create', $item = null ) {
$item = is_null( $item ) ? new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item;
if ( 'create' === $action ) {
if ( empty( $posted['name'] ) ) {
@ -684,14 +685,14 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
/**
* Create or update an order coupon.
*
* @param array $posted Item data.
* @param array $posted Item data.
* @param string $action 'create' to add coupon or 'update' to update it.
*
* @param object $item Passed when updating an item. Null during creation.
* @return WC_Order_Item_Coupon
* @throws WC_REST_Exception Invalid data, server error.
*/
protected function prepare_coupon_lines( $posted, $action ) {
$item = new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' );
protected function prepare_coupon_lines( $posted, $action = 'create', $item = null ) {
$item = is_null( $item ) ? new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item;
if ( 'create' === $action ) {
if ( empty( $posted['code'] ) ) {
@ -710,10 +711,10 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
* When updating, the item ID provided is checked to ensure it is associated
* with the order.
*
* @param WC_Order $order order
* @param string $item_type
* @param array $posted item provided in the request body
* @throws WC_REST_Exception If item ID is not associated with order
* @param WC_Order $order order object.
* @param string $item_type The item type.
* @param array $posted item provided in the request body.
* @throws WC_REST_Exception If item ID is not associated with order.
*/
protected function set_item( $order, $item_type, $posted ) {
global $wpdb;
@ -725,29 +726,23 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
}
$method = 'prepare_' . $item_type;
$item = null;
// Verify provided line item ID is associated with order.
if ( 'update' === $action ) {
$result = $wpdb->get_row(
$wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d AND order_id = %d",
absint( $posted['id'] ),
absint( $order->get_id() )
) );
if ( is_null( $result ) ) {
$item = $order->get_item( absint( $posted['id'] ), false );
if ( ! $item ) {
throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 );
}
}
// Prepare item data
$item = $this->$method( $posted, $action );
// Prepare item data.
$item = $this->$method( $posted, $action, $item );
/**
* Action hook to adjust item before save.
* @since 3.0.0
*/
do_action( 'woocommerce_rest_set_order_item', $item, $posted );
// Save or add to order
// If creating the order, add the item to it.
if ( 'create' === $action ) {
$order->add_item( $item );
} else {
@ -1647,7 +1642,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
'validate_callback' => 'rest_validate_request_arg',
);
$params['dp'] = array(
'default' => 2,
'default' => wc_get_price_decimals(),
'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ),
'type' => 'integer',
'sanitize_callback' => 'absint',

View File

@ -418,6 +418,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Controller {
* For image_width, Crop can return "0" instead of false -- so we want
* to make sure we return these consistently the same we accept them.
*
* @todo remove in 4.0
* @since 3.0.0
* @param array $setting
* @return array
@ -475,6 +476,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Controller {
'radio', // Validates with validate_setting_radio_field (-> validate_setting_select_field).
'checkbox', // Validates with validate_setting_checkbox_field.
'image_width', // Validates with validate_setting_image_width_field.
'thumbnail_cropping', // Validates with validate_setting_text_field.
) );
}
@ -553,7 +555,7 @@ class WC_REST_Setting_Options_Controller extends WC_REST_Controller {
'sanitize_callback' => 'sanitize_text_field',
),
'context' => array( 'view', 'edit' ),
'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox' ),
'enum' => array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'image_width', 'checkbox', 'thumbnail_cropping' ),
'readonly' => true,
),
'options' => array(

View File

@ -874,7 +874,7 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller {
'version_latest' => WC_Admin_Status::get_latest_theme_version( $active_theme ),
'author_url' => esc_url_raw( $active_theme->{'Author URI'} ),
'is_child_theme' => is_child_theme(),
'has_woocommerce_support' => ( current_theme_supports( 'woocommerce' ) || in_array( $active_theme->template, wc_get_core_supported_themes() ) ),
'has_woocommerce_support' => current_theme_supports( 'woocommerce' ),
'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ),
'has_outdated_templates' => $outdated_templates,
'overrides' => $override_files,

View File

@ -406,15 +406,15 @@ class WC_REST_System_Status_Tools_Controller extends WC_REST_Controller {
* that don't have address indexes yet.
*/
$sql = "INSERT INTO {$wpdb->postmeta}( post_id, meta_key, meta_value )
SELECT post_id, '%1\$s', GROUP_CONCAT( meta_value SEPARATOR ' ' )
SELECT post_id, '%s', GROUP_CONCAT( meta_value SEPARATOR ' ' )
FROM {$wpdb->postmeta}
WHERE meta_key IN ( '%2\$s', '%3\$s' )
WHERE meta_key IN ( '%s', '%s' )
AND post_id IN ( SELECT DISTINCT post_id FROM {$wpdb->postmeta}
WHERE post_id NOT IN ( SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='%1\$s' )
AND post_id IN ( SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='%3\$s' ) )
WHERE post_id NOT IN ( SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='%s' )
AND post_id IN ( SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='%s' ) )
GROUP BY post_id";
$rows = $wpdb->query( $wpdb->prepare( $sql, '_billing_address_index', '_billing_first_name', '_billing_last_name' ) );
$rows += $wpdb->query( $wpdb->prepare( $sql, '_shipping_address_index', '_shipping_first_name', '_shipping_last_name' ) );
$rows = $wpdb->query( $wpdb->prepare( $sql, '_billing_address_index', '_billing_first_name', '_billing_last_name', '_billing_address_index', '_billing_last_name' ) );
$rows += $wpdb->query( $wpdb->prepare( $sql, '_shipping_address_index', '_shipping_first_name', '_shipping_last_name', '_shipping_address_index', '_shipping_last_name') );
$message = sprintf( __( '%d indexes added', 'woocommerce' ), $rows );
break;

View File

@ -98,13 +98,14 @@ class WC_REST_Legacy_Orders_Controller extends WC_REST_CRUD_Controller {
* @return WP_REST_Response $data
*/
public function prepare_item_for_response( $post, $request ) {
$this->request = $request;
$statuses = wc_get_order_statuses();
$order = wc_get_order( $post );
$data = array_merge( array( 'id' => $order->get_id() ), $order->get_data() );
$format_decimal = array( 'discount_total', 'discount_tax', 'shipping_total', 'shipping_tax', 'shipping_total', 'shipping_tax', 'cart_tax', 'total', 'total_tax' );
$format_date = array( 'date_created', 'date_modified', 'date_completed', 'date_paid' );
$format_line_items = array( 'line_items', 'tax_lines', 'shipping_lines', 'fee_lines', 'coupon_lines' );
$this->request = $request;
$this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] );
$statuses = wc_get_order_statuses();
$order = wc_get_order( $post );
$data = array_merge( array( 'id' => $order->get_id() ), $order->get_data() );
$format_decimal = array( 'discount_total', 'discount_tax', 'shipping_total', 'shipping_tax', 'shipping_total', 'shipping_tax', 'cart_tax', 'total', 'total_tax' );
$format_date = array( 'date_created', 'date_modified', 'date_completed', 'date_paid' );
$format_line_items = array( 'line_items', 'tax_lines', 'shipping_lines', 'fee_lines', 'coupon_lines' );
// Format decimal values.
foreach ( $format_decimal as $key ) {

View File

@ -619,7 +619,8 @@ class WC_API_Server {
* @return string
*/
public function get_raw_data() {
// $HTTP_RAW_POST_DATA is deprecated on PHP 5.6
// @codingStandardsIgnoreStart
// $HTTP_RAW_POST_DATA is deprecated on PHP 5.6.
if ( function_exists( 'phpversion' ) && version_compare( phpversion(), '5.6', '>=' ) ) {
return file_get_contents( 'php://input' );
}
@ -633,6 +634,7 @@ class WC_API_Server {
}
return $HTTP_RAW_POST_DATA;
// @codingStandardsIgnoreEnd
}
/**

View File

@ -651,7 +651,8 @@ class WC_API_Server {
* @return string
*/
public function get_raw_data() {
// $HTTP_RAW_POST_DATA is deprecated on PHP 5.6
// @codingStandardsIgnoreStart
// $HTTP_RAW_POST_DATA is deprecated on PHP 5.6.
if ( function_exists( 'phpversion' ) && version_compare( phpversion(), '5.6', '>=' ) ) {
return file_get_contents( 'php://input' );
}
@ -665,6 +666,7 @@ class WC_API_Server {
}
return $HTTP_RAW_POST_DATA;
// @codingStandardsIgnoreEnd
}
/**

View File

@ -658,7 +658,8 @@ class WC_API_Server {
* @return string
*/
public function get_raw_data() {
// $HTTP_RAW_POST_DATA is deprecated on PHP 5.6
// @codingStandardsIgnoreStart
// $HTTP_RAW_POST_DATA is deprecated on PHP 5.6.
if ( function_exists( 'phpversion' ) && version_compare( phpversion(), '5.6', '>=' ) ) {
return file_get_contents( 'php://input' );
}
@ -672,6 +673,7 @@ class WC_API_Server {
}
return $HTTP_RAW_POST_DATA;
// @codingStandardsIgnoreEnd
}
/**

View File

@ -133,7 +133,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller {
return new WP_Error( 'woocommerce_rest_invalid_order_refund_id', __( 'Invalid order refund ID.', 'woocommerce' ), 404 );
}
$dp = $request['dp'];
$dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] );
$data = array(
'id' => $refund->get_id(),
@ -511,7 +511,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller {
$params = parent::get_collection_params();
$params['dp'] = array(
'default' => 2,
'default' => wc_get_price_decimals(),
'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ),
'type' => 'integer',
'sanitize_callback' => 'absint',

View File

@ -126,7 +126,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
*/
public function prepare_item_for_response( $post, $request ) {
$order = wc_get_order( $post );
$dp = $request['dp'];
$dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] );
$data = array(
'id' => $order->get_id(),
@ -1609,7 +1609,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
'validate_callback' => 'rest_validate_request_arg',
);
$params['dp'] = array(
'default' => 2,
'default' => wc_get_price_decimals(),
'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ),
'type' => 'integer',
'sanitize_callback' => 'absint',

View File

@ -59,7 +59,7 @@ class WC_AJAX {
@header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
@header( 'X-Robots-Tag: noindex' );
send_nosniff_header();
nocache_headers();
wc_nocache_headers();
status_header( 200 );
}
@ -580,14 +580,13 @@ class WC_AJAX {
* Add variation via ajax function.
*/
public static function add_variation() {
check_ajax_referer( 'add-variation', 'security' );
if ( ! current_user_can( 'edit_products' ) ) {
wp_die( -1 );
}
global $post; // Set $post global so its available, like within the admin screens
global $post; // Set $post global so its available, like within the admin screens.
$product_id = intval( $_POST['post_id'] );
$post = get_post( $product_id );
@ -595,6 +594,7 @@ class WC_AJAX {
$product_object = wc_get_product( $product_id );
$variation_object = new WC_Product_Variation();
$variation_object->set_parent_id( $product_id );
$variation_object->set_attributes( array_fill_keys( array_keys( $product_object->get_variation_attributes() ), '' ) );
$variation_id = $variation_object->save();
$variation = get_post( $variation_id );
$variation_data = array_merge( array_map( 'maybe_unserialize', get_post_custom( $variation_id ) ), wc_get_product_variation_attributes( $variation_id ) ); // kept for BW compatibility.

View File

@ -86,7 +86,7 @@ class WC_API extends WC_Legacy_API {
ob_start();
// No cache headers.
nocache_headers();
wc_nocache_headers();
// Clean the API request.
$api_request = $wp->query_vars['wc-api'];

View File

@ -1,9 +1,4 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* WC_Cache_Helper class.
*
@ -13,6 +8,14 @@ if ( ! defined( 'ABSPATH' ) ) {
* @category Class
* @author WooThemes
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC_Cache_Helper.
*/
class WC_Cache_Helper {
/**
@ -20,18 +23,19 @@ class WC_Cache_Helper {
*/
public static function init() {
add_action( 'template_redirect', array( __CLASS__, 'geolocation_ajax_redirect' ) );
add_action( 'wp', array( __CLASS__, 'prevent_caching' ) );
add_action( 'admin_notices', array( __CLASS__, 'notices' ) );
add_action( 'delete_version_transients', array( __CLASS__, 'delete_version_transients' ) );
add_action( 'wp', array( __CLASS__, 'prevent_caching' ) );
}
/**
* Get prefix for use with wp_cache_set. Allows all cache in a group to be invalidated at once.
* @param string $group
*
* @param string $group Group of cache to get.
* @return string
*/
public static function get_cache_prefix( $group ) {
// Get cache key - uses cache key wc_orders_cache_prefix to invalidate when needed
// Get cache key - uses cache key wc_orders_cache_prefix to invalidate when needed.
$prefix = wp_cache_get( 'wc_' . $group . '_cache_prefix', $group );
if ( false === $prefix ) {
@ -44,7 +48,8 @@ class WC_Cache_Helper {
/**
* Increment group cache prefix (invalidates cache).
* @param string $group
*
* @param string $group Group of cache to clear.
*/
public static function incr_cache_prefix( $group ) {
wp_cache_incr( 'wc_' . $group . '_cache_prefix', 1, $group );
@ -52,6 +57,7 @@ class WC_Cache_Helper {
/**
* Get a hash of the customer location.
*
* @return string
*/
public static function geolocation_ajax_get_location_hash() {
@ -64,22 +70,37 @@ class WC_Cache_Helper {
return substr( md5( implode( '', $location ) ), 0, 12 );
}
/**
* Prevent caching on certain pages
*/
public static function prevent_caching() {
if ( ! is_blog_installed() ) {
return;
}
$page_ids = array_filter( array( wc_get_page_id( 'cart' ), wc_get_page_id( 'checkout' ), wc_get_page_id( 'myaccount' ) ) );
if ( is_page( $page_ids ) ) {
self::set_nocache_constants();
nocache_headers();
}
}
/**
* When using geolocation via ajax, to bust cache, redirect if the location hash does not equal the querystring.
*
* This prevents caching of the wrong data for this request.
*/
public static function geolocation_ajax_redirect() {
if ( 'geolocation_ajax' === get_option( 'woocommerce_default_customer_address' ) && ! is_checkout() && ! is_cart() && ! is_account_page() && ! is_ajax() && empty( $_POST ) ) {
if ( 'geolocation_ajax' === get_option( 'woocommerce_default_customer_address' ) && ! is_checkout() && ! is_cart() && ! is_account_page() && ! is_ajax() && empty( $_POST ) ) { // WPCS: CSRF ok, input var ok.
$location_hash = self::geolocation_ajax_get_location_hash();
$current_hash = isset( $_GET['v'] ) ? wc_clean( $_GET['v'] ) : '';
$current_hash = isset( $_GET['v'] ) ? wc_clean( wp_unslash( $_GET['v'] ) ) : ''; // WPCS: sanitization ok, input var ok.
if ( empty( $current_hash ) || $current_hash !== $location_hash ) {
global $wp;
$redirect_url = trailingslashit( home_url( $wp->request ) );
if ( ! empty( $_SERVER['QUERY_STRING'] ) ) {
$redirect_url = add_query_arg( $_SERVER['QUERY_STRING'], '', $redirect_url );
if ( ! empty( $_SERVER['QUERY_STRING'] ) ) { // WPCS: Input var ok.
$redirect_url = add_query_arg( wp_unslash( $_SERVER['QUERY_STRING'] ), '', $redirect_url ); // WPCS: sanitization ok, Input var ok.
}
if ( ! get_option( 'permalink_structure' ) ) {
@ -110,9 +131,9 @@ class WC_Cache_Helper {
* Raised in issue https://github.com/woocommerce/woocommerce/issues/5777.
* Adapted from ideas in http://tollmanz.com/invalidation-schemes/.
*
* @param string $group Name for the group of transients we need to invalidate
* @param boolean $refresh true to force a new version
* @return string transient version based on time(), 10 digits
* @param string $group Name for the group of transients we need to invalidate.
* @param boolean $refresh true to force a new version.
* @return string transient version based on time(), 10 digits.
*/
public static function get_transient_version( $group, $refresh = false ) {
$transient_name = $group . '-transient-version';
@ -131,15 +152,14 @@ class WC_Cache_Helper {
* Note; this only works on transients appended with the transient version, and when object caching is not being used.
*
* @since 2.3.10
*
* @param string $version
* @param string $version Version of the transient to remove.
*/
public static function delete_version_transients( $version = '' ) {
if ( ! wp_using_ext_object_cache() && ! empty( $version ) ) {
global $wpdb;
$limit = apply_filters( 'woocommerce_delete_version_transients_limit', 1000 );
$affected = $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s ORDER BY option_id LIMIT %d;", "\_transient\_%" . $version, $limit ) );
$affected = $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s ORDER BY option_id LIMIT %d;", '\_transient\_%' . $version, $limit ) ); // WPCS: cache ok, db call ok.
// If affected rows is equal to limit, there are more rows to delete. Delete in 10 secs.
if ( $affected === $limit ) {
@ -148,38 +168,21 @@ class WC_Cache_Helper {
}
}
/**
* Prevent caching on dynamic pages.
*/
public static function prevent_caching() {
if ( ! is_blog_installed() ) {
return;
}
$page_ids = array_filter( array( wc_get_page_id( 'cart' ), wc_get_page_id( 'checkout' ), wc_get_page_id( 'myaccount' ) ) );
if ( isset( $_GET['download_file'] ) || isset( $_GET['add-to-cart'] ) || is_page( $page_ids ) ) {
add_filter( 'nocache_headers', array( __CLASS__, 'set_nocache_constants' ) );
nocache_headers();
}
}
/**
* Set constants to prevent caching by some plugins.
*
* Hooked into nocache_headers filter but does not change headers.
*
* @param array $value
* @return array
* @param mixed $return Value to return. Previously hooked into a filter.
* @return mixed
*/
public static function set_nocache_constants( $value ) {
public static function set_nocache_constants( $return = true ) {
wc_maybe_define_constant( 'DONOTCACHEPAGE', true );
wc_maybe_define_constant( 'DONOTCACHEOBJECT', true );
wc_maybe_define_constant( 'DONOTCACHEDB', true );
return $value;
return $return;
}
/**
* notices function.
* Notices function.
*/
public static function notices() {
if ( ! function_exists( 'w3tc_pgcache_flush' ) || ! function_exists( 'w3_instance' ) ) {
@ -190,10 +193,10 @@ class WC_Cache_Helper {
$enabled = $config->get_integer( 'dbcache.enabled' );
$settings = array_map( 'trim', $config->get_array( 'dbcache.reject.sql' ) );
if ( $enabled && ! in_array( '_wc_session_', $settings ) ) {
if ( $enabled && ! in_array( '_wc_session_', $settings, true ) ) {
?>
<div class="error">
<p><?php printf( __( 'In order for <strong>database caching</strong> to work with WooCommerce you must add %1$s to the "Ignored Query Strings" option in <a href="%2$s">W3 Total Cache settings</a>.', 'woocommerce' ), '<code>_wc_session_</code>', admin_url( 'admin.php?page=w3tc_dbcache' ) ); ?></p>
<p><?php echo wp_kses_post( sprintf( __( 'In order for <strong>database caching</strong> to work with WooCommerce you must add %1$s to the "Ignored Query Strings" option in <a href="%2$s">W3 Total Cache settings</a>.', 'woocommerce' ), '<code>_wc_session_</code>', esc_url( admin_url( 'admin.php?page=w3tc_dbcache' ) ) ) ); ?></p>
</div>
<?php
}

View File

@ -63,6 +63,12 @@ final class WC_Cart_Fees {
}
$this->cart = $cart;
}
/**
* Register methods for this object on the appropriate WordPress hooks.
*/
public function init() {
add_action( 'woocommerce_cart_emptied', array( $this, 'remove_all_fees' ) );
add_action( 'woocommerce_cart_reset', array( $this, 'remove_all_fees' ) );
}

View File

@ -38,7 +38,12 @@ final class WC_Cart_Session {
}
$this->cart = $cart;
}
/**
* Register methods for this object on the appropriate WordPress hooks.
*/
public function init() {
add_action( 'wp_loaded', array( $this, 'get_cart_from_session' ) );
add_action( 'woocommerce_cart_emptied', array( $this, 'destroy_cart_session' ) );
add_action( 'wp', array( $this, 'maybe_set_cart_cookies' ), 99 );

View File

@ -109,6 +109,10 @@ class WC_Cart extends WC_Legacy_Cart {
$this->fees_api = new WC_Cart_Fees( $this );
$this->tax_display_cart = get_option( 'woocommerce_tax_display_cart' );
// Register hooks for the objects.
$this->session->init();
$this->fees_api->init();
add_action( 'woocommerce_add_to_cart', array( $this, 'calculate_totals' ), 20, 0 );
add_action( 'woocommerce_applied_coupon', array( $this, 'calculate_totals' ), 20, 0 );
add_action( 'woocommerce_cart_item_removed', array( $this, 'calculate_totals' ), 20, 0 );
@ -118,6 +122,16 @@ class WC_Cart extends WC_Legacy_Cart {
add_action( 'woocommerce_after_checkout_validation', array( $this, 'check_customer_coupons' ), 1 );
}
/**
* When cloning, ensure object properties are handled.
*
* These properties store a reference to the cart, so we use new instead of clone.
*/
public function __clone() {
$this->session = new WC_Cart_Session( $this );
$this->fees_api = new WC_Cart_Fees( $this );
}
/*
|--------------------------------------------------------------------------
| Getters.
@ -1764,7 +1778,7 @@ class WC_Cart extends WC_Legacy_Cart {
* @return string formatted price
*/
public function get_total_ex_tax() {
return apply_filters( 'woocommerce_cart_total_ex_tax', wc_price( max( 0, $this->get_total( 'edit' ) - $this->get_cart_contents_tax() - $this->get_shipping_tax() ) ) );
return apply_filters( 'woocommerce_cart_total_ex_tax', wc_price( max( 0, $this->get_total( 'edit' ) - $this->get_total_tax() ) ) );
}
/**

View File

@ -0,0 +1,153 @@
<?php
/**
* Class for customer download logs.
*
* @version 3.3.0
* @since 3.3.0
* @package WooCommerce/Classes
* @author Automattic
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC_Customer_Download_Log.
*/
class WC_Customer_Download_Log extends WC_Data {
/**
* This is the name of this object type.
*
* @var string
*/
protected $object_type = 'customer_download_log';
/**
* Download Log Data array.
*
* @var array
*/
protected $data = array(
'timestamp' => null,
'permission_id' => 0,
'user_id' => null,
'user_ip_address' => null,
);
/**
* Constructor.
*
* @param int|object|array $download_log Download log ID.
*/
public function __construct( $download_log = 0 ) {
parent::__construct( $download_log );
if ( is_numeric( $download_log ) && $download_log > 0 ) {
$this->set_id( $download_log );
} elseif ( $download_log instanceof self ) {
$this->set_id( $download_log->get_id() );
} elseif ( is_object( $download_log ) && ! empty( $download_log->download_log_id ) ) {
$this->set_id( $download_log->download_log_id );
$this->set_props( (array) $download_log );
$this->set_object_read( true );
} else {
$this->set_object_read( true );
}
$this->data_store = WC_Data_Store::load( 'customer-download-log' );
if ( $this->get_id() > 0 ) {
$this->data_store->read( $this );
}
}
/*
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
*/
/**
* Get timestamp.
*
* @param string $context Get context.
* @return WC_DateTime|null Object if the date is set or null if there is no date.
*/
public function get_timestamp( $context = 'view' ) {
return $this->get_prop( 'timestamp', $context );
}
/**
* Get permission id.
*
* @param string $context Get context.
* @return integer
*/
public function get_permission_id( $context = 'view' ) {
return $this->get_prop( 'permission_id', $context );
}
/**
* Get user id.
*
* @param string $context Get context.
* @return integer
*/
public function get_user_id( $context = 'view' ) {
return $this->get_prop( 'user_id', $context );
}
/**
* Get user ip address.
*
* @param string $context Get context.
* @return string
*/
public function get_user_ip_address( $context = 'view' ) {
return $this->get_prop( 'user_ip_address', $context );
}
/*
|--------------------------------------------------------------------------
| Setters
|--------------------------------------------------------------------------
*/
/**
* Set timestamp.
*
* @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date.
*/
public function set_timestamp( $date = null ) {
$this->set_date_prop( 'timestamp', $date );
}
/**
* Set permission id.
*
* @param int $value Value to set.
*/
public function set_permission_id( $value ) {
$this->set_prop( 'permission_id', absint( $value ) );
}
/**
* Set user id.
*
* @param int $value Value to set.
*/
public function set_user_id( $value ) {
$this->set_prop( 'user_id', absint( $value ) );
}
/**
* Set user ip address.
*
* @param string $value Value to set.
*/
public function set_user_ip_address( $value ) {
$this->set_prop( 'user_ip_address', $value );
}
}

View File

@ -168,7 +168,22 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
* @return integer
*/
public function get_download_count( $context = 'view' ) {
return $this->get_prop( 'download_count', $context );
// Check for count of download logs.
$data_store = WC_Data_Store::load( 'customer-download-log' );
$download_log_ids = $data_store->get_download_logs_for_permission( $this->get_id() );
$download_log_count = 0;
if ( ! empty( $download_log_ids ) ) {
$download_log_count = count( $download_log_ids );
}
// Check download count in prop.
$download_count_prop = $this->get_prop( 'download_count', $context );
// Return the larger of the two in case they differ.
// If logs are removed for some reason, we should still respect the
// count stored in the prop.
return max( $download_log_count, $download_count_prop );
}
/*
@ -195,7 +210,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
}
/**
* Get user id.
* Set user id.
*
* @param int $value
*/
@ -204,7 +219,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
}
/**
* Get user_email.
* Set user_email.
*
* @param int $value
*/
@ -213,7 +228,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
}
/**
* Get order_id.
* Set order_id.
*
* @param int $value
*/
@ -222,7 +237,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
}
/**
* Get order_key.
* Set order_key.
*
* @param string $value
*/
@ -231,7 +246,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
}
/**
* Get downloads_remaining.
* Set downloads_remaining.
*
* @param integer|string $value
*/
@ -240,7 +255,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
}
/**
* Get access_granted.
* Set access_granted.
*
* @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date.
*/
@ -249,7 +264,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
}
/**
* Get access_expires.
* Set access_expires.
*
* @param string|integer|null $date UTC timestamp, or ISO 8601 DateTime. If the DateTime string has no timezone or offset, WordPress site timezone will be assumed. Null if their is no date.
*/
@ -258,7 +273,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
}
/**
* Get download_count.
* Set download_count.
*
* @param int $value
*/
@ -266,6 +281,53 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
$this->set_prop( 'download_count', absint( $value ) );
}
/**
* Track a download on this permission.
*
* @since 3.3.0
* @param int user_id Id of the user performing the download
* @param string user_ip_address IP Address of the user performing the download
*/
public function track_download( $user_id = null, $user_ip_address = null ) {
global $wpdb;
// Must have a permission_id to track download log.
if ( ! ( $this->get_id() > 0 ) ) {
throw new Exception( __( 'Invalid permission ID.', 'woocommerce' ) );
}
// Increment download count, and decrement downloads remaining.
// Use SQL to avoid possible issues with downloads in quick succession.
// If downloads_remaining is blank, leave it blank (unlimited).
// Also, ensure downloads_remaining doesn't drop below zero.
$query = $wpdb->prepare( "
UPDATE {$wpdb->prefix}woocommerce_downloadable_product_permissions
SET download_count = download_count + 1,
downloads_remaining = IF( downloads_remaining = '', '', GREATEST( 0, downloads_remaining - 1 ) )
WHERE permission_id = %d",
$this->get_id()
);
$wpdb->query( $query );
// Re-read this download from the data store to pull updated counts.
$this->data_store->read( $this );
// Track download in download log.
$download_log = new WC_Customer_Download_Log();
$download_log->set_timestamp( current_time( 'timestamp', true ) );
$download_log->set_permission_id( $this->get_id() );
if ( ! is_null( $user_id ) ) {
$download_log->set_user_id( $user_id );
}
if ( ! is_null( $user_ip_address ) ) {
$download_log->set_user_ip_address( $user_ip_address );
}
$download_log->save();
}
/*
|--------------------------------------------------------------------------
| CRUD methods
@ -345,7 +407,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
* @return bool
*/
public function __isset( $key ) {
return in_array( $offset, array_keys( $this->data ) );
return in_array( $key, array_keys( $this->data ) );
}
/**

View File

@ -28,25 +28,26 @@ class WC_Data_Store {
* Ran through `woocommerce_data_stores`.
*/
private $stores = array(
'coupon' => 'WC_Coupon_Data_Store_CPT',
'customer' => 'WC_Customer_Data_Store',
'customer-download' => 'WC_Customer_Download_Data_Store',
'customer-session' => 'WC_Customer_Data_Store_Session',
'order' => 'WC_Order_Data_Store_CPT',
'order-refund' => 'WC_Order_Refund_Data_Store_CPT',
'order-item' => 'WC_Order_Item_Data_Store',
'order-item-coupon' => 'WC_Order_Item_Coupon_Data_Store',
'order-item-fee' => 'WC_Order_Item_Fee_Data_Store',
'order-item-product' => 'WC_Order_Item_Product_Data_Store',
'order-item-shipping' => 'WC_Order_Item_Shipping_Data_Store',
'order-item-tax' => 'WC_Order_Item_Tax_Data_Store',
'payment-token' => 'WC_Payment_Token_Data_Store',
'product' => 'WC_Product_Data_Store_CPT',
'product-grouped' => 'WC_Product_Grouped_Data_Store_CPT',
'product-variable' => 'WC_Product_Variable_Data_Store_CPT',
'product-variation' => 'WC_Product_Variation_Data_Store_CPT',
'shipping-zone' => 'WC_Shipping_Zone_Data_Store',
'webhook' => 'WC_Webhook_Data_Store',
'coupon' => 'WC_Coupon_Data_Store_CPT',
'customer' => 'WC_Customer_Data_Store',
'customer-download' => 'WC_Customer_Download_Data_Store',
'customer-download-log' => 'WC_Customer_Download_Log_Data_Store',
'customer-session' => 'WC_Customer_Data_Store_Session',
'order' => 'WC_Order_Data_Store_CPT',
'order-refund' => 'WC_Order_Refund_Data_Store_CPT',
'order-item' => 'WC_Order_Item_Data_Store',
'order-item-coupon' => 'WC_Order_Item_Coupon_Data_Store',
'order-item-fee' => 'WC_Order_Item_Fee_Data_Store',
'order-item-product' => 'WC_Order_Item_Product_Data_Store',
'order-item-shipping' => 'WC_Order_Item_Shipping_Data_Store',
'order-item-tax' => 'WC_Order_Item_Tax_Data_Store',
'payment-token' => 'WC_Payment_Token_Data_Store',
'product' => 'WC_Product_Data_Store_CPT',
'product-grouped' => 'WC_Product_Grouped_Data_Store_CPT',
'product-variable' => 'WC_Product_Variable_Data_Store_CPT',
'product-variation' => 'WC_Product_Variation_Data_Store_CPT',
'shipping-zone' => 'WC_Shipping_Zone_Data_Store',
'webhook' => 'WC_Webhook_Data_Store',
);
/**

View File

@ -353,7 +353,8 @@ class WC_Discounts {
$price_to_discount = ( 'yes' === get_option( 'woocommerce_calc_discounts_sequentially', 'no' ) ) ? $discounted_price : $item->price;
// See how many and what price to apply to.
$apply_quantity = max( 0, ( $limit_usage_qty && ( $limit_usage_qty - $applied_count ) < $item->quantity ? $limit_usage_qty - $applied_count : $item->quantity ) );
$apply_quantity = $limit_usage_qty && ( $limit_usage_qty - $applied_count ) < $item->quantity ? $limit_usage_qty - $applied_count : $item->quantity;
$apply_quantity = max( 0, apply_filters( 'woocommerce_coupon_get_apply_quantity', $apply_quantity, $item, $coupon, $this ) );
$price_to_discount = ( $price_to_discount / $item->quantity ) * $apply_quantity;
// Run coupon calculations.
@ -416,10 +417,11 @@ class WC_Discounts {
// Run coupon calculations.
if ( $limit_usage_qty ) {
$apply_quantity = max( 0, ( $limit_usage_qty - $applied_count < $item->quantity ? $limit_usage_qty - $applied_count: $item->quantity ) );
$apply_quantity = $limit_usage_qty - $applied_count < $item->quantity ? $limit_usage_qty - $applied_count : $item->quantity;
$apply_quantity = max( 0, apply_filters( 'woocommerce_coupon_get_apply_quantity', $apply_quantity, $item, $coupon, $this ) );
$discount = min( $amount, $item->price / $item->quantity ) * $apply_quantity;
} else {
$apply_quantity = $item->quantity;
$apply_quantity = apply_filters( 'woocommerce_coupon_get_apply_quantity', $item->quantity, $item, $coupon, $this );
$discount = $amount * $apply_quantity;
}

View File

@ -72,14 +72,13 @@ class WC_Download_Handler {
$download->get_download_id(),
$download->get_order_id()
);
$count = $download->get_download_count();
$remaining = $download->get_downloads_remaining();
$download->set_download_count( $count + 1 );
if ( '' !== $remaining ) {
$download->set_downloads_remaining( $remaining - 1 );
}
$download->save();
// Track the download in logs and change remaining/counts.
$current_user_id = get_current_user_id();
$ip_address = WC_Geolocation::get_ip_address();
$download->track_download( $current_user_id > 0 ? $current_user_id : null, ! empty( $ip_address ) ? $ip_address : null );
self::download( $product->get_file_download_path( $download->get_download_id() ), $download->get_product_id() );
}
@ -305,7 +304,7 @@ class WC_Download_Handler {
private static function download_headers( $file_path, $filename ) {
self::check_server_config();
self::clean_buffers();
nocache_headers();
wc_nocache_headers();
header( "X-Robots-Tag: noindex, nofollow", true );
header( "Content-Type: " . self::get_download_content_type( $file_path ) );
@ -324,7 +323,7 @@ class WC_Download_Handler {
private static function check_server_config() {
wc_set_time_limit( 0 );
if ( function_exists( 'get_magic_quotes_runtime' ) && get_magic_quotes_runtime() && version_compare( phpversion(), '5.4', '<' ) ) {
set_magic_quotes_runtime( 0 );
set_magic_quotes_runtime( 0 ); // @codingStandardsIgnoreLine
}
if ( function_exists( 'apache_setenv' ) ) {
@apache_setenv( 'no-gzip', 1 );

View File

@ -67,7 +67,7 @@ class WC_Form_Handler {
return;
}
nocache_headers();
wc_nocache_headers();
$user_id = get_current_user_id();
@ -181,7 +181,7 @@ class WC_Form_Handler {
return;
}
nocache_headers();
wc_nocache_headers();
$errors = new WP_Error();
$user = new stdClass();
@ -278,7 +278,7 @@ class WC_Form_Handler {
*/
public static function checkout_action() {
if ( isset( $_POST['woocommerce_checkout_place_order'] ) || isset( $_POST['woocommerce_checkout_update_totals'] ) ) {
nocache_headers();
wc_nocache_headers();
if ( WC()->cart->is_empty() ) {
wp_redirect( wc_get_page_permalink( 'cart' ) );
@ -298,7 +298,7 @@ class WC_Form_Handler {
global $wp;
if ( isset( $_POST['woocommerce_pay'] ) && isset( $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-pay' ) ) {
nocache_headers();
wc_nocache_headers();
ob_start();
// Pay for existing order
@ -377,7 +377,7 @@ class WC_Form_Handler {
*/
public static function add_payment_method_action() {
if ( isset( $_POST['woocommerce_add_payment_method'], $_POST['payment_method'], $_POST['_wpnonce'] ) && wp_verify_nonce( $_POST['_wpnonce'], 'woocommerce-add-payment-method' ) ) {
nocache_headers();
wc_nocache_headers();
ob_start();
$payment_method_id = wc_clean( wp_unslash( $_POST['payment_method'] ) );
@ -422,7 +422,7 @@ class WC_Form_Handler {
global $wp;
if ( isset( $wp->query_vars['delete-payment-method'] ) ) {
nocache_headers();
wc_nocache_headers();
$token_id = absint( $wp->query_vars['delete-payment-method'] );
$token = WC_Payment_Tokens::get( $token_id );
@ -447,7 +447,7 @@ class WC_Form_Handler {
global $wp;
if ( isset( $wp->query_vars['set-default-payment-method'] ) ) {
nocache_headers();
wc_nocache_headers();
$token_id = absint( $wp->query_vars['set-default-payment-method'] );
$token = WC_Payment_Tokens::get( $token_id );
@ -473,7 +473,7 @@ class WC_Form_Handler {
return;
}
nocache_headers();
wc_nocache_headers();
if ( ! empty( $_POST['apply_coupon'] ) && ! empty( $_POST['coupon_code'] ) ) {
WC()->cart->add_discount( sanitize_text_field( $_POST['coupon_code'] ) );
@ -587,7 +587,7 @@ class WC_Form_Handler {
return;
}
nocache_headers();
wc_nocache_headers();
if ( apply_filters( 'woocommerce_empty_cart_when_order_again', true ) ) {
WC()->cart->empty_cart();
@ -678,7 +678,7 @@ class WC_Form_Handler {
isset( $_GET['order_id'] ) &&
( isset( $_GET['_wpnonce'] ) && wp_verify_nonce( $_GET['_wpnonce'], 'woocommerce-cancel_order' ) )
) {
nocache_headers();
wc_nocache_headers();
$order_key = $_GET['order'];
$order_id = absint( $_GET['order_id'] );
@ -725,7 +725,7 @@ class WC_Form_Handler {
return;
}
nocache_headers();
wc_nocache_headers();
$product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_REQUEST['add-to-cart'] ) );
$was_added_to_cart = false;

View File

@ -43,20 +43,6 @@ class WC_Frontend_Scripts {
add_action( 'wp_enqueue_scripts', array( __CLASS__, 'load_scripts' ) );
add_action( 'wp_print_scripts', array( __CLASS__, 'localize_printed_scripts' ), 5 );
add_action( 'wp_print_footer_scripts', array( __CLASS__, 'localize_printed_scripts' ), 5 );
add_action( 'setup_theme', array( __CLASS__, 'add_default_theme_support' ) );
}
/**
* Add theme support for default WP themes.
*
* @since 3.0.0
*/
public static function add_default_theme_support() {
if ( in_array( get_option( 'template' ), wc_get_core_supported_themes() ) ) {
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
}
}
/**

View File

@ -237,7 +237,16 @@ class WC_Geolocation {
fwrite( $handle, $string, strlen( $string ) );
}
gzclose( $gzhandle );
$s_array = fstat( $handle );
fclose( $handle );
if ( ! isset( $s_array['size'] ) || 0 === $s_array['size'] ) {
$logger->notice( 'Empty database file, deleting local copy.', array( 'source' => 'geolocation' ) );
// Delete empty DB, we do not want to keep empty files around.
@unlink( self::get_local_database_path( $tmp_database_version ) );
// Reschedule download of DB.
wp_clear_scheduled_hook( 'woocommerce_geoip_updater' );
wp_schedule_event( strtotime( 'first tuesday of next month' ), 'monthly', 'woocommerce_geoip_updater' );
}
} else {
$logger->notice( 'Unable to open database file', array( 'source' => 'geolocation' ) );
}
@ -265,10 +274,16 @@ class WC_Geolocation {
if ( self::is_IPv6( $ip_address ) ) {
$database = self::get_local_database_path( 'v6' );
if ( ! self::get_file_size( $database ) ) {
return false;
}
$gi->geoip_open( $database, 0 );
$country_code = $gi->geoip_country_code_by_addr_v6( $ip_address );
} else {
$database = self::get_local_database_path();
if ( ! self::get_file_size( $database ) ) {
return false;
}
$gi->geoip_open( $database, 0 );
$country_code = $gi->geoip_country_code_by_addr( $ip_address );
}
@ -278,6 +293,27 @@ class WC_Geolocation {
return sanitize_text_field( strtoupper( $country_code ) );
}
/**
* Check file size
* Check the file size, if empty file also delete it.
*
* @param string $filename Name of the file to check.
* @return bool|int
*/
private static function get_file_size( $filename ) {
$handle = @fopen( $filename, 'r' );
$s_array = fstat( $handle );
@fclose( $handle );
if ( ! isset( $s_array['size'] ) || 0 === $s_array['size'] ) {
$logger = wc_get_logger();
$logger->notice( 'Empty database file, deleting local copy.', array( 'source' => 'geolocation' ) );
// Delete the file as we do not want to keep empty files around.
@unlink( $filename );
return false;
}
return $s_array['size'];
}
/**
* Use APIs to Geolocate the user.
* @param string $ip_address

View File

@ -96,7 +96,9 @@ class WC_Install {
),
'3.3.0' => array(
'wc_update_330_webhook_logs',
)
'wc_update_330_image_options',
'wc_update_330_db_version',
),
);
/**
@ -557,7 +559,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_attribute_taxonomies (
) $collate;
CREATE TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions (
permission_id BIGINT UNSIGNED NOT NULL auto_increment,
download_id varchar(32) NOT NULL,
download_id varchar(36) NOT NULL,
product_id BIGINT UNSIGNED NOT NULL,
order_id BIGINT UNSIGNED NOT NULL DEFAULT 0,
order_key varchar(200) NOT NULL,
@ -684,6 +686,16 @@ CREATE TABLE {$wpdb->prefix}wc_webhooks (
pending_delivery tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (webhook_id),
KEY user_id (user_id)
) $collate;
CREATE TABLE {$wpdb->prefix}wc_download_log (
download_log_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
timestamp datetime NOT NULL,
permission_id BIGINT UNSIGNED NOT NULL,
user_id BIGINT UNSIGNED NULL,
user_ip_address VARCHAR(100) NULL DEFAULT '',
PRIMARY KEY (download_log_id),
KEY permission_id (permission_id),
KEY timestamp (timestamp)
) $collate;
";

View File

@ -50,9 +50,6 @@ class WC_Post_Data {
add_action( 'untrashed_post', array( __CLASS__, 'untrash_post' ) );
add_action( 'before_delete_post', array( __CLASS__, 'before_delete_order' ) );
// Download permissions
add_action( 'woocommerce_process_product_file_download_paths', array( __CLASS__, 'process_product_file_download_paths' ), 10, 3 );
// Meta cache flushing.
add_action( 'updated_post_meta', array( __CLASS__, 'flush_object_meta_cache' ), 10, 4 );
add_action( 'updated_order_item_meta', array( __CLASS__, 'flush_object_meta_cache' ), 10, 4 );
@ -481,26 +478,13 @@ class WC_Post_Data {
/**
* Update changed downloads.
*
* @deprecated 3.3.0 No action is necessary on changes to download paths since download_id is no longer based on file hash.
* @param int $product_id product identifier
* @param int $variation_id optional product variation identifier
* @param array $downloads newly set files
*/
public static function process_product_file_download_paths( $product_id, $variation_id, $downloads ) {
if ( $variation_id ) {
$product_id = $variation_id;
}
$data_store = WC_Data_Store::load( 'customer-download' );
if ( $downloads ) {
foreach ( $downloads as $download ) {
$new_hash = md5( $download->get_file() );
if ( $download->get_previous_hash() && $download->get_previous_hash() !== $new_hash ) {
// Update permissions.
$data_store->update_download_id( $product_id, $download->get_previous_hash(), $new_hash );
}
}
}
wc_deprecated_function( __FUNCTION__, '3.3' );
}
/**

View File

@ -22,7 +22,6 @@ class WC_Product_Download implements ArrayAccess {
'id' => '',
'name' => '',
'file' => '',
'previous_hash' => '',
);
/**
@ -127,9 +126,11 @@ class WC_Product_Download implements ArrayAccess {
/**
* Set previous_hash.
* @deprecated 3.3.0 No longer using filename based hashing to keep track of files.
* @param string $value
*/
public function set_previous_hash( $value ) {
wc_deprecated_function( __FUNCTION__, '3.3' );
$this->data['previous_hash'] = wc_clean( $value );
}
@ -172,9 +173,11 @@ class WC_Product_Download implements ArrayAccess {
/**
* Get previous_hash.
* @deprecated 3.3.0 No longer using filename based hashing to keep track of files.
* @return string
*/
public function get_previous_hash() {
wc_deprecated_function( __FUNCTION__, '3.3' );
return $this->data['previous_hash'];
}

View File

@ -290,7 +290,7 @@ class WC_Product_Variable extends WC_Product {
'attributes' => $variation->get_variation_attributes(),
'availability_html' => wc_get_stock_html( $variation ),
'backorders_allowed' => $variation->backorders_allowed(),
'dimensions' => wc_format_dimensions( $variation->get_dimensions( false ) ),
'dimensions' => $variation->get_dimensions( false ),
'dimensions_html' => wc_format_dimensions( $variation->get_dimensions( false ) ),
'display_price' => wc_get_price_to_display( $variation ),
'display_regular_price' => wc_get_price_to_display( $variation, array( 'price' => $variation->get_regular_price() ) ),
@ -309,7 +309,7 @@ class WC_Product_Variable extends WC_Product {
'variation_id' => $variation->get_id(),
'variation_is_active' => $variation->variation_is_active(),
'variation_is_visible' => $variation->variation_is_visible(),
'weight' => wc_format_weight( $variation->get_weight() ),
'weight' => $variation->get_weight(),
'weight_html' => wc_format_weight( $variation->get_weight() ),
), $this, $variation );
}

View File

@ -502,9 +502,25 @@ class WC_Query {
* @return array
*/
public function order_by_price_asc_post_clauses( $args ) {
global $wpdb;
$args['join'] .= " INNER JOIN ( SELECT post_id, min( meta_value+0 ) price FROM $wpdb->postmeta WHERE meta_key='_price' GROUP BY post_id ) as price_query ON $wpdb->posts.ID = price_query.post_id ";
$args['orderby'] = " price_query.price ASC ";
global $wpdb, $wp_query;
if ( isset( $wp_query->queried_object, $wp_query->queried_object->term_taxonomy_id, $wp_query->queried_object->taxonomy ) && is_a( $wp_query->queried_object, 'WP_Term' ) ) {
$search_within_terms = get_term_children( $wp_query->queried_object->term_taxonomy_id, $wp_query->queried_object->taxonomy );
$search_within_terms[] = $wp_query->queried_object->term_taxonomy_id;
$args['join'] .= " INNER JOIN (
SELECT post_id, max( meta_value+0 ) price
FROM $wpdb->postmeta
INNER JOIN (
SELECT $wpdb->term_relationships.object_id
FROM $wpdb->term_relationships
WHERE 1=1
AND $wpdb->term_relationships.term_taxonomy_id IN (" . implode( ',', array_map( 'absint', $search_within_terms ) ) . ")
) as products_within_terms ON $wpdb->postmeta.post_id = products_within_terms.object_id
WHERE meta_key='_price' GROUP BY post_id ) as price_query ON $wpdb->posts.ID = price_query.post_id ";
} else {
$args['join'] .= " INNER JOIN ( SELECT post_id, min( meta_value+0 ) price FROM $wpdb->postmeta WHERE meta_key='_price' GROUP BY post_id ) as price_query ON $wpdb->posts.ID = price_query.post_id ";
}
$args['orderby'] = ' price_query.price ASC ';
return $args;
}
@ -535,8 +551,7 @@ class WC_Query {
$args['join'] .= " INNER JOIN ( SELECT post_id, max( meta_value+0 ) price FROM $wpdb->postmeta WHERE meta_key='_price' GROUP BY post_id ) as price_query ON $wpdb->posts.ID = price_query.post_id ";
}
$args['orderby'] = " price_query.price DESC ";
$args['orderby'] = ' price_query.price DESC ';
return $args;
}

View File

@ -141,7 +141,7 @@ class WC_Tracker {
public static function get_theme_info() {
$theme_data = wp_get_theme();
$theme_child_theme = is_child_theme() ? 'Yes' : 'No';
$theme_wc_support = ( ! current_theme_supports( 'woocommerce' ) && ! in_array( $theme_data->template, wc_get_core_supported_themes() ) ) ? 'No' : 'Yes';
$theme_wc_support = ! current_theme_supports( 'woocommerce' ) ? 'No' : 'Yes';
return array( 'name' => $theme_data->Name, 'version' => $theme_data->Version, 'child_theme' => $theme_child_theme, 'wc_support' => $theme_wc_support );
}

View File

@ -16,7 +16,7 @@ if ( ! defined( 'ABSPATH' ) ) {
* Main WooCommerce Class.
*
* @class WooCommerce
* @version 3.2.0
* @version 3.3.0
*/
final class WooCommerce {
@ -25,7 +25,7 @@ final class WooCommerce {
*
* @var string
*/
public $version = '3.2.0';
public $version = '3.3.0';
/**
* The single instance of the class.
@ -256,7 +256,7 @@ final class WooCommerce {
* @return bool
*/
private function is_active_theme( $theme ) {
return get_template() === $theme;
return is_array( $theme ) ? in_array( get_template(), $theme, true ) : get_template() === $theme;
}
/**
@ -275,6 +275,7 @@ final class WooCommerce {
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-coupon-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-customer-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-customer-download-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-customer-download-log-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-object-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-order-data-store-interface.php' );
include_once( WC_ABSPATH . 'includes/interfaces/class-wc-order-item-data-store-interface.php' );
@ -360,6 +361,7 @@ final class WooCommerce {
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-customer-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-customer-data-store-session.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-customer-download-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-customer-download-log-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-shipping-zone-data-store.php' );
include_once( WC_ABSPATH . 'includes/data-stores/abstract-wc-order-data-store-cpt.php' );
include_once( WC_ABSPATH . 'includes/data-stores/class-wc-order-data-store-cpt.php' );
@ -394,10 +396,49 @@ final class WooCommerce {
include_once( WC_ABSPATH . 'includes/class-wc-tracker.php' );
}
$this->theme_support_includes();
$this->query = new WC_Query();
$this->api = new WC_API();
}
/**
* Include classes sfor theme support.
*
* @since 3.3.0
*/
private function theme_support_includes() {
$theme_support = array( 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' );
if ( $this->is_active_theme( array( 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' ) ) ) {
switch ( get_template() ) {
case 'twentyten' :
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-ten.php' );
break;
case 'twentyeleven' :
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-eleven.php' );
break;
case 'twentytwelve' :
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-twelve.php' );
break;
case 'twentythirteen' :
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-thirteen.php' );
break;
case 'twentyfourteen' :
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-fourteen.php' );
break;
case 'twentyfifteen' :
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-fifteen.php' );
break;
case 'twentysixteen' :
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-sixteen.php' );
break;
case 'twentyseventeen' :
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-seventeen.php' );
break;
}
}
}
/**
* Include required frontend files.
*/
@ -415,10 +456,6 @@ final class WooCommerce {
include_once( WC_ABSPATH . 'includes/class-wc-shortcodes.php' ); // Shortcodes class.
include_once( WC_ABSPATH . 'includes/class-wc-embed.php' ); // Embeds.
include_once( WC_ABSPATH . 'includes/class-wc-structured-data.php' ); // Structured Data class.
if ( $this->is_active_theme( 'twentyseventeen' ) ) {
include_once( WC_ABSPATH . 'includes/theme-support/class-wc-twenty-seventeen.php' );
}
}
/**
@ -508,16 +545,28 @@ final class WooCommerce {
/**
* Add WC Image sizes to WP.
*
* As of 3.3, image sizes can be registered via themes using add_theme_support for woocommerce
* and defining an array of args. If these are not defined, we will use defaults. This is
* handled in wc_get_image_size function.
*
* 3.3 sizes:
*
* thumbnail - Used in product listings.
* single - Used on single product pages for the main image.
*
* shop_thumbnail, shop_single, shop_catalog registered for bw compat. @todo remove in 4.0.
*
* @since 2.3
*/
private function add_image_sizes() {
$shop_thumbnail = wc_get_image_size( 'shop_thumbnail' );
$shop_catalog = wc_get_image_size( 'shop_catalog' );
$shop_single = wc_get_image_size( 'shop_single' );
$thumbnail = wc_get_image_size( 'thumbnail' );
$single = wc_get_image_size( 'single' );
add_image_size( 'shop_thumbnail', $shop_thumbnail['width'], $shop_thumbnail['height'], $shop_thumbnail['crop'] );
add_image_size( 'shop_catalog', $shop_catalog['width'], $shop_catalog['height'], $shop_catalog['crop'] );
add_image_size( 'shop_single', $shop_single['width'], $shop_single['height'], $shop_single['crop'] );
add_image_size( 'woocommerce_thumbnail', $thumbnail['width'], $thumbnail['height'], $thumbnail['crop'] );
add_image_size( 'woocommerce_single', $single['width'], $single['height'], $single['crop'] );
add_image_size( 'shop_thumbnail', $thumbnail['width'], $thumbnail['height'], $thumbnail['crop'] );
add_image_size( 'shop_catalog', $thumbnail['width'], $thumbnail['height'], $thumbnail['crop'] );
add_image_size( 'shop_single', $single['width'], $single['height'], $single['crop'] );
}
/**

View File

@ -91,6 +91,7 @@ abstract class Abstract_WC_Order_Item_Type_Data_Store extends WC_Data_Store_WP i
$wpdb->delete( $wpdb->prefix . 'woocommerce_order_items', array( 'order_item_id' => $item->get_id() ) );
$wpdb->delete( $wpdb->prefix . 'woocommerce_order_itemmeta', array( 'order_item_id' => $item->get_id() ) );
do_action( 'woocommerce_delete_order_item', $item->get_id() );
$this->clear_cache( $item );
}
}

View File

@ -274,6 +274,8 @@ class WC_Customer_Download_Data_Store implements WC_Customer_Download_Data_Store
/**
* Update download ids if the hash changes.
*
* @deprecated 3.3.0 Download id is now a static UUID and should not be changed based on file hash.
*
* @param int $product_id
* @param string $old_id
* @param string $new_id
@ -281,6 +283,8 @@ class WC_Customer_Download_Data_Store implements WC_Customer_Download_Data_Store
public function update_download_id( $product_id, $old_id, $new_id ) {
global $wpdb;
wc_deprecated_function( __METHOD__, '3.3' );
$wpdb->update(
$wpdb->prefix . 'woocommerce_downloadable_product_permissions',
array(

View File

@ -0,0 +1,221 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC Customer Download Log Data Store.
*
* @version 3.3.0
* @category Class
* @author WooThemes
*/
class WC_Customer_Download_Log_Data_Store implements WC_Customer_Download_Log_Data_Store_Interface {
// Table name for download logs.
const WC_DOWNLOAD_LOG_TABLE = 'wc_download_log';
/**
* Get the table name for download logs.
*
* @return string
*/
public static function get_table_name() {
return self::WC_DOWNLOAD_LOG_TABLE;
}
/**
* Create download log entry.
*
* @param WC_Customer_Download_Log $download_log
*/
public function create( WC_Customer_Download_Log &$download_log ) {
global $wpdb;
// Always set a timestamp.
if ( is_null( $download_log->get_timestamp( 'edit' ) ) ) {
$download_log->set_timestamp( current_time( 'timestamp', true ) );
}
$data = array(
'timestamp' => date( 'Y-m-d H:i:s', $download_log->get_timestamp( 'edit' )->getTimestamp() ),
'permission_id' => $download_log->get_permission_id( 'edit' ),
'user_id' => $download_log->get_user_id( 'edit' ),
'user_ip_address' => $download_log->get_user_ip_address( 'edit' ),
);
$format = array(
'%s',
'%s',
'%s',
'%s',
);
$result = $wpdb->insert(
$wpdb->prefix . self::get_table_name(),
apply_filters( 'woocommerce_downloadable_product_download_log_insert_data', $data ),
apply_filters( 'woocommerce_downloadable_product_download_log_insert_format', $format, $data )
);
do_action( 'woocommerce_downloadable_product_download_log_insert', $data );
if ( $result ) {
$download_log->set_id( $wpdb->insert_id );
$download_log->apply_changes();
}
else {
wp_die( __( 'Unable to insert download log entry in database.', 'woocommerce' ) );
}
}
/**
* Method to read a download log from the database.
*
* @param $download_log
*
* @throws Exception
*/
public function read( &$download_log ) {
global $wpdb;
$download_log->set_defaults();
// Ensure we have an id to pull from the DB.
if ( ! $download_log->get_id() ) {
throw new Exception( __( 'Invalid download log: no ID.', 'woocommerce' ) );
}
// Query the DB for the download log.
$raw_download_log_query = $wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}" . self::get_table_name() . " WHERE download_log_id = %d", $download_log->get_id()
);
$raw_download_log = $wpdb->get_row( $raw_download_log_query );
if ( ! $raw_download_log ) {
throw new Exception( __( 'Invalid download log: not found.', 'woocommerce' ) );
}
$download_log->set_props( array(
'timestamp' => strtotime( $raw_download_log->timestamp ),
'permission_id' => $raw_download_log->permission_id,
'user_id' => $raw_download_log->user_id,
'user_ip_address' => $raw_download_log->user_ip_address,
) );
$download_log->set_object_read( true );
}
/**
* Method to update a download log in the database.
*
* @param WC_Customer_Download_Log $download_log
*/
public function update( &$download_log ) {
global $wpdb;
$data = array(
'timestamp' => date( 'Y-m-d H:i:s', $download_log->get_timestamp( 'edit' )->getTimestamp() ),
'permission_id' => $download_log->get_permission_id( 'edit' ),
'user_id' => $download_log->get_user_id( 'edit' ),
'user_ip_address' => $download_log->get_user_ip_address( 'edit' ),
);
$format = array(
'%s',
'%s',
'%s',
'%s',
);
$wpdb->update(
$wpdb->prefix . self::get_table_name(),
$data,
array(
'download_log_id' => $download_log->get_id(),
),
$format
);
$download_log->apply_changes();
}
/**
* Get a download log object.
*
* @param array $data From the DB.
* @return WC_Customer_Download_Log
*/
private function get_download_log( $data ) {
return new WC_Customer_Download_Log( $data );
}
/**
* Get array of download log ids by specified args.
*
* @param array $args
* @return array
*/
public function get_download_logs( $args = array() ) {
global $wpdb;
$args = wp_parse_args( $args, array(
'permission_id' => '',
'user_id' => '',
'user_ip_address' => '',
'orderby' => 'download_log_id',
'order' => 'DESC',
'limit' => -1,
'return' => 'objects',
) );
$query = array();
$query[] = "SELECT * FROM {$wpdb->prefix}" . self::get_table_name() . " WHERE 1=1";
if ( $args['permission_id'] ) {
$query[] = $wpdb->prepare( "AND permission_id = %d", $args['permission_id'] );
}
if ( $args['user_id'] ) {
$query[] = $wpdb->prepare( "AND user_id = %d", $args['user_id'] );
}
if ( $args['user_ip_address'] ) {
$query[] = $wpdb->prepare( "AND user_ip_address = %s", $args['user_ip_address'] );
}
$allowed_orders = array( 'download_log_id', 'timestamp', 'permission_id', 'user_id' );
$order = in_array( $args['order'], $allowed_orders ) ? $args['order'] : 'download_log_id';
$orderby = 'DESC' === strtoupper( $args['orderby'] ) ? 'DESC' : 'ASC';
$orderby_sql = sanitize_sql_orderby( "{$order} {$orderby}" );
$query[] = "ORDER BY {$orderby_sql}";
if ( 0 < $args['limit'] ) {
$query[] = $wpdb->prepare( "LIMIT %d", $args['limit'] );
}
$raw_download_logs = $wpdb->get_results( implode( ' ', $query ) );
switch ( $args['return'] ) {
case 'ids' :
return wp_list_pluck( $raw_download_logs, 'download_log_id' );
default :
return array_map( array( $this, 'get_download_log' ), $raw_download_logs );
}
}
/**
* Get download logs for a given download permission.
*
* @param int $permission_id
* @return array
*/
public function get_download_logs_for_permission( $permission_id ) {
// If no permission_id is passed, return an empty array.
if ( empty( $permission_id ) ) {
return array();
}
return $this->get_download_logs( array(
'permission_id' => $permission_id
) );
}
}

View File

@ -168,7 +168,7 @@ abstract class WC_CSV_Exporter {
@ini_set( 'output_handler', '' );
ignore_user_abort( true );
wc_set_time_limit( 0 );
nocache_headers();
wc_nocache_headers();
header( 'Content-Type: text/csv; charset=utf-8' );
header( 'Content-Disposition: attachment; filename=' . $this->get_filename() );
header( 'Pragma: no-cache' );

View File

@ -339,6 +339,11 @@ class WC_Gateway_Paypal_IPN_Handler extends WC_Gateway_Paypal_Response {
$mailer = WC()->mailer();
$message = $mailer->wrap_message( $subject, $message );
$woocommerce_paypal_settings = get_option('woocommerce_paypal_settings');
if ( ! empty( $woocommerce_paypal_settings['ipn_notification'] ) && 'no' === $woocommerce_paypal_settings['ipn_notification'] ) {
return;
}
$mailer->send( ! empty( $new_order_settings['recipient'] ) ? $new_order_settings['recipient'] : get_option( 'admin_email' ), strip_tags( $subject ), $message );
}
}

View File

@ -50,6 +50,13 @@ return array(
'default' => 'no',
'description' => sprintf( __( 'Log PayPal events, such as IPN requests, inside %s', 'woocommerce' ), '<code>' . WC_Log_Handler_File::get_log_file_path( 'paypal' ) . '</code>' ),
),
'ipn_notification' => array(
'title' => __( 'IPN Email Notifications', 'woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable IPN email notification', 'woocommerce' ),
'default' => 'yes',
'description' => __( 'Send an email to the user handling orders when an IPN is received from PayPal.', 'woocommerce' )
),
'advanced' => array(
'title' => __( 'Advanced options', 'woocommerce' ),
'type' => 'title',

View File

@ -0,0 +1,31 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC Customer Download Log Data Store Interface.
*
* @version 3.3.0
* @category Interface
* @author WooThemes
*/
interface WC_Customer_Download_Log_Data_Store_Interface {
/**
* Get array of download log ids by specified args.
*
* @param array $args
* @return array of WC_Customer_Download_Log
*/
public function get_download_logs( $args = array() );
/**
* Get logs for a specific download permission.
*
* @param int $permission_id
* @return array
*/
public function get_download_logs_for_permission( $permission_id );
}

View File

@ -0,0 +1,52 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Eleven support.
*
* @class WC_Twenty_Eleven
* @since 3.3.0
* @package WooCommerce/Classes
*/
class WC_Twenty_Eleven {
/**
* Theme init.
*/
public static function init() {
// Remove default wrappers.
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper' );
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end' );
// Add custom wrappers.
add_action( 'woocommerce_before_main_content', array( __CLASS__, 'output_content_wrapper' ) );
add_action( 'woocommerce_after_main_content', array( __CLASS__, 'output_content_wrapper_end' ) );
// Declare theme support for features.
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 130,
'single_image_width' => 280,
) );
}
/**
* Open wrappers.
*/
public static function output_content_wrapper() {
echo '<div id="primary"><div id="content" role="main" class="twentyeleven">';
}
/**
* Close wrappers.
*/
public static function output_content_wrapper_end() {
echo '</div></div>';
}
}
WC_Twenty_Eleven::init();

View File

@ -0,0 +1,52 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Fifteen support.
*
* @class WC_Twenty_Fifteen
* @since 3.3.0
* @package WooCommerce/Classes
*/
class WC_Twenty_Fifteen {
/**
* Theme init.
*/
public static function init() {
// Remove default wrappers.
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper' );
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end' );
// Add custom wrappers.
add_action( 'woocommerce_before_main_content', array( __CLASS__, 'output_content_wrapper' ) );
add_action( 'woocommerce_after_main_content', array( __CLASS__, 'output_content_wrapper_end' ) );
// Declare theme support for features.
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 140,
'single_image_width' => 302,
) );
}
/**
* Open wrappers.
*/
public static function output_content_wrapper() {
echo '<div id="primary" role="main" class="content-area twentyfifteen"><div id="main" class="site-main t15wc">';
}
/**
* Close wrappers.
*/
public static function output_content_wrapper_end() {
echo '</div></div>';
}
}
WC_Twenty_Fifteen::init();

View File

@ -0,0 +1,53 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Fourteen support.
*
* @class WC_Twenty_Fourteen
* @since 3.3.0
* @package WooCommerce/Classes
*/
class WC_Twenty_Fourteen {
/**
* Theme init.
*/
public static function init() {
// Remove default wrappers.
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper' );
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end' );
// Add custom wrappers.
add_action( 'woocommerce_before_main_content', array( __CLASS__, 'output_content_wrapper' ) );
add_action( 'woocommerce_after_main_content', array( __CLASS__, 'output_content_wrapper_end' ) );
// Declare theme support for features.
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 105,
'single_image_width' => 228,
) );
}
/**
* Open wrappers.
*/
public static function output_content_wrapper() {
echo '<div id="primary" class="content-area"><div id="content" role="main" class="site-content twentyfourteen"><div class="tfwc">';
}
/**
* Close wrappers.
*/
public static function output_content_wrapper_end() {
echo '</div></div></div>';
get_sidebar( 'content' );
}
}
WC_Twenty_Fourteen::init();

View File

@ -8,7 +8,6 @@ if ( ! defined( 'ABSPATH' ) ) {
*
* @class WC_Twenty_Seventeen
* @since 2.6.9
* @version 2.6.9
* @package WooCommerce/Classes
*/
class WC_Twenty_Seventeen {
@ -24,12 +23,20 @@ class WC_Twenty_Seventeen {
add_action( 'woocommerce_after_main_content', array( __CLASS__, 'output_content_wrapper_end' ), 10 );
add_filter( 'woocommerce_enqueue_styles', array( __CLASS__, 'enqueue_styles' ) );
add_filter( 'twentyseventeen_custom_colors_css', array( __CLASS__, 'custom_colors_css' ), 10, 3 );
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 150,
'single_image_width' => 322,
) );
}
/**
* Enqueue CSS for this theme.
*
* @param array $styles
* @param array $styles Array of registered styles.
* @return array
*/
public static function enqueue_styles( $styles ) {
@ -48,30 +55,28 @@ class WC_Twenty_Seventeen {
/**
* Open the Twenty Seventeen wrapper.
*/
public static function output_content_wrapper() { ?>
<div class="wrap">
<div id="primary" class="content-area twentyseventeen">
<main id="main" class="site-main" role="main">
<?php
public static function output_content_wrapper() {
echo '<div class="wrap">';
echo '<div id="primary" class="content-area twentyseventeen">';
echo '<main id="main" class="site-main" role="main">';
}
/**
* Close the Twenty Seventeen wrapper.
*/
public static function output_content_wrapper_end() { ?>
</main>
</div>
<?php get_sidebar(); ?>
</div>
<?php
public static function output_content_wrapper_end() {
echo '</main>';
echo '</div>';
get_sidebar();
echo '</div>';
}
/**
* Custom colors.
*
* @param string $css
* @param string $hue
* @param string $saturation
* @param string $css Styles.
* @param string $hue Color.
* @param string $saturation Saturation.
* @return string
*/
public static function custom_colors_css( $css, $hue, $saturation ) {

View File

@ -0,0 +1,52 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Sixteen support.
*
* @class WC_Twenty_Sixteen
* @since 3.3.0
* @package WooCommerce/Classes
*/
class WC_Twenty_Sixteen {
/**
* Theme init.
*/
public static function init() {
// Remove default wrappers.
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper' );
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end' );
// Add custom wrappers.
add_action( 'woocommerce_before_main_content', array( __CLASS__, 'output_content_wrapper' ) );
add_action( 'woocommerce_after_main_content', array( __CLASS__, 'output_content_wrapper_end' ) );
// Declare theme support for features.
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 186,
'single_image_width' => 390,
) );
}
/**
* Open wrappers.
*/
public static function output_content_wrapper() {
echo '<div id="primary" class="content-area twentysixteen"><main id="main" class="site-main" role="main">';
}
/**
* Close wrappers.
*/
public static function output_content_wrapper_end() {
echo '</main></div>';
}
}
WC_Twenty_Sixteen::init();

View File

@ -0,0 +1,52 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Ten support.
*
* @class WC_Twenty_Ten
* @since 3.3.0
* @package WooCommerce/Classes
*/
class WC_Twenty_Ten {
/**
* Theme init.
*/
public static function init() {
// Remove default wrappers.
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper' );
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end' );
// Add custom wrappers.
add_action( 'woocommerce_before_main_content', array( __CLASS__, 'output_content_wrapper' ) );
add_action( 'woocommerce_after_main_content', array( __CLASS__, 'output_content_wrapper_end' ) );
// Declare theme support for features.
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 140,
'single_image_width' => 300,
) );
}
/**
* Open wrappers.
*/
public static function output_content_wrapper() {
echo '<div id="container"><div id="content" role="main">';
}
/**
* Close wrappers.
*/
public static function output_content_wrapper_end() {
echo '</div></div>';
}
}
WC_Twenty_Ten::init();

View File

@ -0,0 +1,52 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Thirteen support.
*
* @class WC_Twenty_Thirteen
* @since 3.3.0
* @package WooCommerce/Classes
*/
class WC_Twenty_Thirteen {
/**
* Theme init.
*/
public static function init() {
// Remove default wrappers.
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper' );
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end' );
// Add custom wrappers.
add_action( 'woocommerce_before_main_content', array( __CLASS__, 'output_content_wrapper' ) );
add_action( 'woocommerce_after_main_content', array( __CLASS__, 'output_content_wrapper_end' ) );
// Declare theme support for features.
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 140,
'single_image_width' => 290,
) );
}
/**
* Open wrappers.
*/
public static function output_content_wrapper() {
echo '<div id="primary" class="site-content"><div id="content" role="main" class="entry-content twentythirteen">';
}
/**
* Close wrappers.
*/
public static function output_content_wrapper_end() {
echo '</div></div>';
}
}
WC_Twenty_Thirteen::init();

View File

@ -0,0 +1,52 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Twenty Twelve support.
*
* @class WC_Twenty_Twelve
* @since 3.3.0
* @package WooCommerce/Classes
*/
class WC_Twenty_Twelve {
/**
* Theme init.
*/
public static function init() {
// Remove default wrappers.
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper' );
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end' );
// Add custom wrappers.
add_action( 'woocommerce_before_main_content', array( __CLASS__, 'output_content_wrapper' ) );
add_action( 'woocommerce_after_main_content', array( __CLASS__, 'output_content_wrapper_end' ) );
// Declare theme support for features.
add_theme_support( 'wc-product-gallery-zoom' );
add_theme_support( 'wc-product-gallery-lightbox' );
add_theme_support( 'wc-product-gallery-slider' );
add_theme_support( 'woocommerce', array(
'thumbnail_image_width' => 140,
'single_image_width' => 300,
) );
}
/**
* Open wrappers.
*/
public static function output_content_wrapper() {
echo '<div id="primary" class="site-content"><div id="content" role="main" class="twentytwelve">';
}
/**
* Close wrappers.
*/
public static function output_content_wrapper_end() {
echo '</div></div>';
}
}
WC_Twenty_Twelve::init();

View File

@ -222,7 +222,7 @@ if ( ! function_exists( 'is_add_payment_method_page' ) ) {
function is_add_payment_method_page() {
global $wp;
return ( is_page( wc_get_page_id( 'myaccount' ) ) && isset( $wp->query_vars['add-payment-method'] ) );
return ( is_page( wc_get_page_id( 'myaccount' ) ) && ( isset( $wp->query_vars['payment-methods'] ) || isset( $wp->query_vars['add-payment-method'] ) ) );
}
}

View File

@ -659,39 +659,64 @@ function wc_mail( $to, $subject, $message, $headers = "Content-Type: text/html\r
}
/**
* Get an image size.
* Get an image size by name or defined dimensions.
*
* Variable is filtered by woocommerce_get_image_size_{image_size}.
* The returned variable is filtered by woocommerce_get_image_size_{image_size} filter to
* allow 3rd party customisation.
*
* @param array|string $image_size
* @return array
* Sizes defined by the theme take priority over settings. Settings are hidden when a theme
* defines sizes.
*
* @param array|string $image_size Name of the image size to get, or an array of dimensions.
* @return array Array of dimensions including width, height, and cropping mode. Cropping mode is 0 for no crop, and 1 for hard crop.
*/
function wc_get_image_size( $image_size ) {
$theme_support = get_theme_support( 'woocommerce' );
$theme_support = is_array( $theme_support ) ? $theme_support[0]: false;
$size = array(
'width' => 600,
'height' => 600,
'crop' => 1,
);
if ( is_array( $image_size ) ) {
$width = isset( $image_size[0] ) ? $image_size[0] : '300';
$height = isset( $image_size[1] ) ? $image_size[1] : '300';
$crop = isset( $image_size[2] ) ? $image_size[2] : 1;
$size = array(
'width' => $width,
'height' => $height,
'crop' => $crop,
'width' => isset( $image_size[0] ) ? $image_size[0] : 600,
'height' => isset( $image_size[1] ) ? $image_size[1] : 600,
'crop' => isset( $image_size[2] ) ? $image_size[2] : 1,
);
$image_size = $size['width'] . '_' . $size['height'];
} elseif ( in_array( $image_size, array( 'single', 'shop_single' ), true ) ) {
// If the theme supports woocommerce, take image sizes from that definition.
if ( isset( $theme_support[ 'single_image_width' ] ) ) {
$size['width'] = $theme_support[ 'single_image_width' ];
} else {
$size['width'] = get_option( 'woocommerce_single_image_width', 600 );
}
$size['height'] = 9999999999;
$size['crop'] = 0;
$image_size = 'single';
} elseif ( in_array( $image_size, array( 'thumbnail', 'shop_thumbnail', 'shop_catalog' ), true ) ) {
// If the theme supports woocommerce, take image sizes from that definition.
if ( isset( $theme_support[ 'thumbnail_image_width' ] ) ) {
$size['width'] = $theme_support[ 'thumbnail_image_width' ];
} else {
$size['width'] = get_option( 'woocommerce_thumbnail_image_width', 300 );
}
$image_size = $width . '_' . $height;
$cropping = get_option( 'woocommerce_thumbnail_cropping', '1:1' );
} elseif ( in_array( $image_size, array( 'shop_thumbnail', 'shop_catalog', 'shop_single' ) ) ) {
$size = get_option( $image_size . '_image_size', array() );
$size['width'] = isset( $size['width'] ) ? $size['width'] : '300';
$size['height'] = isset( $size['height'] ) ? $size['height'] : '300';
$size['crop'] = isset( $size['crop'] ) ? $size['crop'] : 0;
} else {
$size = array(
'width' => '300',
'height' => '300',
'crop' => 1,
);
if ( 'uncropped' === $cropping ) {
$size['height'] = 9999999999;
$size['crop'] = 0;
} else {
$cropping_split = explode( ':', $cropping );
$width_ratio = max( 1, current( $cropping_split ) );
$height_ratio = max( 1, end( $cropping_split ) );
$size['height'] = round( ( $size['width'] / $width_ratio ) * $height_ratio );
$size['crop'] = 1;
}
$image_size = 'thumbnail';
}
return apply_filters( 'woocommerce_get_image_size_' . $image_size, $size );
@ -911,11 +936,11 @@ add_filter( 'attachment_link', 'wc_fix_product_attachment_link', 10, 2 );
/**
* Protect downloads from ms-files.php in multisite.
*
* @param mixed $rewrite
* @param string $rewrite rewrite rules.
* @return string
*/
function wc_ms_protect_download_rewite_rules( $rewrite ) {
if ( ! is_multisite() || 'redirect' == get_option( 'woocommerce_file_download_method' ) ) {
if ( ! is_multisite() || 'redirect' === get_option( 'woocommerce_file_download_method' ) ) {
return $rewrite;
}
@ -930,16 +955,6 @@ function wc_ms_protect_download_rewite_rules( $rewrite ) {
}
add_filter( 'mod_rewrite_rules', 'wc_ms_protect_download_rewite_rules' );
/**
* WooCommerce Core Supported Themes.
*
* @since 2.2
* @return string[]
*/
function wc_get_core_supported_themes() {
return array( 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' );
}
/**
* Wrapper function to execute the `woocommerce_deliver_webhook_async` cron.
* hook, see WC_Webhook::process().
@ -1404,8 +1419,8 @@ function wc_get_shipping_method_count( $include_legacy = false ) {
/**
* Wrapper for set_time_limit to see if it is enabled.
* @since 2.6.0
*
* @since 2.6.0
* @param int $limit
*/
function wc_set_time_limit( $limit = 0 ) {
@ -1414,6 +1429,16 @@ function wc_set_time_limit( $limit = 0 ) {
}
}
/**
* Wrapper for nocache_headers which also disables page caching.
*
* @since 3.2.4
*/
function wc_nocache_headers() {
WC_Cache_Helper::set_nocache_constants();
nocache_headers();
}
/**
* Used to sort products attributes with uasort.
* @since 2.6.0

View File

@ -809,7 +809,7 @@ function woocommerce_placeholder_img_src() {
/**
* @deprecated 3.0
*/
function woocommerce_placeholder_img( $size = 'shop_thumbnail' ) {
function woocommerce_placeholder_img( $size = 'woocommerce_thumbnail' ) {
wc_deprecated_function( __FUNCTION__, '3.0', 'wc_placeholder_img' );
return wc_placeholder_img( $size );
}
@ -972,3 +972,15 @@ function wc_get_customer_avatar_url( $email ) {
return get_avatar_url( $email );
}
/**
* WooCommerce Core Supported Themes.
*
* @deprecated 3.3.0
* @since 2.2
* @return string[]
*/
function wc_get_core_supported_themes() {
wc_deprecated_function( 'wc_get_core_supported_themes()', '3.3' );
return array( 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' );
}

View File

@ -294,7 +294,7 @@ function wc_placeholder_img_src() {
*
* @return string
*/
function wc_placeholder_img( $size = 'shop_thumbnail' ) {
function wc_placeholder_img( $size = 'woocommerce_thumbnail' ) {
$dimensions = wc_get_image_size( $size );
return apply_filters( 'woocommerce_placeholder_img', '<img src="' . wc_placeholder_img_src() . '" alt="' . esc_attr__( 'Placeholder', 'woocommerce' ) . '" width="' . esc_attr( $dimensions['width'] ) . '" class="woocommerce-placeholder wp-post-image" height="' . esc_attr( $dimensions['height'] ) . '" />', $size, $dimensions );
@ -693,18 +693,18 @@ function wc_get_product_attachment_props( $attachment_id = null, $product = fals
$props['full_src_h'] = $src[2];
// Thumbnail version.
$src = wp_get_attachment_image_src( $attachment_id, 'shop_thumbnail' );
$src = wp_get_attachment_image_src( $attachment_id, 'woocommerce_thumbnail' );
$props['thumb_src'] = $src[0];
$props['thumb_src_w'] = $src[1];
$props['thumb_src_h'] = $src[2];
// Image source.
$src = wp_get_attachment_image_src( $attachment_id, 'shop_single' );
$src = wp_get_attachment_image_src( $attachment_id, 'woocommerce_single' );
$props['src'] = $src[0];
$props['src_w'] = $src[1];
$props['src_h'] = $src[2];
$props['srcset'] = function_exists( 'wp_get_attachment_image_srcset' ) ? wp_get_attachment_image_srcset( $attachment_id, 'shop_single' ) : false;
$props['sizes'] = function_exists( 'wp_get_attachment_image_sizes' ) ? wp_get_attachment_image_sizes( $attachment_id, 'shop_single' ) : false;
$props['srcset'] = function_exists( 'wp_get_attachment_image_srcset' ) ? wp_get_attachment_image_srcset( $attachment_id, 'woocommerce_single' ) : false;
$props['sizes'] = function_exists( 'wp_get_attachment_image_sizes' ) ? wp_get_attachment_image_sizes( $attachment_id, 'woocommerce_single' ) : false;
// Alt text fallbacks.
$props['alt'] = empty( $props['alt'] ) ? $props['caption'] : $props['alt'];

View File

@ -684,9 +684,10 @@ if ( ! function_exists( 'woocommerce_taxonomy_archive_description' ) ) {
*/
function woocommerce_taxonomy_archive_description() {
if ( is_product_taxonomy() && 0 === absint( get_query_var( 'paged' ) ) ) {
$description = wc_format_content( term_description() );
if ( $description ) {
echo '<div class="term-description">' . $description . '</div>'; // WPCS: XSS ok.
$term = get_queried_object();
if ( $term && ! empty( $term->description ) ) {
echo '<div class="term-description">' . wc_format_content( $term->description ) . '</div>'; // WPCS: XSS ok.
}
}
}
@ -794,12 +795,12 @@ if ( ! function_exists( 'woocommerce_get_product_thumbnail' ) ) {
* Get the product thumbnail, or the placeholder if not set.
*
* @subpackage Loop
* @param string $size (default: 'shop_catalog').
* @param string $size (default: 'woocommerce_thumbnail').
* @param int $deprecated1 Deprecated since WooCommerce 2.0 (default: 0).
* @param int $deprecated2 Deprecated since WooCommerce 2.0 (default: 0).
* @return string
*/
function woocommerce_get_product_thumbnail( $size = 'shop_catalog', $deprecated1 = 0, $deprecated2 = 0 ) {
function woocommerce_get_product_thumbnail( $size = 'woocommerce_thumbnail', $deprecated1 = 0, $deprecated2 = 0 ) {
global $product;
$image_size = apply_filters( 'single_product_archive_thumbnail_size', $size );
@ -1856,7 +1857,7 @@ if ( ! function_exists( 'woocommerce_subcategory_thumbnail' ) ) {
* @subpackage Loop
*/
function woocommerce_subcategory_thumbnail( $category ) {
$small_thumbnail_size = apply_filters( 'subcategory_archive_thumbnail_size', 'shop_catalog' );
$small_thumbnail_size = apply_filters( 'subcategory_archive_thumbnail_size', 'woocommerce_thumbnail' );
$dimensions = wc_get_image_size( $small_thumbnail_size );
$thumbnail_id = get_woocommerce_term_meta( $category->term_id, 'thumbnail_id', true );

View File

@ -1449,3 +1449,32 @@ function wc_update_330_webhook_logs() {
}
}
}
/**
* Update image settings to use new aspect ratios and widths.
*/
function wc_update_330_image_options() {
$old_thumbnail_size = get_option( 'shop_catalog_image_size', array() );
$old_single_size = get_option( 'shop_single_image_size', array() );
if ( ! empty( $old_thumbnail_size['width'] ) ) {
update_option( 'woocommerce_thumbnail_image_width', absint( $old_thumbnail_size['width'] ) );
}
if ( ! empty( $old_thumbnail_size['crop'] ) ) {
update_option( 'woocommerce_thumbnail_cropping', '1:1' );
} elseif ( isset( $old_thumbnail_size['crop'] ) ) {
update_option( 'woocommerce_thumbnail_cropping', 'uncropped' );
}
if ( ! empty( $old_single_size['width'] ) ) {
update_option( 'woocommerce_single_image_width', absint( $old_single_size['width'] ) );
}
}
/**
* Update DB Version.
*/
function wc_update_330_db_version() {
WC_Install::update_db_version( '3.3.0' );
}

View File

@ -83,7 +83,7 @@ class WC_Widget_Recently_Viewed extends WC_Widget {
);
}
$r = new WP_Query( $query_args );
$r = new WP_Query( apply_filters( 'woocommerce_recently_viewed_products_widget_query_args', $query_args ) );
if ( $r->have_posts() ) {

View File

@ -5,6 +5,15 @@
<description>WooCommerce dev PHP_CodeSniffer ruleset.</description>
<!-- Exclude paths -->
<exclude-pattern>tests/cli/</exclude-pattern>
<exclude-pattern>apigen/</exclude-pattern>
<exclude-pattern>includes/gateways/simplify-commerce/includes/</exclude-pattern>
<exclude-pattern>includes/libraries/</exclude-pattern>
<exclude-pattern>includes/api/legacy/</exclude-pattern>
<rule ref="PHPCompatibility"/>
<rule ref="WordPress">
<exclude name="WordPress.VIP.RestrictedFunctions" />
<exclude name="WordPress.VIP.OrderByRand" />
@ -12,7 +21,12 @@
<rule ref="WordPress.VIP.ValidatedSanitizedInput">
<properties>
<property name="customSanitizingFunctions" type="array" value="wc_clean" />
<property name="customSanitizingFunctions" type="array" value="wc_clean,wc_sanitize_tooltip,wc_format_decimal,wc_stock_amount" />
</properties>
</rule>
<rule ref="WordPress.XSS.EscapeOutput">
<properties>
<property name="customEscapingFunctions" type="array" value="wc_help_tip,wc_sanitize_tooltip" />
</properties>
</rule>
</ruleset>

View File

@ -55,4 +55,6 @@ if ( $available_gateways = WC()->payment_gateways->get_available_payment_gateway
</div>
</div>
</form>
<?php else : ?>
<p class="woocommerce-notice woocommerce-notice--info woocommerce-info"><?php esc_html_e( 'New payment methods can only be added during checkout. Please contact us if you require assistance.', 'woocommerce' ); ?></p>
<?php endif; ?>

View File

@ -76,4 +76,6 @@ do_action( 'woocommerce_before_account_payment_methods', $has_methods ); ?>
<?php do_action( 'woocommerce_after_account_payment_methods', $has_methods ); ?>
<a class="button" href="<?php echo esc_url( wc_get_endpoint_url( 'add-payment-method' ) ); ?>"><?php esc_html_e( 'Add payment method', 'woocommerce' ); ?></a>
<?php if ( WC()->payment_gateways->get_available_payment_gateways() ) : ?>
<a class="button" href="<?php echo esc_url( wc_get_endpoint_url( 'add-payment-method' ) ); ?>"><?php esc_html_e( 'Add payment method', 'woocommerce' ); ?></a>
<?php endif; ?>

View File

@ -46,8 +46,8 @@ $wrapper_classes = apply_filters( 'woocommerce_single_product_image_gallery_cl
);
if ( has_post_thumbnail() ) {
$html = '<div data-thumb="' . get_the_post_thumbnail_url( $post->ID, 'shop_thumbnail' ) . '" class="woocommerce-product-gallery__image"><a href="' . esc_url( $full_size_image[0] ) . '">';
$html .= get_the_post_thumbnail( $post->ID, 'shop_single', $attributes );
$html = '<div data-thumb="' . get_the_post_thumbnail_url( $post->ID, 'woocommerce_thumbnail' ) . '" class="woocommerce-product-gallery__image"><a href="' . esc_url( $full_size_image[0] ) . '">';
$html .= get_the_post_thumbnail( $post->ID, 'woocommerce_single', $attributes );
$html .= '</a></div>';
} else {
$html = '<div class="woocommerce-product-gallery__image--placeholder">';

View File

@ -27,7 +27,7 @@ $attachment_ids = $product->get_gallery_image_ids();
if ( $attachment_ids && has_post_thumbnail() ) {
foreach ( $attachment_ids as $attachment_id ) {
$full_size_image = wp_get_attachment_image_src( $attachment_id, 'full' );
$thumbnail = wp_get_attachment_image_src( $attachment_id, 'shop_thumbnail' );
$thumbnail = wp_get_attachment_image_src( $attachment_id, 'woocommerce_thumbnail' );
$attributes = array(
'title' => get_post_field( 'post_title', $attachment_id ),
'data-caption' => get_post_field( 'post_excerpt', $attachment_id ),
@ -38,7 +38,7 @@ if ( $attachment_ids && has_post_thumbnail() ) {
);
$html = '<div data-thumb="' . esc_url( $thumbnail[0] ) . '" class="woocommerce-product-gallery__image"><a href="' . esc_url( $full_size_image[0] ) . '">';
$html .= wp_get_attachment_image( $attachment_id, 'shop_single', false, $attributes );
$html .= wp_get_attachment_image( $attachment_id, 'woocommerce_single', false, $attributes );
$html .= '</a></div>';
echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', $html, $attachment_id );

View File

@ -1,5 +1,5 @@
#!/usr/bin/env bash
if [[ ${TRAVIS_PHP_VERSION} == '7.1' ]]; then
if [[ ${RUN_CODE_COVERAGE} == 1 ]]; then
phpunit -c phpunit.xml --coverage-clover=coverage.clover
else
phpunit -c phpunit.xml

View File

@ -15,11 +15,17 @@ if [ $1 == 'before' ]; then
composer global require "phpunit/phpunit=6.2.*"
fi
# Remove Xdebug from PHP runtime for all PHP version except 7.1 to speed up builds.
# We need Xdebug enabled in the PHP 7.1 build job as it is used to generate code coverage.
if [[ ${RUN_CODE_COVERAGE} != 1 ]]; then
phpenv config-rm xdebug.ini
fi
fi
if [ $1 == 'after' ]; then
if [[ ${TRAVIS_PHP_VERSION} == '7.1' ]]; then
if [[ ${RUN_CODE_COVERAGE} == 1 ]]; then
bash <(curl -s https://codecov.io/bash)
wget https://scrutinizer-ci.com/ocular.phar
chmod +x ocular.phar

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