Merge branch 'master' into feature/webhook-crud

This commit is contained in:
Claudio Sanches 2017-11-16 12:20:22 -02:00
commit 9fe0c7261e
166 changed files with 9589 additions and 7626 deletions

4
.gitignore vendored
View File

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

View File

@ -9,17 +9,21 @@ php:
- 7.1 - 7.1
env: 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: matrix:
fast_finish: true
include: include:
- php: 5.3 - php: 5.3
env: WP_VERSION=latest WP_MULTISITE=0 PHP_LATEST_STABLE=7.1
dist: precise dist: precise
- php: 5.2 - php: 5.2
env: WP_VERSION=latest WP_MULTISITE=0 PHP_LATEST_STABLE=7.1
dist: precise 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: before_script:
- export PATH="$HOME/.composer/vendor/bin:$PATH" - 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 - On checkout, improved the field locale logic to work without clearing default values.
* Tweak - Change title of customer invoice email for clarity. * Tweak - Change title of customer invoice email for clarity.
* Tweak - Use custom event instead of blur to trigger validation. * 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. * Tweak - Various setup Wizard improvements.
* Dev - Fixed orders date query when querying by meta data. * Dev - Fixed orders date query when querying by meta data.
* Dev - In the CSV exporter, added a filter to process meta values before export. * 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

@ -1893,73 +1893,227 @@ ul.wc_coupon_list_block {
font-size: inherit; font-size: inherit;
margin: 3px 0; margin: 3px 0;
} }
}
.column-order_total, .post-type-shop_order {
.column-order_date { .tablenav .one-page .displaying-num {
width: 9%; display: none;
} }
.wp-list-table {
.column-order_status { margin-top: 1em;
width: 45px; th {
text-align: center; padding: .75em 1em;
mark {
@include ir();
background: none;
font-size: 1.4em;
margin: 0 auto;
} }
th.sortable a, th.sorted a {
mark.pending, padding: 0;
mark.completed, }
mark.on-hold, .check-column {
mark.failed, width: 1px;
mark.cancelled, white-space: nowrap;
mark.processing, padding: 1em 1em 1em 1em !important;
mark.refunded { vertical-align: middle;
&::after { input {
@include icon; vertical-align: text-top;
margin: 1px 0;
} }
} }
td.column-order_number {
line-height: 26px;
.order-preview {
float:right;
width: 16px;
padding: 20px 4px 4px 4px;
height: 0;
overflow: hidden;
position: relative;
border: 2px solid transparent;
border-radius: 4px;
mark.pending::after { &::before {
content: '\e012'; @include icon( '\e010' );
color: $orange; line-height: 16px;
font-size: 14px;
vertical-align:middle;
top: 4px;
}
&:hover {
border: 2px solid #00a0d2;
}
}
.order-preview.disabled {
&::before {
content: '';
background: url(../../../../../wp-includes/images/wpspin.gif) no-repeat center top;
}
}
} }
.column-order_date {
mark.completed::after { width: 10ch;
content: '\e015';
color: $blue;
} }
.column-order_number {
mark.on-hold::after { width: 35ch;
content: '\e033';
color: #999;
} }
.column-order_status {
mark.failed::after { width: 20ch;
content: '\e016';
color: #d0c21f;
} }
.column-order_total {
mark.cancelled::after { text-align: right;
content: '\e013'; width: 10ch;
color: $red; a span {
float:right;
}
} }
.column-shipping_address,
mark.processing::after { .column-billing_address {
content: '\e011'; width: 20ch;
color: #73a724;
} }
th:first-child,
td:first-child {
padding-left: 2em;
}
th:last-child,
td:last-child {
padding-right: 2em;
}
tbody {
th, td {
border-top: 1px solid #f5f5f5;
}
td {
vertical-align: middle;
padding: 1em;
mark.refunded::after { .post-row-actions {
content: '\e014'; display: none;
color: #999; }
.order-status {
display: inline-flex;
padding: 0px 1em;
line-height: 2.5em;
color: #777;
background: #E5E5E5;
border-radius: 4px;
border-bottom: 1px solid rgba(0,0,0,0.05);
margin: -.5em 0;
cursor: inherit !important;
&.status-completed {
background: #C8D7E1;
color: #2e4453;
}
&.status-on-hold {
background: #f8dda7;
color: #94660c;
}
&.status-failed {
background: #eba3a3;
color: #761919;
}
&.status-processing {
background: #C6E1C6;
color: #5B841B;
}
&.status-trash {
background: #eba3a3;
color: #761919;
}
}
}
tr:hover:not(.status-trash) {
td, th {
cursor: pointer;
}
}
} }
} }
}
td.column-order_status { // Hide some columns on smaller screens.
padding-top: 9px; @media only screen and (max-width: 1400px) {
.post-type-shop_order .wp-list-table {
.column-billing_address {
display:none;
visibility:hidden;
}
}
}
@media only screen and (max-width: 1200px) {
.post-type-shop_order .wp-list-table {
.column-shipping_address,
.column-order_total {
display:none;
visibility:hidden;
}
}
}
.wc-order-preview {
article {
padding: 0 !important;
}
.wc-order-preview__table {
width: 100%;
margin: 0;
border-bottom: 1px solid #ccc;
th, td {
padding: 1em 1.5em;
text-align: left;
border: 0;
border-bottom: 1px solid #eee;
margin: 0;
background: transparent;
box-shadow: none;
text-align: right;
vertical-align: top;
}
td:first-child,
th:first-child {
text-align: left;
}
th {
border-color: #ccc;
}
tr:last-child td {
border: 0;
}
.wc-order-item-sku {
margin-top: .5em;
}
.wc-order-item-meta {
margin-top: .5em;
th, td {
padding: 0;
border: 0;
text-align: left;
vertical-align: top;
}
td:last-child {
padding-left: .5em;
}
}
}
.wc-order-preview-addresses {
overflow:hidden;
.wc-order-preview-address {
width: 50%;
float: left;
padding: 1.5em;
box-sizing: border-box;
h2 {
margin-top: 0;
}
strong {
display: block;
margin-top: 1em;
}
}
} }
} }
@ -3139,6 +3293,10 @@ img.help_tip {
box-sizing: border-box; box-sizing: border-box;
} }
input[size] {
width: auto !important;
}
// Ignore nested inputs. // Ignore nested inputs.
table { table {
select, select,
@ -3265,6 +3423,105 @@ img.help_tip {
.wc_emails_wrapper { .wc_emails_wrapper {
padding: 0 15px 10px 0; 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 +4812,10 @@ img.ui-datepicker-trigger {
/** /**
* Reports * Reports
*/ */
.woocommerce-reports-remove-filter {
color: red;
text-decoration: none;
}
.woocommerce-reports-wrap, .woocommerce-reports-wrap,
.woocommerce-reports-wide { .woocommerce-reports-wide {
&.woocommerce-reports-wrap { &.woocommerce-reports-wrap {
@ -4568,6 +4829,10 @@ img.ui-datepicker-trigger {
zoom: 1; zoom: 1;
} }
.widefat th {
padding: 7px;
}
.widefat td { .widefat td {
vertical-align: top; vertical-align: top;
padding: 7px; padding: 7px;
@ -5307,20 +5572,6 @@ table.bar_chart {
.post-type-shop_order { .post-type-shop_order {
.wp-list-table { .wp-list-table {
.column-order_status {
display: none;
text-align: left;
padding-bottom: 0;
mark {
margin: 0;
}
&::before {
display: none !important;
}
}
.column-customer_message, .column-customer_message,
.column-order_notes { .column-order_notes {
text-align: inherit; text-align: inherit;
@ -5410,6 +5661,14 @@ table.bar_chart {
} }
} }
@media screen and (max-width: 782px) {
.wc-backbone-modal .wc-backbone-modal-content {
width: 100%;
height: 100%;
min-width: 100%;
}
}
.wc-backbone-modal-backdrop { .wc-backbone-modal-backdrop {
position: fixed; position: fixed;
top: 0; top: 0;
@ -5605,7 +5864,7 @@ table.bar_chart {
} }
select, select,
input { input {
line-height: 32px; line-height: 1;
height: 32px; height: 32px;
} }
.select2-container { .select2-container {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -602,6 +602,7 @@ body {
.wc-wizard-service-enable input { .wc-wizard-service-enable input {
visibility: hidden; visibility: hidden;
position: relative; position: relative;
cursor: pointer;
&:before { &:before {
content: "\f347"; // down chevron content: "\f347"; // down chevron

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 { div.summary {
float: right; float: right;
width: 48%; width: 48%;
clear: none;
} }
.woocommerce-tabs { .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 ) { $.fn.WCBackboneModal = function( options ) {
return this.each( function() { return this.each( function() {
var WCeachBackboneModal = new $.WCBackboneModal( $( this ), options ) ( new $.WCBackboneModal( $( this ), options ) );
( WCeachBackboneModal() );
}); });
}; };
@ -25,12 +24,10 @@
var settings = $.extend( {}, $.WCBackboneModal.defaultOptions, options ); var settings = $.extend( {}, $.WCBackboneModal.defaultOptions, options );
if ( settings.template ) { if ( settings.template ) {
new $.WCBackboneModal.View({
var BackboneModal = new $.WCBackboneModal.View({ target: settings.template,
target: settings.template, string: settings.variable
string: settings.variable });
});
BackboneModal();
} }
}; };

View File

@ -1 +1 @@
!function(e,t,n){"use strict";e.fn.WCBackboneModal=function(t){return this.each(function(){var n=new e.WCBackboneModal(e(this),t)(n())})},e.WCBackboneModal=function(t,n){var o=e.extend({},e.WCBackboneModal.defaultOptions,n);o.template&&new e.WCBackboneModal.View({target:o.template,string:o.variable})()},e.WCBackboneModal.defaultOptions={template:"",variable:{}},e.WCBackboneModal.View=t.View.extend({tagName:"div",id:"wc-backbone-modal-dialog",_target:undefined,_string:undefined,events:{"click .modal-close":"closeButton","click #btn-ok":"addButton","touchstart #btn-ok":"addButton",keydown:"keyboardActions"},resizeContent:function(){var t=e(".wc-backbone-modal-content").find("article"),n=.75*e(window).height();t.css({"max-height":n+"px"})},initialize:function(t){var o=this;this._target=t.target,this._string=t.string,n.bindAll(this,"render"),this.render(),e(window).resize(function(){o.resizeContent()})},render:function(){var t=wp.template(this._target);this.$el.append(t(this._string)),e(document.body).css({overflow:"hidden"}).append(this.$el),this.resizeContent(),this.$(".wc-backbone-modal-content").attr("tabindex","0").focus(),e(document.body).trigger("init_tooltips"),e(document.body).trigger("wc_backbone_modal_loaded",this._target)},closeButton:function(t){t.preventDefault(),e(document.body).trigger("wc_backbone_modal_before_remove",this._target),this.undelegateEvents(),e(document).off("focusin"),e(document.body).css({overflow:"auto"}),this.remove(),e(document.body).trigger("wc_backbone_modal_removed",this._target)},addButton:function(t){e(document.body).trigger("wc_backbone_modal_response",[this._target,this.getFormData()]),this.closeButton(t)},getFormData:function(){var t={};return e(document.body).trigger("wc_backbone_modal_before_update",this._target),e.each(e("form",this.$el).serializeArray(),function(n,o){-1!==o.name.indexOf("[]")?(o.name=o.name.replace("[]",""),t[o.name]=e.makeArray(t[o.name]),t[o.name].push(o.value)):t[o.name]=o.value}),t},keyboardActions:function(e){var t=e.keyCode||e.which;13!==t||e.target.tagName&&("input"===e.target.tagName.toLowerCase()||"textarea"===e.target.tagName.toLowerCase())||this.addButton(e),27===t&&this.closeButton(e)}})}(jQuery,Backbone,_); !function(e,t,n){"use strict";e.fn.WCBackboneModal=function(t){return this.each(function(){new e.WCBackboneModal(e(this),t)})},e.WCBackboneModal=function(t,n){var o=e.extend({},e.WCBackboneModal.defaultOptions,n);o.template&&new e.WCBackboneModal.View({target:o.template,string:o.variable})},e.WCBackboneModal.defaultOptions={template:"",variable:{}},e.WCBackboneModal.View=t.View.extend({tagName:"div",id:"wc-backbone-modal-dialog",_target:undefined,_string:undefined,events:{"click .modal-close":"closeButton","click #btn-ok":"addButton","touchstart #btn-ok":"addButton",keydown:"keyboardActions"},resizeContent:function(){var t=e(".wc-backbone-modal-content").find("article"),n=.75*e(window).height();t.css({"max-height":n+"px"})},initialize:function(t){var o=this;this._target=t.target,this._string=t.string,n.bindAll(this,"render"),this.render(),e(window).resize(function(){o.resizeContent()})},render:function(){var t=wp.template(this._target);this.$el.append(t(this._string)),e(document.body).css({overflow:"hidden"}).append(this.$el),this.resizeContent(),this.$(".wc-backbone-modal-content").attr("tabindex","0").focus(),e(document.body).trigger("init_tooltips"),e(document.body).trigger("wc_backbone_modal_loaded",this._target)},closeButton:function(t){t.preventDefault(),e(document.body).trigger("wc_backbone_modal_before_remove",this._target),this.undelegateEvents(),e(document).off("focusin"),e(document.body).css({overflow:"auto"}),this.remove(),e(document.body).trigger("wc_backbone_modal_removed",this._target)},addButton:function(t){e(document.body).trigger("wc_backbone_modal_response",[this._target,this.getFormData()]),this.closeButton(t)},getFormData:function(){var t={};return e(document.body).trigger("wc_backbone_modal_before_update",this._target),e.each(e("form",this.$el).serializeArray(),function(n,o){-1!==o.name.indexOf("[]")?(o.name=o.name.replace("[]",""),t[o.name]=e.makeArray(t[o.name]),t[o.name].push(o.value)):t[o.name]=o.value}),t},keyboardActions:function(e){var t=e.keyCode||e.which;13!==t||e.target.tagName&&("input"===e.target.tagName.toLowerCase()||"textarea"===e.target.tagName.toLowerCase())||this.addButton(e),27===t&&this.closeButton(e)}})}(jQuery,Backbone,_);

View File

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

File diff suppressed because one or more lines are too long

View File

@ -124,4 +124,43 @@
$( this ).closest( 'td' ).find( 'select' ).trigger( 'change' ); $( this ).closest( 'td' ).find( 'select' ).trigger( 'change' );
return false; 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 ); })( 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","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);

View File

@ -0,0 +1,78 @@
/* global wc_orders_params */
jQuery( function( $ ) {
if ( typeof wc_orders_params === 'undefined' ) {
return false;
}
/**
* WCOrdersTable class.
*/
var WCOrdersTable = function() {
$( document )
.on( 'click', '.post-type-shop_order .wp-list-table tbody td', this.onRowClick )
.on( 'click', '.order-preview:not(.disabled)', this.onPreview );
};
/**
* Click a row.
*/
WCOrdersTable.prototype.onRowClick = function( e ) {
if ( $( e.target ).filter( 'a' ).length ) {
return true;
}
var $row = $( this ).closest( 'tr' ),
href = $row.find( 'a.order-view' ).attr( 'href' );
if ( href.length ) {
window.location = href;
}
};
/**
* Preview an order.
*/
WCOrdersTable.prototype.onPreview = function() {
var $previewButton = $( this ),
$order_id = $previewButton.data( 'order-id' );
if ( $previewButton.data( 'order-data' ) ) {
$( this ).WCBackboneModal({
template: 'wc-modal-view-order',
variable : $previewButton.data( 'order-data' )
});
} else {
$previewButton.addClass( 'disabled' );
$.ajax({
url: wc_orders_params.ajax_url,
data: {
order_id: $order_id,
action : 'woocommerce_get_order_details',
security: wc_orders_params.preview_nonce
},
type: 'GET',
success: function( response ) {
$( '.order-preview' ).removeClass( 'disabled' );
if ( response.success ) {
$previewButton.data( 'order-data', response.data );
$( this ).WCBackboneModal({
template: 'wc-modal-view-order',
variable : response.data
});
}
}
});
}
return false;
};
/**
* Init WCOrdersTable.
*/
new WCOrdersTable();
} );

1
assets/js/admin/wc-orders.min.js vendored Normal file
View File

@ -0,0 +1 @@
jQuery(function(e){if("undefined"==typeof wc_orders_params)return!1;var r=function(){e(document).on("click",".post-type-shop_order .wp-list-table tbody td",this.onRowClick).on("click",".order-preview:not(.disabled)",this.onPreview)};r.prototype.onRowClick=function(r){if(e(r.target).filter("a").length)return!0;var a=e(this).closest("tr").find("a.order-view").attr("href");a.length&&(window.location=a)},r.prototype.onPreview=function(){var r=e(this),a=r.data("order-id");return r.data("order-data")?e(this).WCBackboneModal({template:"wc-modal-view-order",variable:r.data("order-data")}):(r.addClass("disabled"),e.ajax({url:wc_orders_params.ajax_url,data:{order_id:a,action:"woocommerce_get_order_details",security:wc_orders_params.preview_nonce},type:"GET",success:function(a){e(".order-preview").removeClass("disabled"),a.success&&(r.data("order-data",a.data),e(this).WCBackboneModal({template:"wc-modal-view-order",variable:a.data}))}})),!1},new r});

View File

@ -36,17 +36,23 @@ jQuery( function( $ ) {
} ); } );
$( '.wc-wizard-services' ).on( 'click', '.wc-wizard-service-enable', function( e ) { $( '.wc-wizard-services' ).on( 'click', '.wc-wizard-service-enable', function( e ) {
e.stopPropagation(); var eventTarget = $( e.target );
if ( eventTarget.is( 'input' ) ) {
e.stopPropagation();
return;
}
var $checkbox = $( this ).find( 'input[type="checkbox"]' );
var $checkbox = $( this ).find( '.wc-wizard-service-toggle input' );
$checkbox.prop( 'checked', ! $checkbox.prop( 'checked' ) ).change(); $checkbox.prop( 'checked', ! $checkbox.prop( 'checked' ) ).change();
} ); } );
$( '.wc-wizard-services-list-toggle' ).on( 'change', '.wc-wizard-service-enable input', function() { $( '.wc-wizard-services-list-toggle' ).on( 'change', '.wc-wizard-service-enable input', function() {
$( this ).closest( '.wc-wizard-services-list-toggle' ).toggleClass( 'closed' ); $( this ).closest( '.wc-wizard-services-list-toggle' ).toggleClass( 'closed' );
$( this ).closest( '.wc-wizard-services' ).find( '.wc-wizard-service-item' ) $( this ).closest( '.wc-wizard-services' ).find( '.wc-wizard-service-item' )
.slideToggle() .slideToggle()
.css( 'display', 'flex' ); .css( 'display', 'flex' );
} ); } );
$( '.wc-wizard-services' ).on( 'change', '.wc-wizard-shipping-method-select .method', function( e ) { $( '.wc-wizard-services' ).on( 'change', '.wc-wizard-shipping-method-select .method', function( e ) {

View File

@ -1 +1 @@
jQuery(function(e){function i(){e(".wc-setup-content").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})}function s(){e("form.activate-jetpack").submit()}function t(){wp.ajax.post("setup_wizard_check_jetpack").then(function(e){if(!e||!e.is_active||"yes"===e.is_active)return s();setTimeout(t,3e3)}).fail(function(){s()})}e(".button-next").on("click",function(){var s=e(this).parents("form").get(0);return("function"!=typeof s.checkValidity||s.checkValidity())&&i(),!0}),e(".wc-wizard-services").on("change",".wc-wizard-service-enable input",function(){e(this).is(":checked")?(e(this).closest(".wc-wizard-service-toggle").removeClass("disabled"),e(this).closest(".wc-wizard-service-item").addClass("checked"),e(this).closest(".wc-wizard-service-item").find(".wc-wizard-service-settings").removeClass("hide")):(e(this).closest(".wc-wizard-service-toggle").addClass("disabled"),e(this).closest(".wc-wizard-service-item").removeClass("checked"),e(this).closest(".wc-wizard-service-item").find(".wc-wizard-service-settings").addClass("hide"))}),e(".wc-wizard-services").on("click",".wc-wizard-service-enable",function(i){i.stopPropagation();var s=e(this).find(".wc-wizard-service-toggle input");s.prop("checked",!s.prop("checked")).change()}),e(".wc-wizard-services-list-toggle").on("change",".wc-wizard-service-enable input",function(){e(this).closest(".wc-wizard-services-list-toggle").toggleClass("closed"),e(this).closest(".wc-wizard-services").find(".wc-wizard-service-item").slideToggle().css("display","flex")}),e(".wc-wizard-services").on("change",".wc-wizard-shipping-method-select .method",function(i){var s=e(this).closest(".wc-wizard-service-description"),t=i.target.value,c=s.find(".shipping-method-descriptions");c.find(".shipping-method-description").addClass("hide"),c.find("."+t).removeClass("hide");var r=s.find(".shipping-method-settings");r.find(".shipping-method-setting").addClass("hide").find(".shipping-method-required-field").prop("required",!1),r.find("."+t).removeClass("hide").find(".shipping-method-required-field").prop("required",!0)}),e(".wc-wizard-services").on("change",".wc-wizard-shipping-method-enable",function(){var i=e(this).is(":checked");e(this).closest(".wc-wizard-service-item").find(".shipping-method-required-field").prop("required",i)}),e(".activate-jetpack").on("click",".button-primary",function(e){if(i(),"no"===wc_setup_params.pending_jetpack_install)return!0;e.preventDefault(),t()}),e(".wc-wizard-services").on("change","input#stripe_create_account",function(){e(this).is(":checked")?(e(this).closest(".wc-wizard-service-settings").find("input.payment-email-input").prop("required",!0),e(this).closest(".wc-wizard-service-settings").find(".wc-wizard-service-setting-stripe_email").show()):(e(this).closest(".wc-wizard-service-settings").find("input.payment-email-input").prop("required",!1),e(this).closest(".wc-wizard-service-settings").find(".wc-wizard-service-setting-stripe_email").hide())}),e(".wc-wizard-services input#stripe_create_account").change(),e("select#store_country_state").on("change",function(){var i=this.value.split(":")[0];e("select#currency_code").val(wc_setup_currencies[i]).change()})}); jQuery(function(e){function i(){e(".wc-setup-content").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})}function s(){e("form.activate-jetpack").submit()}function t(){wp.ajax.post("setup_wizard_check_jetpack").then(function(e){if(!e||!e.is_active||"yes"===e.is_active)return s();setTimeout(t,3e3)}).fail(function(){s()})}e(".button-next").on("click",function(){var s=e(this).parents("form").get(0);return("function"!=typeof s.checkValidity||s.checkValidity())&&i(),!0}),e(".wc-wizard-services").on("change",".wc-wizard-service-enable input",function(){e(this).is(":checked")?(e(this).closest(".wc-wizard-service-toggle").removeClass("disabled"),e(this).closest(".wc-wizard-service-item").addClass("checked"),e(this).closest(".wc-wizard-service-item").find(".wc-wizard-service-settings").removeClass("hide")):(e(this).closest(".wc-wizard-service-toggle").addClass("disabled"),e(this).closest(".wc-wizard-service-item").removeClass("checked"),e(this).closest(".wc-wizard-service-item").find(".wc-wizard-service-settings").addClass("hide"))}),e(".wc-wizard-services").on("click",".wc-wizard-service-enable",function(i){if(e(i.target).is("input"))i.stopPropagation();else{var s=e(this).find('input[type="checkbox"]');s.prop("checked",!s.prop("checked")).change()}}),e(".wc-wizard-services-list-toggle").on("change",".wc-wizard-service-enable input",function(){e(this).closest(".wc-wizard-services-list-toggle").toggleClass("closed"),e(this).closest(".wc-wizard-services").find(".wc-wizard-service-item").slideToggle().css("display","flex")}),e(".wc-wizard-services").on("change",".wc-wizard-shipping-method-select .method",function(i){var s=e(this).closest(".wc-wizard-service-description"),t=i.target.value,c=s.find(".shipping-method-descriptions");c.find(".shipping-method-description").addClass("hide"),c.find("."+t).removeClass("hide");var r=s.find(".shipping-method-settings");r.find(".shipping-method-setting").addClass("hide").find(".shipping-method-required-field").prop("required",!1),r.find("."+t).removeClass("hide").find(".shipping-method-required-field").prop("required",!0)}),e(".wc-wizard-services").on("change",".wc-wizard-shipping-method-enable",function(){var i=e(this).is(":checked");e(this).closest(".wc-wizard-service-item").find(".shipping-method-required-field").prop("required",i)}),e(".activate-jetpack").on("click",".button-primary",function(e){if(i(),"no"===wc_setup_params.pending_jetpack_install)return!0;e.preventDefault(),t()}),e(".wc-wizard-services").on("change","input#stripe_create_account",function(){e(this).is(":checked")?(e(this).closest(".wc-wizard-service-settings").find("input.payment-email-input").prop("required",!0),e(this).closest(".wc-wizard-service-settings").find(".wc-wizard-service-setting-stripe_email").show()):(e(this).closest(".wc-wizard-service-settings").find("input.payment-email-input").prop("required",!1),e(this).closest(".wc-wizard-service-settings").find(".wc-wizard-service-setting-stripe_email").hide())}),e(".wc-wizard-services input#stripe_create_account").change(),e("select#store_country_state").on("change",function(){var i=this.value.split(":")[0];e("select#currency_code").val(wc_setup_currencies[i]).change()})});

File diff suppressed because one or more lines are too long

View File

@ -184,13 +184,11 @@ jQuery( function( $ ) {
* *
* @param {Object} evt The JQuery event. * @param {Object} evt The JQuery event.
*/ */
shipping_method_selected: function( evt ) { shipping_method_selected: function() {
var target = evt.currentTarget;
var shipping_methods = {}; var shipping_methods = {};
$( 'select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]' ).each( function() { $( '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' ) ); block( $( 'div.cart_totals' ) );

File diff suppressed because one or more lines are too long

View File

@ -391,11 +391,7 @@ jQuery( function( $ ) {
// Lose focus for all fields // Lose focus for all fields
$form.find( '.input-text, select, input:checkbox' ).trigger( 'validate' ).blur(); $form.find( '.input-text, select, input:checkbox' ).trigger( 'validate' ).blur();
// Scroll to top wc_checkout_form.scroll_to_notices();
$( 'html, body' ).animate( {
scrollTop: ( $( 'form.checkout' ).offset().top - 100 )
}, 1000 );
} }
// Re-init methods // 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.prepend( '<div class="woocommerce-NoticeGroup woocommerce-NoticeGroup-checkout">' + error_message + '</div>' );
wc_checkout_form.$checkout_form.removeClass( 'processing' ).unblock(); wc_checkout_form.$checkout_form.removeClass( 'processing' ).unblock();
wc_checkout_form.$checkout_form.find( '.input-text, select, input:checkbox' ).trigger( 'validate' ).blur(); wc_checkout_form.$checkout_form.find( '.input-text, select, input:checkbox' ).trigger( 'validate' ).blur();
$( 'html, body' ).animate({ wc_checkout_form.scroll_to_notices();
scrollTop: ( $( 'form.checkout' ).offset().top - 100 )
}, 1000 );
$( document.body ).trigger( 'checkout_error' ); $( 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

@ -1,5 +1,5 @@
jQuery( function( $ ) { jQuery( function( $ ) {
$( '.lost_reset_password' ).on( 'submit', function () { $( '.lost_reset_password' ).on( 'submit', function () {
$( 'input[type="submit"]', this ).attr( 'disabled', 'disabled' ); $( 'button[type="submit"]', this ).attr( 'disabled', 'disabled' );
}); });
}); });

View File

@ -1 +1 @@
jQuery(function(t){t(".lost_reset_password").on("submit",function(){t('input[type="submit"]',this).attr("disabled","disabled")})}); jQuery(function(t){t(".lost_reset_password").on("submit",function(){t('button[type="submit"]',this).attr("disabled","disabled")})});

View File

@ -20,7 +20,7 @@
*/ */
strengthMeter: function() { strengthMeter: function() {
var wrapper = $( 'form.register, form.checkout, form.edit-account, form.lost_reset_password' ), var wrapper = $( 'form.register, form.checkout, form.edit-account, form.lost_reset_password' ),
submit = $( 'input[type="submit"]', wrapper ), submit = $( 'button[type="submit"]', wrapper ),
field = $( '#reg_password, #account_password, #password_1', wrapper ), field = $( '#reg_password, #account_password, #password_1', wrapper ),
strength = 1, strength = 1,
fieldValue = field.val(); fieldValue = field.val();

View File

@ -1 +1 @@
!function(s){"use strict";var r={init:function(){s(document.body).on("keyup change","form.register #reg_password, form.checkout #account_password, form.edit-account #password_1, form.lost_reset_password #password_1",this.strengthMeter),s("form.checkout #createaccount").change()},strengthMeter:function(){var e=s("form.register, form.checkout, form.edit-account, form.lost_reset_password"),t=s('input[type="submit"]',e),a=s("#reg_password, #account_password, #password_1",e),o=1,d=a.val();r.includeMeter(e,a),o=r.checkPasswordStrength(e,a),d.length>0&&o<wc_password_strength_meter_params.min_password_strength&&!e.is("form.checkout")?t.attr("disabled","disabled").addClass("disabled"):t.removeAttr("disabled","disabled").removeClass("disabled")},includeMeter:function(r,e){var t=r.find(".woocommerce-password-strength");""===e.val()?(t.remove(),s(document.body).trigger("wc-password-strength-removed")):0===t.length&&(e.after('<div class="woocommerce-password-strength" aria-live="polite"></div>'),s(document.body).trigger("wc-password-strength-added"))},checkPasswordStrength:function(s,r){var e=s.find(".woocommerce-password-strength"),t=s.find(".woocommerce-password-hint"),a='<small class="woocommerce-password-hint">'+wc_password_strength_meter_params.i18n_password_hint+"</small>",o=wp.passwordStrength.meter(r.val(),wp.passwordStrength.userInputBlacklist()),d="";switch(e.removeClass("short bad good strong"),t.remove(),o<wc_password_strength_meter_params.min_password_strength&&(d=" - "+wc_password_strength_meter_params.i18n_password_error),o){case 0:e.addClass("short").html(pwsL10n["short"]+d),e.after(a);break;case 1:case 2:e.addClass("bad").html(pwsL10n.bad+d),e.after(a);break;case 3:e.addClass("good").html(pwsL10n.good+d);break;case 4:e.addClass("strong").html(pwsL10n.strong+d);break;case 5:e.addClass("short").html(pwsL10n.mismatch)}return o}};r.init()}(jQuery); !function(s){"use strict";var r={init:function(){s(document.body).on("keyup change","form.register #reg_password, form.checkout #account_password, form.edit-account #password_1, form.lost_reset_password #password_1",this.strengthMeter),s("form.checkout #createaccount").change()},strengthMeter:function(){var e=s("form.register, form.checkout, form.edit-account, form.lost_reset_password"),t=s('button[type="submit"]',e),o=s("#reg_password, #account_password, #password_1",e),a=1,d=o.val();r.includeMeter(e,o),a=r.checkPasswordStrength(e,o),d.length>0&&a<wc_password_strength_meter_params.min_password_strength&&!e.is("form.checkout")?t.attr("disabled","disabled").addClass("disabled"):t.removeAttr("disabled","disabled").removeClass("disabled")},includeMeter:function(r,e){var t=r.find(".woocommerce-password-strength");""===e.val()?(t.remove(),s(document.body).trigger("wc-password-strength-removed")):0===t.length&&(e.after('<div class="woocommerce-password-strength" aria-live="polite"></div>'),s(document.body).trigger("wc-password-strength-added"))},checkPasswordStrength:function(s,r){var e=s.find(".woocommerce-password-strength"),t=s.find(".woocommerce-password-hint"),o='<small class="woocommerce-password-hint">'+wc_password_strength_meter_params.i18n_password_hint+"</small>",a=wp.passwordStrength.meter(r.val(),wp.passwordStrength.userInputBlacklist()),d="";switch(e.removeClass("short bad good strong"),t.remove(),a<wc_password_strength_meter_params.min_password_strength&&(d=" - "+wc_password_strength_meter_params.i18n_password_error),a){case 0:e.addClass("short").html(pwsL10n["short"]+d),e.after(o);break;case 1:case 2:e.addClass("bad").html(pwsL10n.bad+d),e.after(o);break;case 3:e.addClass("good").html(pwsL10n.good+d);break;case 4:e.addClass("strong").html(pwsL10n.strong+d);break;case 5:e.addClass("short").html(pwsL10n.mismatch)}return a}};r.init()}(jQuery);

View File

@ -11,7 +11,9 @@
"squizlabs/php_codesniffer": "*", "squizlabs/php_codesniffer": "*",
"wp-coding-standards/wpcs": "0.13.1", "wp-coding-standards/wpcs": "0.13.1",
"phpunit/phpunit": "6.2.3", "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": { "scripts": {
"pre-update-cmd": [ "pre-update-cmd": [
@ -21,11 +23,9 @@
"WooCommerce\\GitHooks\\Hooks::preHooks" "WooCommerce\\GitHooks\\Hooks::preHooks"
], ],
"post-install-cmd": [ "post-install-cmd": [
"\"vendor/bin/phpcs\" --config-set installed_paths vendor/wp-coding-standards/wpcs",
"WooCommerce\\GitHooks\\Hooks::postHooks" "WooCommerce\\GitHooks\\Hooks::postHooks"
], ],
"post-update-cmd": [ "post-update-cmd": [
"\"vendor/bin/phpcs\" --config-set installed_paths vendor/wp-coding-standards/wpcs",
"WooCommerce\\GitHooks\\Hooks::postHooks" "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", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "5268174ad56d2293f14e24b931afeb63", "content-hash": "9a9c7e81cc3a30935c03b1b2d64c201c",
"packages": [ "packages": [
{ {
"name": "composer/installers", "name": "composer/installers",
@ -125,6 +125,74 @@
} }
], ],
"packages-dev": [ "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", "name": "doctrine/instantiator",
"version": "1.1.0", "version": "1.1.0",
@ -181,37 +249,40 @@
}, },
{ {
"name": "myclabs/deep-copy", "name": "myclabs/deep-copy",
"version": "1.6.1", "version": "1.7.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/myclabs/DeepCopy.git", "url": "https://github.com/myclabs/DeepCopy.git",
"reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102" "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/8e6e04167378abf1ddb4d3522d8755c5fd90d102", "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
"reference": "8e6e04167378abf1ddb4d3522d8755c5fd90d102", "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.4.0" "php": "^5.6 || ^7.0"
}, },
"require-dev": { "require-dev": {
"doctrine/collections": "1.*", "doctrine/collections": "^1.0",
"phpunit/phpunit": "~4.1" "doctrine/common": "^2.6",
"phpunit/phpunit": "^4.1"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"DeepCopy\\": "src/DeepCopy/" "DeepCopy\\": "src/DeepCopy/"
} },
"files": [
"src/DeepCopy/deep_copy.php"
]
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
], ],
"description": "Create deep copies (clones) of your objects", "description": "Create deep copies (clones) of your objects",
"homepage": "https://github.com/myclabs/DeepCopy",
"keywords": [ "keywords": [
"clone", "clone",
"copy", "copy",
@ -219,7 +290,7 @@
"object", "object",
"object graph" "object graph"
], ],
"time": "2017-04-12T18:52:22+00:00" "time": "2017-10-19T19:58:43+00:00"
}, },
{ {
"name": "phar-io/manifest", "name": "phar-io/manifest",
@ -534,16 +605,16 @@
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
"version": "5.2.2", "version": "5.2.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "8ed1902a57849e117b5651fc1a5c48110946c06b" "reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/8ed1902a57849e117b5651fc1a5c48110946c06b", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d",
"reference": "8ed1902a57849e117b5651fc1a5c48110946c06b", "reference": "8e1d2397d8adf59a3f12b2878a3aaa66d1ab189d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -552,7 +623,7 @@
"php": "^7.0", "php": "^7.0",
"phpunit/php-file-iterator": "^1.4.2", "phpunit/php-file-iterator": "^1.4.2",
"phpunit/php-text-template": "^1.2.1", "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/code-unit-reverse-lookup": "^1.0.1",
"sebastian/environment": "^3.0", "sebastian/environment": "^3.0",
"sebastian/version": "^2.0.1", "sebastian/version": "^2.0.1",
@ -594,7 +665,7 @@
"testing", "testing",
"xunit" "xunit"
], ],
"time": "2017-08-03T12:40:43+00:00" "time": "2017-11-03T13:47:33+00:00"
}, },
{ {
"name": "phpunit/php-file-iterator", "name": "phpunit/php-file-iterator",
@ -972,30 +1043,30 @@
}, },
{ {
"name": "sebastian/comparator", "name": "sebastian/comparator",
"version": "2.0.2", "version": "2.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git", "url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "ae068fede81d06e7bb9bb46a367210a3d3e1fe6a" "reference": "1174d9018191e93cb9d719edec01257fc05f8158"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/ae068fede81d06e7bb9bb46a367210a3d3e1fe6a", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1174d9018191e93cb9d719edec01257fc05f8158",
"reference": "ae068fede81d06e7bb9bb46a367210a3d3e1fe6a", "reference": "1174d9018191e93cb9d719edec01257fc05f8158",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.0", "php": "^7.0",
"sebastian/diff": "^2.0", "sebastian/diff": "^2.0",
"sebastian/exporter": "^3.0" "sebastian/exporter": "^3.1"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^6.0" "phpunit/phpunit": "^6.4"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.0.x-dev" "dev-master": "2.1.x-dev"
} }
}, },
"autoload": { "autoload": {
@ -1026,13 +1097,13 @@
} }
], ],
"description": "Provides the functionality to compare PHP values for equality", "description": "Provides the functionality to compare PHP values for equality",
"homepage": "http://www.github.com/sebastianbergmann/comparator", "homepage": "https://github.com/sebastianbergmann/comparator",
"keywords": [ "keywords": [
"comparator", "comparator",
"compare", "compare",
"equality" "equality"
], ],
"time": "2017-08-03T07:14:59+00:00" "time": "2017-11-03T07:16:52+00:00"
}, },
{ {
"name": "sebastian/diff", "name": "sebastian/diff",
@ -1626,17 +1697,69 @@
"time": "2016-11-23T20:04:58+00:00" "time": "2016-11-23T20:04:58+00:00"
}, },
{ {
"name": "woocommerce/woocommerce-git-hooks", "name": "wimg/php-compatibility",
"version": "1.0.2", "version": "8.0.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/woocommerce/woocommerce-git-hooks.git", "url": "https://github.com/wimg/PHPCompatibility.git",
"reference": "f0eea8aa392c822f0f3b9cd0b31f92bfa4de6a0c" "reference": "4c4385fb891dff0501009670f988d4fe36785249"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-git-hooks/zipball/f0eea8aa392c822f0f3b9cd0b31f92bfa4de6a0c", "url": "https://api.github.com/repos/wimg/PHPCompatibility/zipball/4c4385fb891dff0501009670f988d4fe36785249",
"reference": "f0eea8aa392c822f0f3b9cd0b31f92bfa4de6a0c", "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": "" "shasum": ""
}, },
"type": "scripts", "type": "scripts",
@ -1656,7 +1779,7 @@
} }
], ],
"description": "WooCommerce Git Hooks", "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", "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 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
,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 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,,,,
,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,,,,,,,,,,,, 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-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-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-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-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-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-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-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-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-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,,,,,,,,,,,, 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,,,,,,,,
,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-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-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-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-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-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-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 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,,,,,,,,
,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,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,,,,,,,,,, "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,,,,,,,,,, "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,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-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,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-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,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-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,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-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,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-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,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 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. * Remove item from the order.
* *
* @param int $item_id * @param int $item_id Item ID to delete.
* @return false|void * @return false|void
*/ */
public function remove_item( $item_id ) { 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 ) ) ) { if ( ! $item || ! ( $items_key = $this->get_items_key( $item ) ) ) {
return false; return false;
} }
// Unset and remove later // Unset and remove later.
$this->items_to_delete[] = $item; $this->items_to_delete[] = $item;
unset( $this->items[ $items_key ][ $item->get_id() ] ); unset( $this->items[ $items_key ][ $item->get_id() ] );
} }
@ -1672,7 +1672,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
} }
} }
/* translators: %s: shipping method */ /* translators: %s: method */
$shipping .= apply_filters( 'woocommerce_order_shipping_to_display_shipped_via', '&nbsp;<small class="shipped_via">' . sprintf( __( 'via %s', 'woocommerce' ), $this->get_shipping_method() ) . '</small>', $this ); $shipping .= apply_filters( 'woocommerce_order_shipping_to_display_shipped_via', '&nbsp;<small class="shipped_via">' . sprintf( __( 'via %s', 'woocommerce' ), $this->get_shipping_method() ) . '</small>', $this );
} elseif ( $this->get_shipping_method() ) { } elseif ( $this->get_shipping_method() ) {

View File

@ -1172,13 +1172,15 @@ class WC_Product extends WC_Abstract_Legacy_Product {
$download_object = $download; $download_object = $download;
} else { } else {
$download_object = new WC_Product_Download(); $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_name( $download['name'] );
$download_object->set_file( $download['file'] ); $download_object->set_file( $download['file'] );
$download_object->set_previous_hash( $download['previous_hash'] );
} }
// Validate the file extension. // Validate the file extension.
@ -1763,12 +1765,12 @@ class WC_Product extends WC_Abstract_Legacy_Product {
/** /**
* Returns the main product image. * Returns the main product image.
* *
* @param string $size (default: 'shop_thumbnail'). * @param string $size (default: 'woocommerce_thumbnail').
* @param array $attr Image attributes. * @param array $attr Image attributes.
* @param bool $placeholder True to return $placeholder if no image is found, or false to return an empty string. * @param bool $placeholder True to return $placeholder if no image is found, or false to return an empty string.
* @return 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() ) ) { if ( has_post_thumbnail( $this->get_id() ) ) {
$image = get_the_post_thumbnail( $this->get_id(), $size, $attr ); $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 ) ) { } elseif ( ( $parent_id = wp_get_post_parent_id( $this->get_id() ) ) && has_post_thumbnail( $parent_id ) ) {

View File

@ -93,7 +93,6 @@ class WC_Admin_Assets {
wp_register_script( 'woocommerce_admin', WC()->plugin_url() . '/assets/js/admin/woocommerce_admin' . $suffix . '.js', array( 'jquery', 'jquery-blockui', 'jquery-ui-sortable', 'jquery-ui-widget', 'jquery-ui-core', 'jquery-tiptip' ), WC_VERSION ); wp_register_script( 'woocommerce_admin', WC()->plugin_url() . '/assets/js/admin/woocommerce_admin' . $suffix . '.js', array( 'jquery', 'jquery-blockui', 'jquery-ui-sortable', 'jquery-ui-widget', 'jquery-ui-core', 'jquery-tiptip' ), WC_VERSION );
wp_register_script( 'jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.70', true ); wp_register_script( 'jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.70', true );
wp_register_script( 'jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip' . $suffix . '.js', array( 'jquery' ), WC_VERSION, true ); wp_register_script( 'jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip' . $suffix . '.js', array( 'jquery' ), WC_VERSION, true );
wp_register_script( 'accounting', WC()->plugin_url() . '/assets/js/accounting/accounting' . $suffix . '.js', array( 'jquery' ), '0.4.2' );
wp_register_script( 'round', WC()->plugin_url() . '/assets/js/round/round' . $suffix . '.js', array( 'jquery' ), WC_VERSION ); wp_register_script( 'round', WC()->plugin_url() . '/assets/js/round/round' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
wp_register_script( 'wc-admin-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes' . $suffix . '.js', array( 'jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'accounting', 'round', 'wc-enhanced-select', 'plupload-all', 'stupidtable', 'jquery-tiptip' ), WC_VERSION ); wp_register_script( 'wc-admin-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes' . $suffix . '.js', array( 'jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'accounting', 'round', 'wc-enhanced-select', 'plupload-all', 'stupidtable', 'jquery-tiptip' ), WC_VERSION );
wp_register_script( 'zeroclipboard', WC()->plugin_url() . '/assets/js/zeroclipboard/jquery.zeroclipboard' . $suffix . '.js', array( 'jquery' ), WC_VERSION ); wp_register_script( 'zeroclipboard', WC()->plugin_url() . '/assets/js/zeroclipboard/jquery.zeroclipboard' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
@ -131,12 +130,18 @@ class WC_Admin_Assets {
'search_categories_nonce' => wp_create_nonce( 'search-categories' ), 'search_categories_nonce' => wp_create_nonce( 'search-categories' ),
) ); ) );
// Accounting wp_register_script( 'accounting', WC()->plugin_url() . '/assets/js/accounting/accounting' . $suffix . '.js', array( 'jquery' ), '0.4.2' );
wp_localize_script( 'accounting', 'accounting_params', array( wp_localize_script( 'accounting', 'accounting_params', array(
'mon_decimal_point' => wc_get_price_decimal_separator(), 'mon_decimal_point' => wc_get_price_decimal_separator(),
) ); ) );
// WooCommerce admin pages wp_register_script( 'wc-orders', WC()->plugin_url() . '/assets/js/admin/wc-orders' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-blockui' ), WC_VERSION );
wp_localize_script( 'wc-orders', 'wc_orders_params', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'preview_nonce' => wp_create_nonce( 'woocommerce-preview-order' ),
) );
// WooCommerce admin pages.
if ( in_array( $screen_id, wc_get_screen_ids() ) ) { if ( in_array( $screen_id, wc_get_screen_ids() ) ) {
wp_enqueue_script( 'iris' ); wp_enqueue_script( 'iris' );
wp_enqueue_script( 'woocommerce_admin' ); wp_enqueue_script( 'woocommerce_admin' );

View File

@ -29,7 +29,7 @@ class WC_Admin_Attributes {
$result = ''; $result = '';
$action = ''; $action = '';
// Action to perform: add, edit, delete or none // Action to perform: add, edit, delete or none.
if ( ! empty( $_POST['add_new_attribute'] ) ) { if ( ! empty( $_POST['add_new_attribute'] ) ) {
$action = 'add'; $action = 'add';
} elseif ( ! empty( $_POST['save_attribute'] ) && ! empty( $_GET['edit'] ) ) { } elseif ( ! empty( $_POST['save_attribute'] ) && ! empty( $_GET['edit'] ) ) {
@ -54,7 +54,7 @@ class WC_Admin_Attributes {
echo '<div id="woocommerce_errors" class="error"><p>' . wp_kses_post( $result->get_error_message() ) . '</p></div>'; echo '<div id="woocommerce_errors" class="error"><p>' . wp_kses_post( $result->get_error_message() ) . '</p></div>';
} }
// Show admin interface // Show admin interface.
if ( ! empty( $_GET['edit'] ) ) { if ( ! empty( $_GET['edit'] ) ) {
self::edit_attribute(); self::edit_attribute();
} else { } else {
@ -64,6 +64,7 @@ class WC_Admin_Attributes {
/** /**
* Get and sanitize posted attribute data. * Get and sanitize posted attribute data.
*
* @return array * @return array
*/ */
private static function get_posted_attribute() { private static function get_posted_attribute() {
@ -169,55 +170,52 @@ class WC_Admin_Attributes {
?> ?>
<div class="wrap woocommerce"> <div class="wrap woocommerce">
<h1><?php _e( 'Edit attribute', 'woocommerce' ) ?></h1> <h1><?php esc_html_e( 'Edit attribute', 'woocommerce' ) ?></h1>
<?php <?php
if ( ! $attribute_to_edit ) {
if ( ! $attribute_to_edit ) { echo '<div id="woocommerce_errors" class="error"><p>' . esc_html__( 'Error: non-existing attribute ID.', 'woocommerce' ) . '</p></div>';
echo '<div id="woocommerce_errors" class="error"><p>' . __( 'Error: non-existing attribute ID.', 'woocommerce' ) . '</p></div>'; } else {
} else { $att_type = $attribute_to_edit->attribute_type;
$att_type = $attribute_to_edit->attribute_type; $att_label = $attribute_to_edit->attribute_label;
$att_label = $attribute_to_edit->attribute_label; $att_name = $attribute_to_edit->attribute_name;
$att_name = $attribute_to_edit->attribute_name; $att_orderby = $attribute_to_edit->attribute_orderby;
$att_orderby = $attribute_to_edit->attribute_orderby; $att_public = $attribute_to_edit->attribute_public;
$att_public = $attribute_to_edit->attribute_public; ?>
?>
<form action="edit.php?post_type=product&amp;page=product_attributes&amp;edit=<?php echo absint( $edit ); ?>" method="post"> <form action="edit.php?post_type=product&amp;page=product_attributes&amp;edit=<?php echo absint( $edit ); ?>" method="post">
<table class="form-table"> <table class="form-table">
<tbody> <tbody>
<?php do_action( 'woocommerce_before_edit_attribute_fields' ); ?> <?php do_action( 'woocommerce_before_edit_attribute_fields' ); ?>
<tr class="form-field form-required"> <tr class="form-field form-required">
<th scope="row" valign="top"> <th scope="row" valign="top">
<label for="attribute_label"><?php _e( 'Name', 'woocommerce' ); ?></label> <label for="attribute_label"><?php esc_html_e( 'Name', 'woocommerce' ); ?></label>
</th> </th>
<td> <td>
<input name="attribute_label" id="attribute_label" type="text" value="<?php echo esc_attr( $att_label ); ?>" /> <input name="attribute_label" id="attribute_label" type="text" value="<?php echo esc_attr( $att_label ); ?>" />
<p class="description"><?php _e( 'Name for the attribute (shown on the front-end).', 'woocommerce' ); ?></p> <p class="description"><?php esc_html_e( 'Name for the attribute (shown on the front-end).', 'woocommerce' ); ?></p>
</td> </td>
</tr> </tr>
<tr class="form-field form-required"> <tr class="form-field form-required">
<th scope="row" valign="top"> <th scope="row" valign="top">
<label for="attribute_name"><?php _e( 'Slug', 'woocommerce' ); ?></label> <label for="attribute_name"><?php esc_html_e( 'Slug', 'woocommerce' ); ?></label>
</th> </th>
<td> <td>
<input name="attribute_name" id="attribute_name" type="text" value="<?php echo esc_attr( $att_name ); ?>" maxlength="28" /> <input name="attribute_name" id="attribute_name" type="text" value="<?php echo esc_attr( $att_name ); ?>" maxlength="28" />
<p class="description"><?php _e( 'Unique slug/reference for the attribute; must be no more than 28 characters.', 'woocommerce' ); ?></p> <p class="description"><?php esc_html_e( 'Unique slug/reference for the attribute; must be no more than 28 characters.', 'woocommerce' ); ?></p>
</td> </td>
</tr> </tr>
<tr class="form-field form-required"> <tr class="form-field form-required">
<th scope="row" valign="top"> <th scope="row" valign="top">
<label for="attribute_public"><?php _e( 'Enable archives?', 'woocommerce' ); ?></label> <label for="attribute_public"><?php esc_html_e( 'Enable archives?', 'woocommerce' ); ?></label>
</th> </th>
<td> <td>
<input name="attribute_public" id="attribute_public" type="checkbox" value="1" <?php checked( $att_public, 1 ); ?> /> <input name="attribute_public" id="attribute_public" type="checkbox" value="1" <?php checked( $att_public, 1 ); ?> />
<p class="description"><?php _e( 'Enable this if you want this attribute to have product archives in your store.', 'woocommerce' ); ?></p> <p class="description"><?php esc_html_e( 'Enable this if you want this attribute to have product archives in your store.', 'woocommerce' ); ?></p>
</td> </td>
</tr> </tr>
<tr class="form-field form-required"> <tr class="form-field form-required">
<th scope="row" valign="top"> <th scope="row" valign="top">
<label for="attribute_type"><?php _e( 'Type', 'woocommerce' ); ?></label> <label for="attribute_type"><?php esc_html_e( 'Type', 'woocommerce' ); ?></label>
</th> </th>
<td> <td>
<select name="attribute_type" id="attribute_type"> <select name="attribute_type" id="attribute_type">
@ -234,27 +232,27 @@ class WC_Admin_Attributes {
do_action( 'woocommerce_admin_attribute_types' ); do_action( 'woocommerce_admin_attribute_types' );
?> ?>
</select> </select>
<p class="description"><?php _e( 'Determines how you select attributes for products. Under admin panel -> products -> product data -> attributes -> values, <strong>Text</strong> allows manual entry whereas <strong>select</strong> allows pre-configured terms in a drop-down list.', 'woocommerce' ); ?></p> <p class="description"><?php esc_html_e( 'Determines how you select attributes for products. Under admin panel -> products -> product data -> attributes -> values, <strong>Text</strong> allows manual entry whereas <strong>select</strong> allows pre-configured terms in a drop-down list.', 'woocommerce' ); ?></p>
</td> </td>
</tr> </tr>
<tr class="form-field form-required"> <tr class="form-field form-required">
<th scope="row" valign="top"> <th scope="row" valign="top">
<label for="attribute_orderby"><?php _e( 'Default sort order', 'woocommerce' ); ?></label> <label for="attribute_orderby"><?php esc_html_e( 'Default sort order', 'woocommerce' ); ?></label>
</th> </th>
<td> <td>
<select name="attribute_orderby" id="attribute_orderby"> <select name="attribute_orderby" id="attribute_orderby">
<option value="menu_order" <?php selected( $att_orderby, 'menu_order' ); ?>><?php _e( 'Custom ordering', 'woocommerce' ); ?></option> <option value="menu_order" <?php selected( $att_orderby, 'menu_order' ); ?>><?php esc_html_e( 'Custom ordering', 'woocommerce' ); ?></option>
<option value="name" <?php selected( $att_orderby, 'name' ); ?>><?php _e( 'Name', 'woocommerce' ); ?></option> <option value="name" <?php selected( $att_orderby, 'name' ); ?>><?php esc_html_e( 'Name', 'woocommerce' ); ?></option>
<option value="name_num" <?php selected( $att_orderby, 'name_num' ); ?>><?php _e( 'Name (numeric)', 'woocommerce' ); ?></option> <option value="name_num" <?php selected( $att_orderby, 'name_num' ); ?>><?php esc_html_e( 'Name (numeric)', 'woocommerce' ); ?></option>
<option value="id" <?php selected( $att_orderby, 'id' ); ?>><?php _e( 'Term ID', 'woocommerce' ); ?></option> <option value="id" <?php selected( $att_orderby, 'id' ); ?>><?php esc_html_e( 'Term ID', 'woocommerce' ); ?></option>
</select> </select>
<p class="description"><?php _e( 'Determines the sort order of the terms on the frontend shop product pages. If using custom ordering, you can drag and drop the terms in this attribute.', 'woocommerce' ); ?></p> <p class="description"><?php esc_html_e( 'Determines the sort order of the terms on the frontend shop product pages. If using custom ordering, you can drag and drop the terms in this attribute.', 'woocommerce' ); ?></p>
</td> </td>
</tr> </tr>
<?php do_action( 'woocommerce_after_edit_attribute_fields' ) ?> <?php do_action( 'woocommerce_after_edit_attribute_fields' ) ?>
</tbody> </tbody>
</table> </table>
<p class="submit"><input type="submit" name="save_attribute" id="submit" class="button-primary" value="<?php esc_attr_e( 'Update', 'woocommerce' ); ?>"></p> <p class="submit"><button type="submit" name="save_attribute" id="submit" class="button-primary" value="<?php esc_attr_e( 'Update', 'woocommerce' ); ?>"><?php esc_html_e( 'Update', 'woocommerce' ); ?></button></p>
<?php wp_nonce_field( 'woocommerce-save-attribute_' . $edit ); ?> <?php wp_nonce_field( 'woocommerce-save-attribute_' . $edit ); ?>
</form> </form>
<?php } ?> <?php } ?>
@ -270,7 +268,7 @@ class WC_Admin_Attributes {
public static function add_attribute() { public static function add_attribute() {
?> ?>
<div class="wrap woocommerce"> <div class="wrap woocommerce">
<h1><?php echo get_admin_page_title(); ?></h1> <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
<br class="clear" /> <br class="clear" />
<div id="col-container"> <div id="col-container">
@ -279,76 +277,79 @@ class WC_Admin_Attributes {
<table class="widefat attributes-table wp-list-table ui-sortable" style="width:100%"> <table class="widefat attributes-table wp-list-table ui-sortable" style="width:100%">
<thead> <thead>
<tr> <tr>
<th scope="col"><?php _e( 'Name', 'woocommerce' ); ?></th> <th scope="col"><?php esc_html_e( 'Name', 'woocommerce' ); ?></th>
<th scope="col"><?php _e( 'Slug', 'woocommerce' ); ?></th> <th scope="col"><?php esc_html_e( 'Slug', 'woocommerce' ); ?></th>
<th scope="col"><?php _e( 'Type', 'woocommerce' ); ?></th> <th scope="col"><?php esc_html_e( 'Type', 'woocommerce' ); ?></th>
<th scope="col"><?php _e( 'Order by', 'woocommerce' ); ?></th> <th scope="col"><?php esc_html_e( 'Order by', 'woocommerce' ); ?></th>
<th scope="col"><?php _e( 'Terms', 'woocommerce' ); ?></th> <th scope="col"><?php esc_html_e( 'Terms', 'woocommerce' ); ?></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php <?php
if ( $attribute_taxonomies = wc_get_attribute_taxonomies() ) : if ( $attribute_taxonomies = wc_get_attribute_taxonomies() ) :
foreach ( $attribute_taxonomies as $tax ) : foreach ( $attribute_taxonomies as $tax ) :
?><tr> ?><tr>
<td> <td>
<strong><a href="edit-tags.php?taxonomy=<?php echo esc_html( wc_attribute_taxonomy_name( $tax->attribute_name ) ); ?>&amp;post_type=product"><?php echo esc_html( $tax->attribute_label ); ?></a></strong> <strong><a href="edit-tags.php?taxonomy=<?php echo esc_html( wc_attribute_taxonomy_name( $tax->attribute_name ) ); ?>&amp;post_type=product"><?php echo esc_html( $tax->attribute_label ); ?></a></strong>
<div class="row-actions"><span class="edit"><a href="<?php echo esc_url( add_query_arg( 'edit', $tax->attribute_id, 'edit.php?post_type=product&amp;page=product_attributes' ) ); ?>"><?php _e( 'Edit', 'woocommerce' ); ?></a> | </span><span class="delete"><a class="delete" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'delete', $tax->attribute_id, 'edit.php?post_type=product&amp;page=product_attributes' ), 'woocommerce-delete-attribute_' . $tax->attribute_id ) ); ?>"><?php _e( 'Delete', 'woocommerce' ); ?></a></span></div> <div class="row-actions"><span class="edit"><a href="<?php echo esc_url( add_query_arg( 'edit', $tax->attribute_id, 'edit.php?post_type=product&amp;page=product_attributes' ) ); ?>"><?php esc_html_e( 'Edit', 'woocommerce' ); ?></a> | </span><span class="delete"><a class="delete" href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'delete', $tax->attribute_id, 'edit.php?post_type=product&amp;page=product_attributes' ), 'woocommerce-delete-attribute_' . $tax->attribute_id ) ); ?>"><?php esc_html_e( 'Delete', 'woocommerce' ); ?></a></span></div>
</td> </td>
<td><?php echo esc_html( $tax->attribute_name ); ?></td> <td><?php echo esc_html( $tax->attribute_name ); ?></td>
<td><?php echo esc_html( wc_get_attribute_type_label( $tax->attribute_type ) ); ?> <?php echo $tax->attribute_public ? __( '(Public)', 'woocommerce' ) : ''; ?></td> <td><?php echo esc_html( wc_get_attribute_type_label( $tax->attribute_type ) ); ?> <?php echo $tax->attribute_public ? esc_html__( '(Public)', 'woocommerce' ) : ''; ?></td>
<td><?php <td><?php
switch ( $tax->attribute_orderby ) {
case 'name' :
esc_html_e( 'Name', 'woocommerce' );
break;
case 'name_num' :
esc_html_e( 'Name (numeric)', 'woocommerce' );
break;
case 'id' :
esc_html_e( 'Term ID', 'woocommerce' );
break;
default:
esc_html_e( 'Custom ordering', 'woocommerce' );
break;
}
?>
</td>
<td class="attribute-terms">
<?php
$taxonomy = wc_attribute_taxonomy_name( $tax->attribute_name );
if ( taxonomy_exists( $taxonomy ) ) {
if ( 'menu_order' === wc_attribute_orderby( $taxonomy ) ) {
$terms = get_terms( $taxonomy, 'hide_empty=0&menu_order=ASC' );
} else {
$terms = get_terms( $taxonomy, 'hide_empty=0&menu_order=false' );
}
switch ( $tax->attribute_orderby ) { switch ( $tax->attribute_orderby ) {
case 'name' :
_e( 'Name', 'woocommerce' );
break;
case 'name_num' : case 'name_num' :
_e( 'Name (numeric)', 'woocommerce' ); usort( $terms, '_wc_get_product_terms_name_num_usort_callback' );
break; break;
case 'id' : case 'parent' :
_e( 'Term ID', 'woocommerce' ); usort( $terms, '_wc_get_product_terms_parent_usort_callback' );
break;
default:
_e( 'Custom ordering', 'woocommerce' );
break; break;
} }
?></td>
<td class="attribute-terms"><?php
$taxonomy = wc_attribute_taxonomy_name( $tax->attribute_name );
if ( taxonomy_exists( $taxonomy ) ) { $terms_string = implode( ', ', wp_list_pluck( $terms, 'name' ) );
if ( 'menu_order' === wc_attribute_orderby( $taxonomy ) ) { if ( $terms_string ) {
$terms = get_terms( $taxonomy, 'hide_empty=0&menu_order=ASC' ); echo esc_html( $terms_string );
} else {
$terms = get_terms( $taxonomy, 'hide_empty=0&menu_order=false' );
}
switch ( $tax->attribute_orderby ) {
case 'name_num' :
usort( $terms, '_wc_get_product_terms_name_num_usort_callback' );
break;
case 'parent' :
usort( $terms, '_wc_get_product_terms_parent_usort_callback' );
break;
}
$terms_string = implode( ', ', wp_list_pluck( $terms, 'name' ) );
if ( $terms_string ) {
echo $terms_string;
} else {
echo '<span class="na">&ndash;</span>';
}
} else { } else {
echo '<span class="na">&ndash;</span>'; echo '<span class="na">&ndash;</span>';
} }
} else {
echo '<span class="na">&ndash;</span>';
}
?> ?>
<br /><a href="edit-tags.php?taxonomy=<?php echo esc_html( wc_attribute_taxonomy_name( $tax->attribute_name ) ); ?>&amp;post_type=product" class="configure-terms"><?php _e( 'Configure terms', 'woocommerce' ); ?></a> <br /><a href="edit-tags.php?taxonomy=<?php echo esc_html( wc_attribute_taxonomy_name( $tax->attribute_name ) ); ?>&amp;post_type=product" class="configure-terms"><?php esc_html_e( 'Configure terms', 'woocommerce' ); ?></a>
</td> </td>
</tr><?php </tr>
<?php
endforeach; endforeach;
else : else :
?><tr><td colspan="6"><?php _e( 'No attributes currently exist.', 'woocommerce' ) ?></td></tr><?php ?><tr><td colspan="6"><?php esc_html_e( 'No attributes currently exist.', 'woocommerce' ) ?></td></tr><?php
endif; endif;
?> ?>
</tbody> </tbody>
@ -358,31 +359,31 @@ class WC_Admin_Attributes {
<div id="col-left"> <div id="col-left">
<div class="col-wrap"> <div class="col-wrap">
<div class="form-wrap"> <div class="form-wrap">
<h2><?php _e( 'Add new attribute', 'woocommerce' ); ?></h2> <h2><?php esc_html_e( 'Add new attribute', 'woocommerce' ); ?></h2>
<p><?php _e( 'Attributes let you define extra product data, such as size or color. You can use these attributes in the shop sidebar using the "layered nav" widgets. Please note: you cannot rename an attribute later on.', 'woocommerce' ); ?></p> <p><?php esc_html_e( 'Attributes let you define extra product data, such as size or color. You can use these attributes in the shop sidebar using the "layered nav" widgets. Please note: you cannot rename an attribute later on.', 'woocommerce' ); ?></p>
<form action="edit.php?post_type=product&amp;page=product_attributes" method="post"> <form action="edit.php?post_type=product&amp;page=product_attributes" method="post">
<?php do_action( 'woocommerce_before_add_attribute_fields' ) ?> <?php do_action( 'woocommerce_before_add_attribute_fields' ) ?>
<div class="form-field"> <div class="form-field">
<label for="attribute_label"><?php _e( 'Name', 'woocommerce' ); ?></label> <label for="attribute_label"><?php esc_html_e( 'Name', 'woocommerce' ); ?></label>
<input name="attribute_label" id="attribute_label" type="text" value="" /> <input name="attribute_label" id="attribute_label" type="text" value="" />
<p class="description"><?php _e( 'Name for the attribute (shown on the front-end).', 'woocommerce' ); ?></p> <p class="description"><?php esc_html_e( 'Name for the attribute (shown on the front-end).', 'woocommerce' ); ?></p>
</div> </div>
<div class="form-field"> <div class="form-field">
<label for="attribute_name"><?php _e( 'Slug', 'woocommerce' ); ?></label> <label for="attribute_name"><?php esc_html_e( 'Slug', 'woocommerce' ); ?></label>
<input name="attribute_name" id="attribute_name" type="text" value="" maxlength="28" /> <input name="attribute_name" id="attribute_name" type="text" value="" maxlength="28" />
<p class="description"><?php _e( 'Unique slug/reference for the attribute; must be no more than 28 characters.', 'woocommerce' ); ?></p> <p class="description"><?php esc_html_e( 'Unique slug/reference for the attribute; must be no more than 28 characters.', 'woocommerce' ); ?></p>
</div> </div>
<div class="form-field"> <div class="form-field">
<label for="attribute_public"><input name="attribute_public" id="attribute_public" type="checkbox" value="1" /> <?php _e( 'Enable Archives?', 'woocommerce' ); ?></label> <label for="attribute_public"><input name="attribute_public" id="attribute_public" type="checkbox" value="1" /> <?php esc_html_e( 'Enable Archives?', 'woocommerce' ); ?></label>
<p class="description"><?php _e( 'Enable this if you want this attribute to have product archives in your store.', 'woocommerce' ); ?></p> <p class="description"><?php esc_html_e( 'Enable this if you want this attribute to have product archives in your store.', 'woocommerce' ); ?></p>
</div> </div>
<div class="form-field"> <div class="form-field">
<label for="attribute_type"><?php _e( 'Type', 'woocommerce' ); ?></label> <label for="attribute_type"><?php esc_html_e( 'Type', 'woocommerce' ); ?></label>
<select name="attribute_type" id="attribute_type"> <select name="attribute_type" id="attribute_type">
<?php foreach ( wc_get_attribute_types() as $key => $value ) : ?> <?php foreach ( wc_get_attribute_types() as $key => $value ) : ?>
<option value="<?php echo esc_attr( $key ); ?>"><?php echo esc_attr( $value ); ?></option> <option value="<?php echo esc_attr( $key ); ?>"><?php echo esc_attr( $value ); ?></option>
@ -398,23 +399,23 @@ class WC_Admin_Attributes {
do_action( 'woocommerce_admin_attribute_types' ); do_action( 'woocommerce_admin_attribute_types' );
?> ?>
</select> </select>
<p class="description"><?php _e( 'Determines how you select attributes for products. Under admin panel -> products -> product data -> attributes -> values, <strong>Text</strong> allows manual entry whereas <strong>select</strong> allows pre-configured terms in a drop-down list.', 'woocommerce' ); ?></p> <p class="description"><?php esc_html_e( 'Determines how you select attributes for products. Under admin panel -> products -> product data -> attributes -> values, <strong>Text</strong> allows manual entry whereas <strong>select</strong> allows pre-configured terms in a drop-down list.', 'woocommerce' ); ?></p>
</div> </div>
<div class="form-field"> <div class="form-field">
<label for="attribute_orderby"><?php _e( 'Default sort order', 'woocommerce' ); ?></label> <label for="attribute_orderby"><?php esc_html_e( 'Default sort order', 'woocommerce' ); ?></label>
<select name="attribute_orderby" id="attribute_orderby"> <select name="attribute_orderby" id="attribute_orderby">
<option value="menu_order"><?php _e( 'Custom ordering', 'woocommerce' ); ?></option> <option value="menu_order"><?php esc_html_e( 'Custom ordering', 'woocommerce' ); ?></option>
<option value="name"><?php _e( 'Name', 'woocommerce' ); ?></option> <option value="name"><?php esc_html_e( 'Name', 'woocommerce' ); ?></option>
<option value="name_num"><?php _e( 'Name (numeric)', 'woocommerce' ); ?></option> <option value="name_num"><?php esc_html_e( 'Name (numeric)', 'woocommerce' ); ?></option>
<option value="id"><?php _e( 'Term ID', 'woocommerce' ); ?></option> <option value="id"><?php esc_html_e( 'Term ID', 'woocommerce' ); ?></option>
</select> </select>
<p class="description"><?php _e( 'Determines the sort order of the terms on the frontend shop product pages. If using custom ordering, you can drag and drop the terms in this attribute.', 'woocommerce' ); ?></p> <p class="description"><?php esc_html_e( 'Determines the sort order of the terms on the frontend shop product pages. If using custom ordering, you can drag and drop the terms in this attribute.', 'woocommerce' ); ?></p>
</div> </div>
<?php do_action( 'woocommerce_after_add_attribute_fields' ) ?> <?php do_action( 'woocommerce_after_add_attribute_fields' ) ?>
<p class="submit"><input type="submit" name="add_new_attribute" id="submit" class="button button-primary" value="<?php esc_attr_e( 'Add attribute', 'woocommerce' ); ?>"></p> <p class="submit"><button type="submit" name="add_new_attribute" id="submit" class="button button-primary" value="<?php esc_attr_e( 'Add attribute', 'woocommerce' ); ?>"><?php esc_html_e( 'Add attribute', 'woocommerce' ); ?></button></p>
<?php wp_nonce_field( 'woocommerce-add-new_attribute' ); ?> <?php wp_nonce_field( 'woocommerce-add-new_attribute' ); ?>
</form> </form>
</div> </div>
@ -425,7 +426,7 @@ class WC_Admin_Attributes {
/* <![CDATA[ */ /* <![CDATA[ */
jQuery( 'a.delete' ).click( function() { jQuery( 'a.delete' ).click( function() {
if ( window.confirm( '<?php _e( "Are you sure you want to delete this attribute?", "woocommerce" ); ?>' ) ) { if ( window.confirm( '<?php esc_html_e( 'Are you sure you want to delete this attribute?', 'woocommerce' ); ?>' ) ) {
return true; return true;
} }
return false; return false;

View File

@ -334,6 +334,10 @@ class WC_Admin_Log_Table_List extends WP_List_Table {
$where_conditions[] = 'source = %s'; $where_conditions[] = 'source = %s';
$where_values[] = wc_clean( $_REQUEST['source'] ); $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 ) ) { if ( ! empty( $where_conditions ) ) {
return $wpdb->prepare( 'WHERE 1 = 1 AND ' . implode( ' AND ', $where_conditions ), $where_values ); return $wpdb->prepare( 'WHERE 1 = 1 AND ' . implode( ' AND ', $where_conditions ), $where_values );

View File

@ -309,8 +309,7 @@ class WC_Admin_Menus {
<a href="<?php echo esc_url( admin_url( 'nav-menus.php?page-tab=all&selectall=1#posttype-woocommerce-endpoints' ) ); ?>" class="select-all"><?php esc_html_e( 'Select all', 'woocommerce' ); ?></a> <a href="<?php echo esc_url( admin_url( 'nav-menus.php?page-tab=all&selectall=1#posttype-woocommerce-endpoints' ) ); ?>" class="select-all"><?php esc_html_e( 'Select all', 'woocommerce' ); ?></a>
</span> </span>
<span class="add-to-menu"> <span class="add-to-menu">
<input type="submit" class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( 'Add to menu', 'woocommerce' ); ?>" name="add-post-type-menu-item" id="submit-posttype-woocommerce-endpoints"> <button type="submit" class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( 'Add to menu', 'woocommerce' ); ?>" name="add-post-type-menu-item" id="submit-posttype-woocommerce-endpoints"><?php esc_html_e( 'Add to menu', 'woocommerce' ); ?></button>
<span class="spinner"></span>
</span> </span>
</p> </p>
</div> </div>

View File

@ -79,7 +79,7 @@ class WC_Admin_Notices {
* Reset notices for themes when switched or a new version of WC is installed. * Reset notices for themes when switched or a new version of WC is installed.
*/ */
public static function reset_admin_notices() { 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' ); self::add_notice( 'theme_support' );
} }
@ -216,7 +216,7 @@ class WC_Admin_Notices {
* Show the Theme Check notice. * Show the Theme Check notice.
*/ */
public static function 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' ); include( 'views/html-notice-theme-support.php' );
} else { } else {
self::remove_notice( 'theme_support' ); self::remove_notice( 'theme_support' );

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -223,6 +223,9 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
if ( ! isset( $value['placeholder'] ) ) { if ( ! isset( $value['placeholder'] ) ) {
$value['placeholder'] = ''; $value['placeholder'] = '';
} }
if ( ! isset( $value['suffix'] ) ) {
$value['suffix'] = '';
}
// Custom attribute handling. // Custom attribute handling.
$custom_attributes = array(); $custom_attributes = array();
@ -288,7 +291,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
class="<?php echo esc_attr( $value['class'] ); ?>" class="<?php echo esc_attr( $value['class'] ); ?>"
placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>" placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>"
<?php echo implode( ' ', $custom_attributes ); // WPCS: XSS ok. ?> <?php echo implode( ' ', $custom_attributes ); // WPCS: XSS ok. ?>
/> <?php echo $description; // WPCS: XSS ok. ?> /><?php echo esc_html( $value['suffix'] ); ?> <?php echo $description; // WPCS: XSS ok. ?>
</td> </td>
</tr> </tr>
<?php <?php
@ -498,7 +501,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
} }
break; break;
// Image width settings. // Image width settings. @todo deprecate and remove in 4.0. No longer needed by core.
case 'image_width': case 'image_width':
$image_size = str_replace( '_image_size', '', $value['id'] ); $image_size = str_replace( '_image_size', '', $value['id'] );
$size = wc_get_image_size( $image_size ); $size = wc_get_image_size( $image_size );
@ -527,6 +530,64 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
<?php <?php
break; 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; // WPCS: XSS ok. ?></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( ! in_array( $option_value, array( '1:1', 'uncropped' ), true ), true ); ?> />
<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( $option_value, 'custom' ); ?> />
<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 esc_attr( $width ); ?>" /> : <input name="thumbnail_cropping_aspect_ratio_height" type="text" pattern="\d*" size="3" value="<?php echo esc_attr( $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. // Single page selects.
case 'single_select_page': case 'single_select_page':
$args = array( $args = array(
@ -723,6 +784,15 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
$value['crop'] = $option['default']['crop']; $value['crop'] = $option['default']['crop'];
} }
break; break;
case 'thumbnail_cropping':
$value = wc_clean( $raw_value );
if ( 'custom' === $value ) {
$width_ratio = isset( $_POST['thumbnail_cropping_aspect_ratio_width'] ) ? wc_clean( wp_unslash( $_POST['thumbnail_cropping_aspect_ratio_width'] ) ) : '1'; // WPCS: input var ok, CSRF ok.
$height_ratio = isset( $_POST['thumbnail_cropping_aspect_ratio_height'] ) ? wc_clean( wp_unslash( $_POST['thumbnail_cropping_aspect_ratio_height'] ) ) : '1'; // WPCS: input var ok, CSRF ok.
$value = $width_ratio . ':' . $height_ratio;
}
break;
case 'select': case 'select':
$allowed_values = empty( $option['options'] ) ? array() : array_keys( $option['options'] ); $allowed_values = empty( $option['options'] ) ? array() : array_keys( $option['options'] );
if ( empty( $option['default'] ) && empty( $allowed_values ) ) { if ( empty( $option['default'] ) && empty( $allowed_values ) ) {

View File

@ -9,6 +9,7 @@
* @package WooCommerce/Admin * @package WooCommerce/Admin
* @version 2.6.0 * @version 2.6.0
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
@ -18,16 +19,32 @@ if ( ! defined( 'ABSPATH' ) ) {
*/ */
class WC_Admin_Setup_Wizard { class WC_Admin_Setup_Wizard {
/** @var string Current Step */ /**
* Current step
*
* @var string
*/
private $step = ''; private $step = '';
/** @var array Steps for the setup wizard */ /**
* Steps for the setup wizard
*
* @var array
*/
private $steps = array(); private $steps = array();
/** @var array Actions to be executed after the HTTP response has completed */ /**
* Actions to be executed after the HTTP response has completed
*
* @var array
*/
private $deferred_actions = array(); private $deferred_actions = array();
/** @var array Tweets user can optionally send after install */ /**
* Tweets user can optionally send after install
*
* @var array
*/
private $tweets = array( private $tweets = array(
'Someone give me woo-t, I just set up a new store with #WordPress and @WooCommerce!', 'Someone give me woo-t, I just set up a new store with #WordPress and @WooCommerce!',
'Someone give me high five, I just set up a new store with #WordPress and @WooCommerce!', 'Someone give me high five, I just set up a new store with #WordPress and @WooCommerce!',
@ -73,7 +90,7 @@ class WC_Admin_Setup_Wizard {
} }
$country_code = WC()->countries->get_base_country(); $country_code = WC()->countries->get_base_country();
// https://developers.taxjar.com/api/reference/#countries // https://developers.taxjar.com/api/reference/#countries .
$tax_supported_countries = array_merge( $tax_supported_countries = array_merge(
array( 'US', 'CA', 'AU' ), array( 'US', 'CA', 'AU' ),
WC()->countries->get_european_union_countries() WC()->countries->get_european_union_countries()
@ -176,9 +193,11 @@ class WC_Admin_Setup_Wizard {
'pending_jetpack_install' => $pending_jetpack ? 'yes' : 'no', 'pending_jetpack_install' => $pending_jetpack ? 'yes' : 'no',
) ); ) );
// @codingStandardsIgnoreStart
if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) { if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) {
call_user_func( $this->steps[ $this->step ]['handler'], $this ); call_user_func( $this->steps[ $this->step ]['handler'], $this );
} }
// @codingStandardsIgnoreEnd
ob_start(); ob_start();
$this->setup_wizard_header(); $this->setup_wizard_header();
@ -190,7 +209,8 @@ class WC_Admin_Setup_Wizard {
/** /**
* Get the URL for the next step's screen. * Get the URL for the next step's screen.
* @param string step slug (default: current step) *
* @param string $step slug (default: current step).
* @return string URL for next step if a next step exists. * @return string URL for next step if a next step exists.
* Admin URL if it's the last step. * Admin URL if it's the last step.
* Empty string on failure. * Empty string on failure.
@ -230,7 +250,7 @@ class WC_Admin_Setup_Wizard {
<?php do_action( 'admin_head' ); ?> <?php do_action( 'admin_head' ); ?>
</head> </head>
<body class="wc-setup wp-core-ui"> <body class="wc-setup wp-core-ui">
<h1 id="wc-logo"><a href="https://woocommerce.com/"><img src="<?php echo WC()->plugin_url(); ?>/assets/images/woocommerce_logo.png" alt="WooCommerce" /></a></h1> <h1 id="wc-logo"><a href="https://woocommerce.com/"><img src="<?php echo esc_url( WC()->plugin_url() ); ?>/assets/images/woocommerce_logo.png" alt="WooCommerce" /></a></h1>
<?php <?php
} }
@ -259,13 +279,15 @@ class WC_Admin_Setup_Wizard {
?> ?>
<ol class="wc-setup-steps"> <ol class="wc-setup-steps">
<?php foreach ( $output_steps as $step_key => $step ) : ?> <?php foreach ( $output_steps as $step_key => $step ) : ?>
<li class="<?php <li class="
<?php
if ( $step_key === $this->step ) { if ( $step_key === $this->step ) {
echo 'active'; echo 'active';
} elseif ( array_search( $this->step, array_keys( $this->steps ) ) > array_search( $step_key, array_keys( $this->steps ) ) ) { } elseif ( array_search( $this->step, array_keys( $this->steps ) ) > array_search( $step_key, array_keys( $this->steps ) ) ) {
echo 'done'; echo 'done';
} }
?>"><?php echo esc_html( $step['name'] ); ?></li> ?>
"><?php echo esc_html( $step['name'] ); ?></li>
<?php endforeach; ?> <?php endforeach; ?>
</ol> </ol>
<?php <?php
@ -294,7 +316,7 @@ class WC_Admin_Setup_Wizard {
$country = WC()->countries->get_base_country(); $country = WC()->countries->get_base_country();
$postcode = WC()->countries->get_base_postcode(); $postcode = WC()->countries->get_base_postcode();
$currency = get_option( 'woocommerce_currency', 'GBP' ); $currency = get_option( 'woocommerce_currency', 'GBP' );
$product_type = get_option( 'woocommerce_product_type' ); $product_type = get_option( 'woocommerce_product_type', 'both' );
if ( empty( $country ) ) { if ( empty( $country ) ) {
$user_location = WC_Geolocation::geolocate_ip(); $user_location = WC_Geolocation::geolocate_ip();
@ -310,7 +332,7 @@ class WC_Admin_Setup_Wizard {
?> ?>
<form method="post" class="address-step"> <form method="post" class="address-step">
<?php wp_nonce_field( 'wc-setup' ); ?> <?php wp_nonce_field( 'wc-setup' ); ?>
<p class="store-setup"><?php esc_html_e( "The following wizard will help you configure your store and get you started quickly.", 'woocommerce' ); ?></p> <p class="store-setup"><?php esc_html_e( 'The following wizard will help you configure your store and get you started quickly.', 'woocommerce' ); ?></p>
<label for="store_country_state" class="location-prompt"> <label for="store_country_state" class="location-prompt">
<?php esc_html_e( 'Where is your store based?', 'woocommerce' ); ?> <?php esc_html_e( 'Where is your store based?', 'woocommerce' ); ?>
</label> </label>
@ -390,7 +412,11 @@ class WC_Admin_Setup_Wizard {
<option value=""><?php esc_html_e( 'Choose a currency&hellip;', 'woocommerce' ); ?></option> <option value=""><?php esc_html_e( 'Choose a currency&hellip;', 'woocommerce' ); ?></option>
<?php foreach ( get_woocommerce_currencies() as $code => $name ) : ?> <?php foreach ( get_woocommerce_currencies() as $code => $name ) : ?>
<option value="<?php echo esc_attr( $code ); ?>" <?php selected( $currency, $code ); ?>> <option value="<?php echo esc_attr( $code ); ?>" <?php selected( $currency, $code ); ?>>
<?php printf( esc_html__( '%1$s (%2$s)', 'woocommerce' ), $name, get_woocommerce_currency_symbol( $code ) ); ?> <?php
// @codingStandardsIgnoreStart
printf( esc_html__( '%1$s (%2$s)', 'woocommerce' ), $name, get_woocommerce_currency_symbol( $code ) );
// // @codingStandardsIgnoreEnd
?>
</option> </option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
@ -405,22 +431,20 @@ class WC_Admin_Setup_Wizard {
id="product_type" id="product_type"
name="product_type" name="product_type"
required required
data-placeholder="<?php esc_attr_e( 'Please choose one&hellip;', 'woocommerce' ); ?>"
class="location-input wc-enhanced-select dropdown" class="location-input wc-enhanced-select dropdown"
> >
<option value="" <?php selected( $product_type, '' ); ?>><?php esc_html_e( 'Please choose one&hellip;', 'woocommerce' ); ?></option> <option value="both" <?php selected( $product_type, 'both' ); ?>><?php esc_html_e( 'I plan to sell both physical and digital products', 'woocommerce' ); ?></option>
<option value="physical" <?php selected( $product_type, 'physical' ); ?>><?php esc_html_e( 'I plan to sell physical products', 'woocommerce' ); ?></option> <option value="physical" <?php selected( $product_type, 'physical' ); ?>><?php esc_html_e( 'I plan to sell physical products', 'woocommerce' ); ?></option>
<option value="virtual" <?php selected( $product_type, 'virtual' ); ?>><?php esc_html_e( 'I plan to sell digital products', 'woocommerce' ); ?></option> <option value="virtual" <?php selected( $product_type, 'virtual' ); ?>><?php esc_html_e( 'I plan to sell digital products', 'woocommerce' ); ?></option>
<option value="both" <?php selected( $product_type, 'both' ); ?>><?php esc_html_e( 'I plan to sell both physical and digital products', 'woocommerce' ); ?></option>
</select> </select>
<?php if ( 'unknown' === get_option( 'woocommerce_allow_tracking', 'unknown' ) ) : ?> <?php if ( 'unknown' === get_option( 'woocommerce_allow_tracking', 'unknown' ) ) : ?>
<div class="allow-tracking"> <div class="allow-tracking">
<input type="checkbox" id="wc_tracker_optin" name="wc_tracker_optin" value="yes" checked /> <input type="checkbox" id="wc_tracker_optin" name="wc_tracker_optin" value="yes" checked />
<label for="wc_tracker_optin"><?php _e( 'Allow WooCommerce to collect non-sensitive diagnostic data and usage information.', 'woocommerce' ); ?></label> <label for="wc_tracker_optin"><?php esc_html_e( 'Allow WooCommerce to collect non-sensitive diagnostic data and usage information.', 'woocommerce' ); ?></label>
</div> </div>
<?php endif; ?> <?php endif; ?>
<p class="wc-setup-actions step"> <p class="wc-setup-actions step">
<input type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( "Let's go!", 'woocommerce' ); ?>" name="save_step" /> <button type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( "Let's go!", 'woocommerce' ); ?>" name="save_step"><?php esc_html_e( "Let's go!", 'woocommerce' ); ?></button>
</p> </p>
</form> </form>
<?php <?php
@ -431,7 +455,7 @@ class WC_Admin_Setup_Wizard {
*/ */
public function wc_setup_store_setup_save() { public function wc_setup_store_setup_save() {
check_admin_referer( 'wc-setup' ); check_admin_referer( 'wc-setup' );
// @codingStandardsIgnoreStart
$address = sanitize_text_field( $_POST['store_address'] ); $address = sanitize_text_field( $_POST['store_address'] );
$address_2 = sanitize_text_field( $_POST['store_address_2'] ); $address_2 = sanitize_text_field( $_POST['store_address_2'] );
$city = sanitize_text_field( $_POST['store_city'] ); $city = sanitize_text_field( $_POST['store_city'] );
@ -440,7 +464,7 @@ class WC_Admin_Setup_Wizard {
$currency_code = sanitize_text_field( $_POST['currency_code'] ); $currency_code = sanitize_text_field( $_POST['currency_code'] );
$product_type = sanitize_text_field( $_POST['product_type'] ); $product_type = sanitize_text_field( $_POST['product_type'] );
$tracking = isset( $_POST['wc_tracker_optin'] ) && ( 'yes' === sanitize_text_field( $_POST['wc_tracker_optin'] ) ); $tracking = isset( $_POST['wc_tracker_optin'] ) && ( 'yes' === sanitize_text_field( $_POST['wc_tracker_optin'] ) );
// @codingStandardsIgnoreEnd
update_option( 'woocommerce_store_address', $address ); update_option( 'woocommerce_store_address', $address );
update_option( 'woocommerce_store_address_2', $address_2 ); update_option( 'woocommerce_store_address_2', $address_2 );
update_option( 'woocommerce_store_city', $city ); update_option( 'woocommerce_store_city', $city );
@ -477,13 +501,16 @@ class WC_Admin_Setup_Wizard {
/** /**
* Finishes replying to the client, but keeps the process running for further (async) code execution. * Finishes replying to the client, but keeps the process running for further (async) code execution.
* @see https://core.trac.wordpress.org/ticket/41358 *
* @see https://core.trac.wordpress.org/ticket/41358 .
*/ */
protected function close_http_connection() { protected function close_http_connection() {
// Only 1 PHP process can access a session object at a time, close this so the next request isn't kept waiting. // Only 1 PHP process can access a session object at a time, close this so the next request isn't kept waiting.
// @codingStandardsIgnoreStart
if ( session_id() ) { if ( session_id() ) {
session_write_close(); session_write_close();
} }
// @codingStandardsIgnoreEnd
wc_set_time_limit( 0 ); wc_set_time_limit( 0 );
@ -502,6 +529,7 @@ class WC_Admin_Setup_Wizard {
/** /**
* Function called after the HTTP request is finished, so it's executed without the client having to wait for it. * Function called after the HTTP request is finished, so it's executed without the client having to wait for it.
*
* @see WC_Admin_Setup_Wizard::install_plugin * @see WC_Admin_Setup_Wizard::install_plugin
* @see WC_Admin_Setup_Wizard::install_theme * @see WC_Admin_Setup_Wizard::install_theme
*/ */
@ -543,7 +571,7 @@ class WC_Admin_Setup_Wizard {
array_push( $this->deferred_actions, array( array_push( $this->deferred_actions, array(
'func' => array( 'WC_Install', 'background_installer' ), 'func' => array( 'WC_Install', 'background_installer' ),
'args' => array( $plugin_id, $plugin_info ) 'args' => array( $plugin_id, $plugin_info ),
) ); ) );
// Set the background installation flag for this plugin. // Set the background installation flag for this plugin.
@ -562,7 +590,7 @@ class WC_Admin_Setup_Wizard {
} }
array_push( $this->deferred_actions, array( array_push( $this->deferred_actions, array(
'func' => array( 'WC_Install', 'theme_background_installer' ), 'func' => array( 'WC_Install', 'theme_background_installer' ),
'args' => array( $theme_id ) 'args' => array( $theme_id ),
) ); ) );
} }
@ -594,8 +622,8 @@ class WC_Admin_Setup_Wizard {
* *
* Can also be used to determine if WCS supports a given country. * Can also be used to determine if WCS supports a given country.
* *
* @param string $country_code * @param string $country_code Country Code.
* @param string $currency_code * @param string $currency_code Currecy Code.
* @return bool|string Carrier name if supported, boolean False otherwise. * @return bool|string Carrier name if supported, boolean False otherwise.
*/ */
protected function get_wcs_shipping_carrier( $country_code, $currency_code ) { protected function get_wcs_shipping_carrier( $country_code, $currency_code ) {
@ -612,8 +640,8 @@ class WC_Admin_Setup_Wizard {
/** /**
* Get shipping methods based on country code. * Get shipping methods based on country code.
* *
* @param string $country_code * @param string $country_code Country code.
* @param string $currency_code * @param string $currency_code Currency code.
* @return array * @return array
*/ */
protected function get_wizard_shipping_methods( $country_code, $currency_code ) { protected function get_wizard_shipping_methods( $country_code, $currency_code ) {
@ -628,7 +656,7 @@ class WC_Admin_Setup_Wizard {
'settings' => array( 'settings' => array(
'cost' => array( 'cost' => array(
'type' => 'text', 'type' => 'text',
'default_value' => __( 'Cost', 'Short label for entering the cost of an item', 'woocommerce' ), 'default_value' => __( 'Cost', 'woocommerce' ),
'description' => __( 'What would you like to charge for flat rate shipping?', 'woocommerce' ), 'description' => __( 'What would you like to charge for flat rate shipping?', 'woocommerce' ),
'required' => true, 'required' => true,
), ),
@ -642,7 +670,7 @@ class WC_Admin_Setup_Wizard {
$live_rate_carrier = $this->get_wcs_shipping_carrier( $country_code, $currency_code ); $live_rate_carrier = $this->get_wcs_shipping_carrier( $country_code, $currency_code );
if ( false === $live_rate_carrier || ! current_user_can('install_plugins') ) { if ( false === $live_rate_carrier || ! current_user_can( 'install_plugins' ) ) {
unset( $shipping_methods['live_rates'] ); unset( $shipping_methods['live_rates'] );
} }
@ -652,9 +680,9 @@ class WC_Admin_Setup_Wizard {
/** /**
* Render the available shipping methods for a given country code. * Render the available shipping methods for a given country code.
* *
* @param string $country_code * @param string $country_code Country code.
* @param string $currency_code * @param string $currency_code Currency code.
* @param string $input_prefix * @param string $input_prefix Input prefix.
*/ */
protected function shipping_method_selection_form( $country_code, $currency_code, $input_prefix ) { protected function shipping_method_selection_form( $country_code, $currency_code, $input_prefix ) {
$live_rate_carrier = $this->get_wcs_shipping_carrier( $country_code, $currency_code ); $live_rate_carrier = $this->get_wcs_shipping_carrier( $country_code, $currency_code );
@ -673,7 +701,7 @@ class WC_Admin_Setup_Wizard {
</div> </div>
<div class="shipping-method-descriptions"> <div class="shipping-method-descriptions">
<?php foreach ( $shipping_methods as $method_id => $method ) : ?> <?php foreach ( $shipping_methods as $method_id => $method ) : ?>
<p class="shipping-method-description <?php echo esc_attr( $method_id ); ?> <?php if ( $method_id !== $selected ) echo 'hide'; ?>"> <p class="shipping-method-description <?php echo esc_attr( $method_id ); ?> <?php if ( $method_id !== $selected ) { echo 'hide'; } ?>">
<?php echo esc_html( $method['description'] ); ?> <?php echo esc_html( $method['description'] ); ?>
</p> </p>
<?php endforeach; ?> <?php endforeach; ?>
@ -682,8 +710,8 @@ class WC_Admin_Setup_Wizard {
<div class="shipping-method-settings"> <div class="shipping-method-settings">
<?php foreach ( $shipping_methods as $method_id => $method ) : ?> <?php foreach ( $shipping_methods as $method_id => $method ) : ?>
<?php if ( empty( $method['settings'] ) ) continue; ?> <?php if ( empty( $method['settings'] ) ) { continue; } ?>
<div class="shipping-method-setting <?php echo esc_attr( $method_id ); ?> <?php if ( $method_id !== $selected ) echo 'hide'; ?>"> <div class="shipping-method-setting <?php echo esc_attr( $method_id ); ?> <?php if ( $method_id !== $selected ) { echo 'hide'; } ?>">
<?php foreach ( $method['settings'] as $setting_id => $setting ) : ?> <?php foreach ( $method['settings'] as $setting_id => $setting ) : ?>
<?php $method_setting_id = "{$input_prefix}[{$method_id}][{$setting_id}]"; ?> <?php $method_setting_id = "{$input_prefix}[{$method_id}][{$setting_id}]"; ?>
<input <input
@ -727,15 +755,15 @@ class WC_Admin_Setup_Wizard {
if ( ! empty( $existing_zones ) ) { if ( ! empty( $existing_zones ) ) {
$intro_text = __( 'How would you like units on your store displayed?', 'woocommerce' ); $intro_text = __( 'How would you like units on your store displayed?', 'woocommerce' );
} elseif ( $wcs_carrier ) { } elseif ( $wcs_carrier ) {
$intro_text = sprintf(
/* translators: %1$s: country name including the 'the' prefix, %2$s: shipping carrier name */ /* translators: %1$s: country name including the 'the' prefix, %2$s: shipping carrier name */
$intro_text = sprintf(
__( "You're all set up to ship anywhere in %1\$s, and outside of it. We recommend using <strong>live rates</strong> (which are powered by our WooCommerce Services plugin and Jetpack) to get accurate %2\$s shipping prices to cover the cost of order fulfillment.", 'woocommerce' ), __( "You're all set up to ship anywhere in %1\$s, and outside of it. We recommend using <strong>live rates</strong> (which are powered by our WooCommerce Services plugin and Jetpack) to get accurate %2\$s shipping prices to cover the cost of order fulfillment.", 'woocommerce' ),
$prefixed_country_name, $prefixed_country_name,
$wcs_carrier $wcs_carrier
); );
} else { } else {
$intro_text = sprintf(
/* translators: %s: country name including the 'the' prefix if needed */ /* translators: %s: country name including the 'the' prefix if needed */
$intro_text = sprintf(
__( "You can choose which countries you'll be shipping to and with which methods. To get started, we've set you up with shipping inside and outside of %s.", 'woocommerce' ), __( "You can choose which countries you'll be shipping to and with which methods. To get started, we've set you up with shipping inside and outside of %s.", 'woocommerce' ),
$prefixed_country_name $prefixed_country_name
); );
@ -827,7 +855,7 @@ class WC_Admin_Setup_Wizard {
</div> </div>
<p class="wc-setup-actions step"> <p class="wc-setup-actions step">
<input type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step" /> <button type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step"><?php esc_html_e( 'Continue', 'woocommerce' ); ?></button>
<?php wp_nonce_field( 'wc-setup' ); ?> <?php wp_nonce_field( 'wc-setup' ); ?>
</p> </p>
</form> </form>
@ -840,18 +868,20 @@ class WC_Admin_Setup_Wizard {
public function wc_setup_shipping_save() { public function wc_setup_shipping_save() {
check_admin_referer( 'wc-setup' ); check_admin_referer( 'wc-setup' );
// If going through this step again, remove the live rates options // If going through this step again, remove the live rates options.
// in case the user saved different settings this time // in case the user saved different settings this time.
delete_option( 'woocommerce_setup_domestic_live_rates_zone' ); delete_option( 'woocommerce_setup_domestic_live_rates_zone' );
delete_option( 'woocommerce_setup_intl_live_rates_zone' ); delete_option( 'woocommerce_setup_intl_live_rates_zone' );
// @codingStandardsIgnoreStart
$setup_domestic = isset( $_POST['shipping_zones']['domestic']['enabled'] ) && ( 'yes' === $_POST['shipping_zones']['domestic']['enabled'] ); $setup_domestic = isset( $_POST['shipping_zones']['domestic']['enabled'] ) && ( 'yes' === $_POST['shipping_zones']['domestic']['enabled'] );
$domestic_method = sanitize_text_field( $_POST['shipping_zones']['domestic']['method'] ); $domestic_method = sanitize_text_field( wp_unslash( $_POST['shipping_zones']['domestic']['method'] ) );
$setup_intl = isset( $_POST['shipping_zones']['intl']['enabled'] ) && ( 'yes' === $_POST['shipping_zones']['intl']['enabled'] ); $setup_intl = isset( $_POST['shipping_zones']['intl']['enabled'] ) && ( 'yes' === $_POST['shipping_zones']['intl']['enabled'] );
$intl_method = sanitize_text_field( $_POST['shipping_zones']['intl']['method'] ); $intl_method = sanitize_text_field( wp_unslash( $_POST['shipping_zones']['intl']['method'] ) );
$weight_unit = sanitize_text_field( $_POST['weight_unit'] ); $weight_unit = sanitize_text_field( wp_unslash( $_POST['weight_unit'] ) );
$dimension_unit = sanitize_text_field( $_POST['dimension_unit'] ); $dimension_unit = sanitize_text_field( wp_unslash( $_POST['dimension_unit'] ) );
$existing_zones = WC_Shipping_Zones::get_zones(); $existing_zones = WC_Shipping_Zones::get_zones();
// @codingStandardsIgnoreEnd
update_option( 'woocommerce_ship_to_countries', '' ); update_option( 'woocommerce_ship_to_countries', '' );
update_option( 'woocommerce_weight_unit', $weight_unit ); update_option( 'woocommerce_weight_unit', $weight_unit );
@ -894,12 +924,13 @@ class WC_Admin_Setup_Wizard {
// Save chosen shipping method settings (using REST controller for convenience). // Save chosen shipping method settings (using REST controller for convenience).
if ( isset( $instance_id ) && ! empty( $_POST['shipping_zones']['domestic'][ $domestic_method ] ) ) { if ( isset( $instance_id ) && ! empty( $_POST['shipping_zones']['domestic'][ $domestic_method ] ) ) {
$method_controller = new WC_REST_Shipping_Zone_Methods_Controller(); $method_controller = new WC_REST_Shipping_Zone_Methods_Controller();
// @codingStandardsIgnoreStart
$method_controller->update_item( array( $method_controller->update_item( array(
'zone_id' => $zone->get_id(), 'zone_id' => $zone->get_id(),
'instance_id' => $instance_id, 'instance_id' => $instance_id,
'settings' => $_POST['shipping_zones']['domestic'][ $domestic_method ], 'settings' => wp_unslash( $_POST['shipping_zones']['domestic'][ $domestic_method ] ),
) ); ) );
// @codingStandardsIgnoreEnd
} }
} }
@ -918,12 +949,13 @@ class WC_Admin_Setup_Wizard {
// Save chosen shipping method settings (using REST controller for convenience). // Save chosen shipping method settings (using REST controller for convenience).
if ( isset( $instance_id ) && ! empty( $_POST['shipping_zones']['intl'][ $intl_method ] ) ) { if ( isset( $instance_id ) && ! empty( $_POST['shipping_zones']['intl'][ $intl_method ] ) ) {
$method_controller = new WC_REST_Shipping_Zone_Methods_Controller(); $method_controller = new WC_REST_Shipping_Zone_Methods_Controller();
// @codingStandardsIgnoreStart
$method_controller->update_item( array( $method_controller->update_item( array(
'zone_id' => $zone->get_id(), 'zone_id' => $zone->get_id(),
'instance_id' => $instance_id, 'instance_id' => $instance_id,
'settings' => $_POST['shipping_zones']['intl'][ $intl_method ], 'settings' => wp_unslash( $_POST['shipping_zones']['intl'][ $intl_method ] ),
) ); ) );
// @codingStandardsIgnoreEnd
} }
} }
@ -937,7 +969,10 @@ class WC_Admin_Setup_Wizard {
} }
/** /**
* https://stripe.com/global * Is Stripe country supported
* https://stripe.com/global .
*
* @param string $country_code Country code.
*/ */
protected function is_stripe_supported_country( $country_code ) { protected function is_stripe_supported_country( $country_code ) {
$stripe_supported_countries = array( $stripe_supported_countries = array(
@ -1078,6 +1113,7 @@ class WC_Admin_Setup_Wizard {
/** /**
* Simple array of "manual" gateways to show in wizard. * Simple array of "manual" gateways to show in wizard.
*
* @return array * @return array
*/ */
protected function get_wizard_manual_payment_gateways() { protected function get_wizard_manual_payment_gateways() {
@ -1107,6 +1143,9 @@ class WC_Admin_Setup_Wizard {
/** /**
* Display service item in list. * Display service item in list.
*
* @param int $item_id Item ID.
* @param array $item_info Item info array.
*/ */
public function display_service_item( $item_id, $item_info ) { public function display_service_item( $item_id, $item_info ) {
$item_class = 'wc-wizard-service-item'; $item_class = 'wc-wizard-service-item';
@ -1116,8 +1155,8 @@ class WC_Admin_Setup_Wizard {
$previously_saved_settings = get_option( 'woocommerce_' . $item_id . '_settings' ); $previously_saved_settings = get_option( 'woocommerce_' . $item_id . '_settings' );
// Show the user-saved state if it was previously saved // Show the user-saved state if it was previously saved.
// Otherwise, rely on the item info // Otherwise, rely on the item info.
if ( is_array( $previously_saved_settings ) ) { if ( is_array( $previously_saved_settings ) ) {
$should_enable_toggle = 'yes' === $previously_saved_settings['enabled']; $should_enable_toggle = 'yes' === $previously_saved_settings['enabled'];
} else { } else {
@ -1194,10 +1233,22 @@ class WC_Admin_Setup_Wizard {
<?php <?php
} }
/**
* Is it a featured service?
*
* @param array $service Service info array.
* @return boolean
*/
public function is_featured_service( $service ) { public function is_featured_service( $service ) {
return ! empty( $service['featured'] ); return ! empty( $service['featured'] );
} }
/**
* Is this a non featured service?
*
* @param array $service Service info array.
* @return boolean
*/
public function is_not_featured_service( $service ) { public function is_not_featured_service( $service ) {
return ! $this->is_featured_service( $service ); return ! $this->is_featured_service( $service );
} }
@ -1213,8 +1264,10 @@ class WC_Admin_Setup_Wizard {
<h1><?php esc_html_e( 'Payment', 'woocommerce' ); ?></h1> <h1><?php esc_html_e( 'Payment', 'woocommerce' ); ?></h1>
<form method="post" class="wc-wizard-payment-gateway-form"> <form method="post" class="wc-wizard-payment-gateway-form">
<p> <p>
<?php printf( __( <?php printf(
'WooCommerce can accept both online and offline payments. <a href="%1$s" target="_blank">Additional payment methods</a> can be installed later.', 'woocommerce' ), esc_html__(
'WooCommerce can accept both online and offline payments. <a href="%1$s" target="_blank">Additional payment methods</a> can be installed later.', 'woocommerce'
),
esc_url( admin_url( 'admin.php?page=wc-addons&view=payment-gateways' ) ) esc_url( admin_url( 'admin.php?page=wc-addons&view=payment-gateways' ) )
); ?> ); ?>
</p> </p>
@ -1250,7 +1303,7 @@ class WC_Admin_Setup_Wizard {
endforeach; ?> endforeach; ?>
</ul> </ul>
<p class="wc-setup-actions step"> <p class="wc-setup-actions step">
<input type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step" /> <button type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step"><?php esc_html_e( 'Continue', 'woocommerce' ); ?></button>
<?php wp_nonce_field( 'wc-setup' ); ?> <?php wp_nonce_field( 'wc-setup' ); ?>
</p> </p>
</form> </form>
@ -1283,13 +1336,15 @@ class WC_Admin_Setup_Wizard {
$settings = array_filter( (array) get_option( $settings_key, array() ) ); $settings = array_filter( (array) get_option( $settings_key, array() ) );
$settings['enabled'] = ! empty( $_POST[ 'wc-wizard-service-' . $gateway_id . '-enabled' ] ) ? 'yes' : 'no'; $settings['enabled'] = ! empty( $_POST[ 'wc-wizard-service-' . $gateway_id . '-enabled' ] ) ? 'yes' : 'no';
// @codingStandardsIgnoreStart
if ( ! empty( $gateway['settings'] ) ) { if ( ! empty( $gateway['settings'] ) ) {
foreach ( $gateway['settings'] as $setting_id => $setting ) { foreach ( $gateway['settings'] as $setting_id => $setting ) {
$settings[ $setting_id ] = 'yes' === $settings['enabled'] $settings[ $setting_id ] = 'yes' === $settings['enabled']
? wc_clean( $_POST[ $gateway_id . '_' . $setting_id ] ) ? wc_clean( wp_unslash( $_POST[ $gateway_id . '_' . $setting_id ] ) )
: false; : false;
} }
} }
// @codingStandardsIgnoreSEnd
update_option( $settings_key, $settings ); update_option( $settings_key, $settings );
} }
@ -1360,7 +1415,7 @@ class WC_Admin_Setup_Wizard {
</ul> </ul>
<?php endif; ?> <?php endif; ?>
<p class="wc-setup-actions step"> <p class="wc-setup-actions step">
<input type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step" /> <button type="submit" class="button-primary button button-large button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step"><?php esc_html_e( 'Continue', 'woocommerce' ); ?></button>
<?php wp_nonce_field( 'wc-setup' ); ?> <?php wp_nonce_field( 'wc-setup' ); ?>
</p> </p>
</form> </form>
@ -1488,7 +1543,7 @@ class WC_Admin_Setup_Wizard {
</p> </p>
<form method="post" class="activate-jetpack"> <form method="post" class="activate-jetpack">
<p class="wc-setup-actions step"> <p class="wc-setup-actions step">
<input type="submit" class="button-primary button button-large" value="<?php esc_attr_e( 'Connect with Jetpack', 'woocommerce' ); ?>" /> <button type="submit" class="button-primary button button-large" value="<?php esc_attr_e( 'Connect with Jetpack', 'woocommerce' ); ?>"><?php esc_html_e( 'Continue with Jetpack', 'woocommerce' ); ?></button>
</p> </p>
<input type="hidden" name="save_step" value="activate" /> <input type="hidden" name="save_step" value="activate" />
<?php wp_nonce_field( 'wc-setup' ); ?> <?php wp_nonce_field( 'wc-setup' ); ?>
@ -1623,13 +1678,13 @@ class WC_Admin_Setup_Wizard {
required required
> >
<p class="wc-setup-actions step newsletter-form-button-container"> <p class="wc-setup-actions step newsletter-form-button-container">
<input <button
type="submit" type="submit"
value="<?php esc_html_e( 'Yes please!', 'woocommerce' ); ?>" value="<?php esc_html_e( 'Yes please!', 'woocommerce' ); ?>"
name="subscribe" name="subscribe"
id="mc-embedded-subscribe" id="mc-embedded-subscribe"
class="button-primary button newsletter-form-button" class="button-primary button newsletter-form-button"
> ><?php esc_html_e( 'Yes please!', 'woocommerce' ); ?></button>
</p> </p>
</div> </div>
</form> </form>

View File

@ -1,4 +1,13 @@
<?php <?php
/**
* Tax importer class file
*
* @version 2.3.0
* @category Admin
* @package WooCommerce/Admin
* @author WooCommerce
*/
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
@ -50,6 +59,7 @@ class WC_Tax_Rate_Importer extends WP_Importer {
*/ */
public function __construct() { public function __construct() {
$this->import_page = 'woocommerce_tax_rate_csv'; $this->import_page = 'woocommerce_tax_rate_csv';
// @codingStandardsIgnoreLine
$this->delimiter = empty( $_POST['delimiter'] ) ? ',' : (string) wc_clean( $_POST['delimiter'] ); $this->delimiter = empty( $_POST['delimiter'] ) ? ',' : (string) wc_clean( $_POST['delimiter'] );
} }
@ -107,8 +117,8 @@ class WC_Tax_Rate_Importer extends WP_Importer {
/** /**
* UTF-8 encode the data if `$enc` value isn't UTF-8. * UTF-8 encode the data if `$enc` value isn't UTF-8.
* *
* @param mixed $data * @param mixed $data Data.
* @param string $enc * @param string $enc Encoding.
* @return string * @return string
*/ */
public function format_data_from_csv( $data, $enc ) { public function format_data_from_csv( $data, $enc ) {
@ -118,7 +128,7 @@ class WC_Tax_Rate_Importer extends WP_Importer {
/** /**
* Import the file if it exists and is valid. * Import the file if it exists and is valid.
* *
* @param mixed $file * @param mixed $file File.
*/ */
public function import( $file ) { public function import( $file ) {
if ( ! is_file( $file ) ) { if ( ! is_file( $file ) ) {
@ -129,11 +139,11 @@ class WC_Tax_Rate_Importer extends WP_Importer {
$loop = 0; $loop = 0;
if ( ( $handle = fopen( $file, "r" ) ) !== false ) { if ( ( $handle = fopen( $file, 'r' ) ) !== false ) {
$header = fgetcsv( $handle, 0, $this->delimiter ); $header = fgetcsv( $handle, 0, $this->delimiter );
if ( 10 === sizeof( $header ) ) { if ( 10 === count( $header ) ) {
while ( ( $row = fgetcsv( $handle, 0, $this->delimiter ) ) !== false ) { while ( ( $row = fgetcsv( $handle, 0, $this->delimiter ) ) !== false ) {
@ -162,12 +172,12 @@ class WC_Tax_Rate_Importer extends WP_Importer {
fclose( $handle ); fclose( $handle );
} }
// Show Result // Show Result.
echo '<div class="updated settings-error"><p>'; echo '<div class="updated settings-error"><p>';
/* translators: %s: tax rates count */ /* translators: %s: tax rates count */
printf( printf(
__( 'Import complete - imported %s tax rates.', 'woocommerce' ), esc_html__( 'Import complete - imported %s tax rates.', 'woocommerce' ),
'<strong>' . $loop . '</strong>' '<strong>' . absint( $loop ) . '</strong>'
); );
echo '</p></div>'; echo '</p></div>';
@ -178,7 +188,7 @@ class WC_Tax_Rate_Importer extends WP_Importer {
* Performs post-import cleanup of files and the cache. * Performs post-import cleanup of files and the cache.
*/ */
public function import_end() { public function import_end() {
echo '<p>' . __( 'All done!', 'woocommerce' ) . ' <a href="' . admin_url( 'admin.php?page=wc-settings&tab=tax' ) . '">' . __( 'View tax rates', 'woocommerce' ) . '</a>' . '</p>'; echo '<p>' . esc_html__( 'All done!', 'woocommerce' ) . ' <a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=tax' ) ) . '">' . esc_html__( 'View tax rates', 'woocommerce' ) . '</a></p>';
do_action( 'import_end' ); do_action( 'import_end' );
} }
@ -190,6 +200,7 @@ class WC_Tax_Rate_Importer extends WP_Importer {
* @return bool False if error uploading or invalid file, true otherwise * @return bool False if error uploading or invalid file, true otherwise
*/ */
public function handle_upload() { public function handle_upload() {
// @codingStandardsIgnoreLine
if ( empty( $_POST['file_url'] ) ) { if ( empty( $_POST['file_url'] ) ) {
$file = wp_import_handle_upload(); $file = wp_import_handle_upload();
@ -199,8 +210,9 @@ class WC_Tax_Rate_Importer extends WP_Importer {
} }
$this->id = absint( $file['id'] ); $this->id = absint( $file['id'] );
// @codingStandardsIgnoreLine
} elseif ( file_exists( ABSPATH . $_POST['file_url'] ) ) { } elseif ( file_exists( ABSPATH . $_POST['file_url'] ) ) {
// @codingStandardsIgnoreLine
$this->file_url = esc_attr( $_POST['file_url'] ); $this->file_url = esc_attr( $_POST['file_url'] );
} else { } else {
$this->import_error(); $this->import_error();
@ -214,7 +226,7 @@ class WC_Tax_Rate_Importer extends WP_Importer {
*/ */
public function header() { public function header() {
echo '<div class="wrap">'; echo '<div class="wrap">';
echo '<h1>' . __( 'Import tax rates', 'woocommerce' ) . '</h1>'; echo '<h1>' . esc_html__( 'Import tax rates', 'woocommerce' ) . '</h1>';
} }
/** /**
@ -230,9 +242,9 @@ class WC_Tax_Rate_Importer extends WP_Importer {
public function greet() { public function greet() {
echo '<div class="narrow">'; echo '<div class="narrow">';
echo '<p>' . __( 'Hi there! Upload a CSV file containing tax rates to import the contents into your shop. Choose a .csv file to upload, then click "Upload file and import".', 'woocommerce' ) . '</p>'; echo '<p>' . esc_html__( 'Hi there! Upload a CSV file containing tax rates to import the contents into your shop. Choose a .csv file to upload, then click "Upload file and import".', 'woocommerce' ) . '</p>';
echo '<p>' . sprintf( __( 'Tax rates need to be defined with columns in a specific order (10 columns). <a href="%s">Click here to download a sample</a>.', 'woocommerce' ), WC()->plugin_url() . '/dummy-data/sample_tax_rates.csv' ) . '</p>'; echo '<p>' . sprintf( esc_html__( 'Tax rates need to be defined with columns in a specific order (10 columns). <a href="%s">Click here to download a sample</a>.', 'woocommerce' ), esc_url( WC()->plugin_url() ) . '/dummy-data/sample_tax_rates.csv' ) . '</p>';
$action = 'admin.php?import=woocommerce_tax_rate_csv&step=1'; $action = 'admin.php?import=woocommerce_tax_rate_csv&step=1';
@ -240,8 +252,8 @@ class WC_Tax_Rate_Importer extends WP_Importer {
$size = size_format( $bytes ); $size = size_format( $bytes );
$upload_dir = wp_upload_dir(); $upload_dir = wp_upload_dir();
if ( ! empty( $upload_dir['error'] ) ) : if ( ! empty( $upload_dir['error'] ) ) :
?><div class="error"><p><?php _e( 'Before you can upload your import file, you will need to fix the following error:', 'woocommerce' ); ?></p> ?><div class="error"><p><?php esc_html_e( 'Before you can upload your import file, you will need to fix the following error:', 'woocommerce' ); ?></p>
<p><strong><?php echo $upload_dir['error']; ?></strong></p></div><?php <p><strong><?php echo esc_html( $upload_dir['error'] ); ?></strong></p></div><?php
else : else :
?> ?>
<form enctype="multipart/form-data" id="import-upload-form" method="post" action="<?php echo esc_attr( wp_nonce_url( $action, 'import-upload' ) ); ?>"> <form enctype="multipart/form-data" id="import-upload-form" method="post" action="<?php echo esc_attr( wp_nonce_url( $action, 'import-upload' ) ); ?>">
@ -249,37 +261,39 @@ class WC_Tax_Rate_Importer extends WP_Importer {
<tbody> <tbody>
<tr> <tr>
<th> <th>
<label for="upload"><?php _e( 'Choose a file from your computer:', 'woocommerce' ); ?></label> <label for="upload"><?php esc_html_e( 'Choose a file from your computer:', 'woocommerce' ); ?></label>
</th> </th>
<td> <td>
<input type="file" id="upload" name="import" size="25" /> <input type="file" id="upload" name="import" size="25" />
<input type="hidden" name="action" value="save" /> <input type="hidden" name="action" value="save" />
<input type="hidden" name="max_file_size" value="<?php echo $bytes; ?>" /> <input type="hidden" name="max_file_size" value="<?php echo absint( $bytes ); ?>" />
<small><?php <small>
<?php
/* translators: %s: maximum upload size */ /* translators: %s: maximum upload size */
printf( printf(
__( 'Maximum size: %s', 'woocommerce' ), esc_html__( 'Maximum size: %s', 'woocommerce' ),
$size esc_attr( $size )
); );
?></small> ?>
</small>
</td> </td>
</tr> </tr>
<tr> <tr>
<th> <th>
<label for="file_url"><?php _e( 'OR enter path to file:', 'woocommerce' ); ?></label> <label for="file_url"><?php esc_html_e( 'OR enter path to file:', 'woocommerce' ); ?></label>
</th> </th>
<td> <td>
<?php echo ' ' . ABSPATH . ' '; ?><input type="text" id="file_url" name="file_url" size="25" /> <?php echo ' ' . esc_html( ABSPATH ) . ' '; ?><input type="text" id="file_url" name="file_url" size="25" />
</td> </td>
</tr> </tr>
<tr> <tr>
<th><label><?php _e( 'Delimiter', 'woocommerce' ); ?></label><br/></th> <th><label><?php esc_html_e( 'Delimiter', 'woocommerce' ); ?></label><br/></th>
<td><input type="text" name="delimiter" placeholder="," size="2" /></td> <td><input type="text" name="delimiter" placeholder="," size="2" /></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<p class="submit"> <p class="submit">
<input type="submit" class="button" value="<?php esc_attr_e( 'Upload file and import', 'woocommerce' ); ?>" /> <button type="submit" class="button" value="<?php esc_attr_e( 'Upload file and import', 'woocommerce' ); ?>"><?php esc_html_e( 'Upload file and import', 'woocommerce' ); ?></button>
</p> </p>
</form> </form>
<?php <?php
@ -290,10 +304,11 @@ class WC_Tax_Rate_Importer extends WP_Importer {
/** /**
* Show import error and quit. * Show import error and quit.
* @param string $message *
* @param string $message Error messag.
*/ */
private function import_error( $message = '' ) { private function import_error( $message = '' ) {
echo '<p><strong>' . __( 'Sorry, there has been an error.', 'woocommerce' ) . '</strong><br />'; echo '<p><strong>' . esc_html__( 'Sorry, there has been an error.', 'woocommerce' ) . '</strong><br />';
if ( $message ) { if ( $message ) {
echo esc_html( $message ); echo esc_html( $message );
} }
@ -305,7 +320,7 @@ class WC_Tax_Rate_Importer extends WP_Importer {
/** /**
* Added to http_request_timeout filter to force timeout at 60 seconds during import. * Added to http_request_timeout filter to force timeout at 60 seconds during import.
* *
* @param int $val * @param int $val Value.
* @return int 60 * @return int 60
*/ */
public function bump_request_timeout( $val ) { public function bump_request_timeout( $val ) {

View File

@ -1,7 +1,10 @@
<?php <?php
/** /**
* Admin View: Importer - CSV mapping * Admin View: Importer - CSV mapping
*
* @package WooCommerce/Admin
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
@ -15,8 +18,8 @@ if ( ! defined( 'ABSPATH' ) ) {
<table class="widefat wc-importer-mapping-table"> <table class="widefat wc-importer-mapping-table">
<thead> <thead>
<tr> <tr>
<th><?php _e( 'Column name', 'woocommerce' ); ?></th> <th><?php esc_html_e( 'Column name', 'woocommerce' ); ?></th>
<th><?php _e( 'Map to field', 'woocommerce' ); ?></th> <th><?php esc_html_e( 'Map to field', 'woocommerce' ); ?></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -26,7 +29,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<td class="wc-importer-mapping-table-name"> <td class="wc-importer-mapping-table-name">
<?php echo esc_html( $name ); ?> <?php echo esc_html( $name ); ?>
<?php if ( ! empty( $sample[ $index ] ) ) : ?> <?php if ( ! empty( $sample[ $index ] ) ) : ?>
<span class="description"><?php _e( 'Sample:', 'woocommerce' ); ?> <code><?php echo esc_html( $sample[ $index ] ); ?></code></span> <span class="description"><?php esc_html_e( 'Sample:', 'woocommerce' ); ?> <code><?php echo esc_html( $sample[ $index ] ); ?></code></span>
<?php endif; ?> <?php endif; ?>
</td> </td>
<td class="wc-importer-mapping-table-field"> <td class="wc-importer-mapping-table-field">
@ -53,7 +56,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</table> </table>
</section> </section>
<div class="wc-actions"> <div class="wc-actions">
<input type="submit" class="button button-primary button-next" value="<?php esc_attr_e( 'Run the importer', 'woocommerce' ); ?>" name="save_step" /> <button type="submit" class="button button-primary button-next" value="<?php esc_attr_e( 'Run the importer', 'woocommerce' ); ?>" name="save_step"><?php esc_html_e( 'Run the importer', 'woocommerce' ); ?></button>
<input type="hidden" name="file" value="<?php echo esc_attr( $this->file ); ?>" /> <input type="hidden" name="file" value="<?php echo esc_attr( $this->file ); ?>" />
<input type="hidden" name="delimiter" value="<?php echo esc_attr( $this->delimiter ); ?>" /> <input type="hidden" name="delimiter" value="<?php echo esc_attr( $this->delimiter ); ?>" />
<input type="hidden" name="update_existing" value="<?php echo (int) $this->update_existing; ?>" /> <input type="hidden" name="update_existing" value="<?php echo (int) $this->update_existing; ?>" />

View File

@ -1,7 +1,10 @@
<?php <?php
/** /**
* Admin View: Product import form * Admin View: Product import form
*
* @package WooCommerce/Admin
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
@ -17,7 +20,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<tr> <tr>
<th scope="row"> <th scope="row">
<label for="upload"> <label for="upload">
<?php _e( 'Choose a CSV file from your computer:', 'woocommerce' ); ?> <?php esc_html_e( 'Choose a CSV file from your computer:', 'woocommerce' ); ?>
</label> </label>
</th> </th>
<td> <td>
@ -32,20 +35,23 @@ if ( ! defined( 'ABSPATH' ) ) {
<input type="file" id="upload" name="import" size="25" /> <input type="file" id="upload" name="import" size="25" />
<input type="hidden" name="action" value="save" /> <input type="hidden" name="action" value="save" />
<input type="hidden" name="max_file_size" value="<?php echo esc_attr( $bytes ); ?>" /> <input type="hidden" name="max_file_size" value="<?php echo esc_attr( $bytes ); ?>" />
<br><small><?php <br>
<small>
<?php
/* translators: %s: maximum upload size */ /* translators: %s: maximum upload size */
printf( printf(
__( 'Maximum size: %s', 'woocommerce' ), esc_html__( 'Maximum size: %s', 'woocommerce' ),
$size absint( $size )
); );
?></small> ?>
</small>
<?php <?php
} }
?> ?>
</td> </td>
</tr> </tr>
<tr> <tr>
<th><label for="woocommerce-importer-update-existing"><?php _e( 'Update existing products', 'woocommerce' ); ?></label><br/></th> <th><label for="woocommerce-importer-update-existing"><?php esc_html_e( 'Update existing products', 'woocommerce' ); ?></label><br/></th>
<td> <td>
<input type="hidden" name="update_existing" value="0" /> <input type="hidden" name="update_existing" value="0" />
<input type="checkbox" id="woocommerce-importer-update-existing" name="update_existing" value="1" /> <input type="checkbox" id="woocommerce-importer-update-existing" name="update_existing" value="1" />
@ -54,7 +60,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr> </tr>
<tr class="woocommerce-importer-advanced hidden"> <tr class="woocommerce-importer-advanced hidden">
<th> <th>
<label for="woocommerce-importer-file-url"><?php _e( '<em>or</em> enter the path to a CSV file on your server:', 'woocommerce' ); ?></label> <label for="woocommerce-importer-file-url"><?php esc_html_e( '<em>or</em> enter the path to a CSV file on your server:', 'woocommerce' ); ?></label>
</th> </th>
<td> <td>
<label for="woocommerce-importer-file-url" class="woocommerce-importer-file-url-field-wrapper"> <label for="woocommerce-importer-file-url" class="woocommerce-importer-file-url-field-wrapper">
@ -63,7 +69,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</td> </td>
</tr> </tr>
<tr class="woocommerce-importer-advanced hidden"> <tr class="woocommerce-importer-advanced hidden">
<th><label><?php _e( 'CSV Delimiter', 'woocommerce' ); ?></label><br/></th> <th><label><?php esc_html_e( 'CSV Delimiter', 'woocommerce' ); ?></label><br/></th>
<td><input type="text" name="delimiter" placeholder="," size="2" /></td> <td><input type="text" name="delimiter" placeholder="," size="2" /></td>
</tr> </tr>
</tbody> </tbody>
@ -86,7 +92,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</script> </script>
<div class="wc-actions"> <div class="wc-actions">
<a href="#" class="woocommerce-importer-toggle-advanced-options" data-hidetext="<?php esc_html_e( 'Hide advanced options', 'woocommerce' ); ?>" data-showtext="<?php esc_html_e( 'Hide advanced options', 'woocommerce' ); ?>"><?php esc_html_e( 'Show advanced options', 'woocommerce' ); ?></a> <a href="#" class="woocommerce-importer-toggle-advanced-options" data-hidetext="<?php esc_html_e( 'Hide advanced options', 'woocommerce' ); ?>" data-showtext="<?php esc_html_e( 'Hide advanced options', 'woocommerce' ); ?>"><?php esc_html_e( 'Show advanced options', 'woocommerce' ); ?></a>
<input type="submit" class="button button-primary button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step" /> <button type="submit" class="button button-primary button-next" value="<?php esc_attr_e( 'Continue', 'woocommerce' ); ?>" name="save_step"><?php esc_html_e( 'Continue', 'woocommerce' ); ?></button>
<?php wp_nonce_field( 'woocommerce-csv-importer' ); ?> <?php wp_nonce_field( 'woocommerce-csv-importer' ); ?>
</div> </div>
</form> </form>

View File

@ -0,0 +1,278 @@
<?php
/**
* List tables.
*
* @author WooCommerce
* @category Admin
* @package WooCommerce/Admin
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( class_exists( 'WC_Admin_List_Table', false ) ) {
return;
}
/**
* WC_Admin_List_Table Class.
*/
abstract class WC_Admin_List_Table {
/**
* Post type.
*
* @var string
*/
protected $list_table_type = '';
/**
* Object being shown on the row.
*
* @var object|null
*/
protected $object = null;
/**
* Constructor.
*/
public function __construct() {
if ( $this->list_table_type ) {
add_action( 'manage_posts_extra_tablenav', array( $this, 'maybe_render_blank_state' ) );
add_filter( 'view_mode_post_types', array( $this, 'disable_view_mode' ) );
add_action( 'restrict_manage_posts', array( $this, 'restrict_manage_posts' ) );
add_filter( 'request', array( $this, 'request_query' ) );
add_filter( 'post_row_actions', array( $this, 'row_actions' ), 100, 2 );
add_filter( 'default_hidden_columns', array( $this, 'default_hidden_columns' ), 10, 2 );
add_filter( 'list_table_primary_column', array( $this, 'list_table_primary_column' ), 10, 2 );
add_filter( 'manage_edit-' . $this->list_table_type . '_sortable_columns', array( $this, 'define_sortable_columns' ) );
add_filter( 'manage_' . $this->list_table_type . '_posts_columns', array( $this, 'define_columns' ) );
add_filter( 'bulk_actions-edit-' . $this->list_table_type, array( $this, 'define_bulk_actions' ) );
add_action( 'manage_' . $this->list_table_type . '_posts_custom_column', array( $this, 'render_columns' ), 10, 2 );
add_filter( 'handle_bulk_actions-edit-' . $this->list_table_type, array( $this, 'handle_bulk_actions' ), 10, 3 );
}
}
/**
* Show blank slate.
*
* @param string $which String which tablenav is being shown.
*/
public function maybe_render_blank_state( $which ) {
global $post_type;
if ( $post_type === $this->list_table_type && 'bottom' === $which ) {
$counts = (array) wp_count_posts( $post_type );
unset( $counts['auto-draft'] );
$count = array_sum( $counts );
if ( 0 < $count ) {
return;
}
$this->render_blank_state();
echo '<style type="text/css">#posts-filter .wp-list-table, #posts-filter .tablenav.top, .tablenav.bottom .actions, .wrap .subsubsub { display: none; } </style>';
}
}
/**
* Render blank state. Extend to add content.
*/
protected function render_blank_state() {}
/**
* Removes this type from list of post types that support "View Mode" switching.
* View mode is seen on posts where you can switch between list or excerpt. Our post types don't support
* it, so we want to hide the useless UI from the screen options tab.
*
* @param array $post_types Array of post types supporting view mode.
* @return array Array of post types supporting view mode, without this type.
*/
public function disable_view_mode( $post_types ) {
unset( $post_types[ $this->list_table_type ] );
return $post_types;
}
/**
* See if we should render search filters or not.
*/
public function restrict_manage_posts() {
global $typenow;
if ( $this->list_table_type === $typenow ) {
$this->render_filters();
}
}
/**
* Handle any filters.
*
* @param array $query_vars Query vars.
* @return array
*/
public function request_query( $query_vars ) {
global $typenow;
if ( $this->list_table_type === $typenow ) {
return $this->query_filters( $query_vars );
}
return $query_vars;
}
/**
* Render any custom filters and search inputs for the list table.
*/
protected function render_filters() {}
/**
* Handle any custom filters.
*
* @param array $query_vars Query vars.
* @return array
*/
protected function query_filters( $query_vars ) {
return $query_vars;
}
/**
* Set row actions.
*
* @param array $actions Array of actions.
* @param WP_Post $post Current post object.
* @return array
*/
public function row_actions( $actions, $post ) {
if ( $this->list_table_type === $post->post_type ) {
return $this->get_row_actions( $actions, $post );
}
return $actions;
}
/**
* Get row actions to show in the list table.
*
* @param array $actions Array of actions.
* @param WP_Post $post Current post object.
* @return array
*/
protected function get_row_actions( $actions, $post ) {
return $actions;
}
/**
* Adjust which columns are displayed by default.
*
* @param array $hidden Current hidden columns.
* @param object $screen Current screen.
* @return array
*/
public function default_hidden_columns( $hidden, $screen ) {
if ( isset( $screen->id ) && 'edit-' . $this->list_table_type === $screen->id ) {
$hidden = array_merge( $hidden, $this->define_hidden_columns() );
}
return $hidden;
}
/**
* Set list table primary column.
*
* @param string $default Default value.
* @param string $screen_id Current screen ID.
* @return string
*/
public function list_table_primary_column( $default, $screen_id ) {
if ( 'edit-' . $this->list_table_type === $screen_id && $this->get_primary_column() ) {
return $this->get_primary_column();
}
return $default;
}
/**
* Define primary column.
*
* @return array
*/
protected function get_primary_column() {
return '';
}
/**
* Define hidden columns.
*
* @return array
*/
protected function define_hidden_columns() {
return array();
}
/**
* Define which columns are sortable.
*
* @param array $columns Existing columns.
* @return array
*/
public function define_sortable_columns( $columns ) {
return $columns;
}
/**
* Define which columns to show on this screen.
*
* @param array $columns Existing columns.
* @return array
*/
public function define_columns( $columns ) {
return $columns;
}
/**
* Define bulk actions.
*
* @param array $actions Existing actions.
* @return array
*/
public function define_bulk_actions( $actions ) {
return $actions;
}
/**
* Pre-fetch any data for the row each column has access to it.
*
* @param int $post_id Post ID being shown.
*/
protected function prepare_row_data( $post_id ) {}
/**
* Render individual columns.
*
* @param string $column Column ID to render.
* @param int $post_id Post ID being shown.
*/
public function render_columns( $column, $post_id ) {
$this->prepare_row_data( $post_id );
if ( ! $this->object ) {
return;
}
if ( is_callable( array( $this, 'render_' . $column . '_column' ) ) ) {
$this->{"render_{$column}_column"}();
}
}
/**
* Handle bulk actions.
*
* @param string $redirect_to URL to redirect to.
* @param string $action Action name.
* @param array $ids List of ids.
* @return string
*/
public function handle_bulk_actions( $redirect_to, $action, $ids ) {
return esc_url_raw( $redirect_to );
}
}

View File

@ -0,0 +1,237 @@
<?php
/**
* List tables: coupons.
*
* @author WooCommerce
* @category Admin
* @package WooCommerce/Admin
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( class_exists( 'WC_Admin_List_Table_Coupons', false ) ) {
new WC_Admin_List_Table_Coupons();
return;
}
if ( ! class_exists( 'WC_Admin_List_Table', false ) ) {
include_once( 'abstract-class-wc-admin-list-table.php' );
}
/**
* WC_Admin_List_Table_Coupons Class.
*/
class WC_Admin_List_Table_Coupons extends WC_Admin_List_Table {
/**
* Post type.
*
* @var string
*/
protected $list_table_type = 'shop_coupon';
/**
* Constructor.
*/
public function __construct() {
parent::__construct();
add_filter( 'disable_months_dropdown', '__return_true' );
}
/**
* Render blank state.
*/
protected function render_blank_state() {
echo '<div class="woocommerce-BlankState">';
echo '<h2 class="woocommerce-BlankState-message">' . esc_html__( 'Coupons are a great way to offer discounts and rewards to your customers. They will appear here once created.', 'woocommerce' ) . '</h2>';
echo '<a class="woocommerce-BlankState-cta button-primary button" target="_blank" href="https://docs.woocommerce.com/document/coupon-management/?utm_source=blankslate&utm_medium=product&utm_content=couponsdoc&utm_campaign=woocommerceplugin">' . esc_html__( 'Learn more about coupons', 'woocommerce' ) . '</a>';
echo '</div>';
}
/**
* Define primary column.
*
* @return array
*/
protected function get_primary_column() {
return 'coupon_code';
}
/**
* Get row actions to show in the list table.
*
* @param array $actions Array of actions.
* @param WP_Post $post Current post object.
* @return array
*/
protected function get_row_actions( $actions, $post ) {
unset( $actions['inline hide-if-no-js'] );
return $actions;
}
/**
* Define which columns to show on this screen.
*
* @param array $columns Existing columns.
* @return array
*/
public function define_columns( $columns ) {
$show_columns = array();
$show_columns['cb'] = $columns['cb'];
$show_columns['coupon_code'] = __( 'Code', 'woocommerce' );
$show_columns['type'] = __( 'Coupon type', 'woocommerce' );
$show_columns['amount'] = __( 'Coupon amount', 'woocommerce' );
$show_columns['description'] = __( 'Description', 'woocommerce' );
$show_columns['products'] = __( 'Product IDs', 'woocommerce' );
$show_columns['usage'] = __( 'Usage / Limit', 'woocommerce' );
$show_columns['expiry_date'] = __( 'Expiry date', 'woocommerce' );
return $show_columns;
}
/**
* Pre-fetch any data for the row each column has access to it. the_coupon global is there for bw compat.
*
* @param int $post_id Post ID being shown.
*/
protected function prepare_row_data( $post_id ) {
global $the_coupon;
if ( empty( $this->object ) || $this->object->get_id() !== $post_id ) {
$this->object = $the_coupon = new WC_Coupon( $post_id );
}
}
/**
* Render columm: coupon_code.
*/
protected function render_coupon_code_column() {
global $post;
$edit_link = get_edit_post_link( $this->object->get_id() );
$title = $this->object->get_code();
echo '<strong><a class="row-title" href="' . esc_url( $edit_link ) . '">' . esc_html( $title ) . '</a>';
_post_states( $post );
echo '</strong>';
}
/**
* Render columm: type.
*/
protected function render_type_column() {
echo esc_html( wc_get_coupon_type( $this->object->get_discount_type() ) );
}
/**
* Render columm: amount.
*/
protected function render_amount_column() {
echo esc_html( wc_format_localized_price( $this->object->get_amount() ) );
}
/**
* Render columm: products.
*/
protected function render_products_column() {
$product_ids = $this->object->get_product_ids();
if ( count( $product_ids ) > 0 ) {
echo esc_html( implode( ', ', $product_ids ) );
} else {
echo '&ndash;';
}
}
/**
* Render columm: usage_limit.
*/
protected function render_usage_limit_column() {
$usage_limit = $this->object->get_usage_limit();
if ( $usage_limit ) {
echo esc_html( $usage_limit );
} else {
echo '&ndash;';
}
}
/**
* Render columm: usage.
*/
protected function render_usage_column() {
$usage_count = $this->object->get_usage_count();
$usage_limit = $this->object->get_usage_limit();
/* translators: 1: count 2: limit */
printf(
__( '%1$s / %2$s', 'woocommerce' ),
esc_html( $usage_count ),
$usage_limit ? esc_html( $usage_limit ) : '&infin;'
);
}
/**
* Render columm: expiry_date.
*/
protected function render_expiry_date_column() {
$expiry_date = $this->object->get_date_expires();
if ( $expiry_date ) {
echo esc_html( $expiry_date->date_i18n( 'F j, Y' ) );
} else {
echo '&ndash;';
}
}
/**
* Render columm: description.
*/
protected function render_description_column() {
echo wp_kses_post( $this->object->get_description() ? $this->object->get_description() : '&ndash;' );
}
/**
* Render any custom filters and search inputs for the list table.
*/
protected function render_filters() {
?>
<select name="coupon_type" id="dropdown_shop_coupon_type">
<option value=""><?php esc_html_e( 'Show all types', 'woocommerce' ); ?></option>
<?php
$types = wc_get_coupon_types();
foreach ( $types as $name => $type ) {
echo '<option value="' . esc_attr( $name ) . '"';
if ( isset( $_GET['coupon_type'] ) ) { // WPCS: input var ok.
selected( $name, wc_clean( wp_unslash( $_GET['coupon_type'] ) ) ); // WPCS: input var ok, sanitization ok.
}
echo '>' . esc_html( $type ) . '</option>';
}
?>
</select>
<?php
}
/**
* Handle any custom filters.
*
* @param array $query_vars Query vars.
* @return array
*/
protected function query_filters( $query_vars ) {
if ( ! empty( $_GET['coupon_type'] ) ) { // WPCS: input var ok, sanitization ok.
// @codingStandardsIgnoreStart
$query_vars['meta_key'] = 'discount_type';
$query_vars['meta_value'] = wc_clean( wp_unslash( $_GET['coupon_type'] ) ); // WPCS: input var ok, sanitization ok.
// @codingStandardsIgnoreEnd
}
return $query_vars;
}
}
new WC_Admin_List_Table_Coupons();

View File

@ -0,0 +1,611 @@
<?php
/**
* List tables: orders.
*
* @author WooCommerce
* @category Admin
* @package WooCommerce/Admin
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( class_exists( 'WC_Admin_List_Table_Orders', false ) ) {
new WC_Admin_List_Table_Orders();
return;
}
if ( ! class_exists( 'WC_Admin_List_Table', false ) ) {
include_once( 'abstract-class-wc-admin-list-table.php' );
}
/**
* WC_Admin_List_Table_Orders Class.
*/
class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
/**
* Post type.
*
* @var string
*/
protected $list_table_type = 'shop_order';
/**
* Constructor.
*/
public function __construct() {
parent::__construct();
add_action( 'admin_notices', array( $this, 'bulk_admin_notices' ) );
add_action( 'admin_footer', array( $this, 'order_preview_template' ) );
add_filter( 'get_search_query', array( $this, 'search_label' ) );
add_filter( 'query_vars', array( $this, 'add_custom_query_var' ) );
add_action( 'parse_query', array( $this, 'search_custom_fields' ) );
}
/**
* Render blank state.
*/
protected function render_blank_state() {
echo '<div class="woocommerce-BlankState">';
echo '<h2 class="woocommerce-BlankState-message">' . esc_html__( 'When you receive a new order, it will appear here.', 'woocommerce' ) . '</h2>';
echo '<a class="woocommerce-BlankState-cta button-primary button" target="_blank" href="https://docs.woocommerce.com/document/managing-orders/?utm_source=blankslate&utm_medium=product&utm_content=ordersdoc&utm_campaign=woocommerceplugin">' . esc_html__( 'Learn more about orders', 'woocommerce' ) . '</a>';
echo '</div>';
}
/**
* Define primary column.
*
* @return array
*/
protected function get_primary_column() {
return 'order_number';
}
/**
* Get row actions to show in the list table.
*
* @param array $actions Array of actions.
* @param WP_Post $post Current post object.
* @return array
*/
protected function get_row_actions( $actions, $post ) {
return array();
}
/**
* Define hidden columns.
*
* @return array
*/
protected function define_hidden_columns() {
return array(
'shipping_address',
'billing_address',
);
}
/**
* Define which columns are sortable.
*
* @param array $columns Existing columns.
* @return array
*/
public function define_sortable_columns( $columns ) {
$custom = array(
'order_number' => 'ID',
'order_total' => 'order_total',
'order_date' => 'date',
);
unset( $columns['comments'] );
return wp_parse_args( $custom, $columns );
}
/**
* Define which columns to show on this screen.
*
* @param array $columns Existing columns.
* @return array
*/
public function define_columns( $columns ) {
$show_columns = array();
$show_columns['cb'] = $columns['cb'];
$show_columns['order_number'] = __( 'Order', 'woocommerce' );
$show_columns['billing_address'] = __( 'Billing', 'woocommerce' );
$show_columns['shipping_address'] = __( 'Ship to', 'woocommerce' );
$show_columns['order_date'] = __( 'Date', 'woocommerce' );
$show_columns['order_status'] = __( 'Status', 'woocommerce' );
$show_columns['order_total'] = __( 'Total', 'woocommerce' );
if ( has_action( 'woocommerce_admin_order_actions_start' ) || has_action( 'woocommerce_admin_order_actions_end' ) || has_filter( 'woocommerce_admin_order_actions' ) ) {
$show_columns['order_actions'] = __( 'Actions', 'woocommerce' );
}
wp_enqueue_script( 'wc-orders' );
return $show_columns;
}
/**
* Define bulk actions.
*
* @param array $actions Existing actions.
* @return array
*/
public function define_bulk_actions( $actions ) {
if ( isset( $actions['edit'] ) ) {
unset( $actions['edit'] );
}
$actions['mark_processing'] = __( 'Mark processing', 'woocommerce' );
$actions['mark_on-hold'] = __( 'Mark on-hold', 'woocommerce' );
$actions['mark_completed'] = __( 'Mark complete', 'woocommerce' );
return $actions;
}
/**
* Pre-fetch any data for the row each column has access to it. the_order global is there for bw compat.
*
* @param int $post_id Post ID being shown.
*/
protected function prepare_row_data( $post_id ) {
global $the_order;
if ( empty( $this->object ) || $this->object->get_id() !== $post_id ) {
$this->object = $the_order = wc_get_order( $post_id );
}
}
/**
* Render columm: order_number.
*/
protected function render_order_number_column() {
$buyer = '';
if ( $this->object->get_billing_first_name() || $this->object->get_billing_last_name() ) {
/* translators: 1: first name 2: last name */
$buyer = trim( sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $this->object->get_billing_first_name(), $this->object->get_billing_last_name() ) );
} elseif ( $this->object->get_billing_company() ) {
$buyer = trim( $this->object->get_billing_company() );
} elseif ( $this->object->get_customer_id() ) {
$user = get_user_by( 'id', $this->object->get_customer_id() );
$buyer = ucwords( $user->display_name );
}
if ( $this->object->get_status() === 'trash' ) {
echo '<strong>#' . esc_attr( $this->object->get_order_number() ) . ' ' . esc_html( $buyer ) . '</strong>';
} else {
echo '<a href="#" class="order-preview" data-order-id="' . absint( $this->object->get_id() ) . '" title="' . esc_attr( __( 'Preview', 'woocommerce' ) ) . '">' . esc_html( __( 'Preview', 'woocommerce' ) ) . '</a>';
echo '<a href="' . esc_url( admin_url( 'post.php?post=' . absint( $this->object->get_id() ) ) . '&action=edit' ) . '" class="order-view"><strong>#' . esc_attr( $this->object->get_order_number() ) . ' ' . esc_html( $buyer ) . '</strong></a>';
}
}
/**
* Render columm: order_status.
*/
protected function render_order_status_column() {
$tooltip = '';
$comment_count = absint( get_comment_count( $this->object->get_id() )['approved'] );
if ( $comment_count ) {
$latest_notes = wc_get_order_notes( array(
'order_id' => $this->object->get_id(),
'limit' => 1,
'orderby' => 'date_created_gmt',
) );
$latest_note = current( $latest_notes );
if ( isset( $latest_note->content ) && 1 === $comment_count ) {
$tooltip = wc_sanitize_tooltip( $latest_note->content );
} elseif ( isset( $latest_note->content ) ) {
/* translators: %d: notes count */
$tooltip = wc_sanitize_tooltip( $latest_note->content . '<br/><small style="display:block">' . sprintf( _n( 'Plus %d other note', 'Plus %d other notes', ( $comment_count - 1 ), 'woocommerce' ), $comment_count - 1 ) . '</small>' );
} else {
/* translators: %d: notes count */
$tooltip = wc_sanitize_tooltip( sprintf( _n( '%d note', '%d notes', $comment_count, 'woocommerce' ), $comment_count ) );
}
}
if ( $tooltip ) {
printf( '<mark class="order-status %s tips" data-tip="%s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $this->object->get_status() ) ), wp_kses_post( $tooltip ), esc_html( wc_get_order_status_name( $this->object->get_status() ) ) );
} else {
printf( '<mark class="order-status %s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $this->object->get_status() ) ), esc_html( wc_get_order_status_name( $this->object->get_status() ) ) );
}
}
/**
* Render columm: order_date.
*/
protected function render_order_date_column() {
$order_timestamp = $this->object->get_date_created()->getTimestamp();
if ( $order_timestamp > strtotime( '-1 day', current_time( 'timestamp', true ) ) ) {
$show_date = sprintf( _x( '%s ago', '%s = human-readable time difference', 'woocommerce' ), human_time_diff( $this->object->get_date_created()->getTimestamp(), current_time( 'timestamp', true ) ) );
} else {
$show_date = $this->object->get_date_created()->date_i18n( apply_filters( 'woocommerce_admin_order_date_format', get_option( 'date_format' ) ) );
}
printf(
'<time datetime="%1$s" title="%2$s">%3$s</time>',
esc_attr( $this->object->get_date_created()->date( 'c' ) ),
esc_html( $this->object->get_date_created()->date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) ) ),
esc_html( $show_date )
);
}
/**
* Render columm: order_total.
*/
protected function render_order_total_column() {
if ( $this->object->get_payment_method_title() ) {
/* translators: %s: method */
echo '<span class="tips" data-tip="' . esc_attr( sprintf( __( 'via %s', 'woocommerce' ), $this->object->get_payment_method_title() ) ) . '">' . wp_kses_post( $this->object->get_formatted_order_total() ) . '</span>';
} else {
echo wp_kses_post( $this->object->get_formatted_order_total() );
}
}
/**
* Render columm: order_actions.
*/
protected function render_order_actions_column() {
echo '<p>';
do_action( 'woocommerce_admin_order_actions_start', $this->object );
$actions = array();
if ( $this->object->has_status( array( 'pending', 'on-hold' ) ) ) {
$actions['processing'] = array(
'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=processing&order_id=' . $this->object->get_id() ), 'woocommerce-mark-order-status' ),
'name' => __( 'Processing', 'woocommerce' ),
'action' => 'processing',
);
}
if ( $this->object->has_status( array( 'pending', 'on-hold', 'processing' ) ) ) {
$actions['complete'] = array(
'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=completed&order_id=' . $this->object->get_id() ), 'woocommerce-mark-order-status' ),
'name' => __( 'Complete', 'woocommerce' ),
'action' => 'complete',
);
}
$actions = apply_filters( 'woocommerce_admin_order_actions', $actions, $this->object );
foreach ( $actions as $action ) {
printf( '<a class="button tips %s" href="%s" data-tip="%s">%s</a>', esc_attr( $action['action'] ), esc_url( $action['url'] ), esc_attr( $action['name'] ), esc_attr( $action['name'] ) );
}
do_action( 'woocommerce_admin_order_actions_end', $this->object );
echo '</p>';
}
/**
* Render columm: billing_address.
*/
protected function render_billing_address_column() {
if ( $address = $this->object->get_formatted_billing_address() ) {
echo esc_html( preg_replace( '#<br\s*/?>#i', ', ', $address ) );
} else {
echo '&ndash;';
}
}
/**
* Render columm: shipping_address.
*/
protected function render_shipping_address_column() {
if ( $address = $this->object->get_formatted_shipping_address() ) {
echo '<a target="_blank" href="' . esc_url( $this->object->get_shipping_address_map_url() ) . '">' . esc_html( preg_replace( '#<br\s*/?>#i', ', ', $address ) ) . '</a>';
} else {
echo '&ndash;';
}
}
/**
* Template for order preview.
*
* @since 3.3.0
*/
public function order_preview_template() {
?>
<script type="text/template" id="tmpl-wc-modal-view-order">
<div class="wc-backbone-modal wc-order-preview">
<div class="wc-backbone-modal-content">
<section class="wc-backbone-modal-main" role="main">
<header class="wc-backbone-modal-header">
<h1><?php echo esc_html( sprintf( __( 'Order #%s', 'woocommerce' ), '{{ data.order_number }}' ) ); ?></h1>
<button class="modal-close modal-close-link dashicons dashicons-no-alt">
<span class="screen-reader-text"><?php esc_html_e( 'Close modal panel', 'woocommerce' ); ?></span>
</button>
</header>
<article>
{{{ data.item_html }}}
<div class="wc-order-preview-addresses">
<div class="wc-order-preview-address">
<h2><?php esc_html_e( 'Billing details', 'woocommerce' ); ?></h2>
{{{ data.formatted_billing_address }}}
<# if ( data.data.billing.email ) { #>
<strong><?php esc_html_e( 'Email', 'woocommerce' ); ?></strong>
<a href="mailto:{{ data.data.billing.email }}">{{ data.data.billing.email }}</a>
<# } #>
<# if ( data.data.billing.phone ) { #>
<strong><?php esc_html_e( 'Phone', 'woocommerce' ); ?></strong>
<a href="tel:{{ data.data.billing.phone }}">{{ data.data.billing.phone }}</a>
<# } #>
<# if ( data.payment_via ) { #>
<strong><?php esc_html_e( 'Payment via', 'woocommerce' ); ?></strong>
{{ data.payment_via }}
<# } #>
</div>
<# if ( data.needs_shipping ) { #>
<div class="wc-order-preview-address">
<h2><?php esc_html_e( 'Shipping details', 'woocommerce' ); ?></h2>
<# if ( data.ship_to_billing ) { #>
{{{ data.formatted_billing_address }}}
<# } else { #>
<a href="{{ data.shipping_address_map_url }}" target="_blank">{{{ data.formatted_shipping_address }}}</a>
<# } #>
<# if ( data.data.customer_note ) { #>
<strong><?php esc_html_e( 'Note', 'woocommerce' ); ?></strong>
{{ data.data.customer_note }}
<# } #>
<# if ( data.shipping_via ) { #>
<strong><?php esc_html_e( 'Shipping method', 'woocommerce' ); ?></strong>
{{ data.shipping_via }}
<# } #>
</div>
<# } #>
</div>
</article>
<footer>
<div class="inner">
<a class="button button-primary button-large" href="<?php echo esc_url( admin_url( 'post.php?action=edit' ) ); ?>&post={{ data.data.id }}"><?php esc_html_e( 'Edit order', 'woocommerce' ); ?></a>
</div>
</footer>
</section>
</div>
</div>
<div class="wc-backbone-modal-backdrop modal-close"></div>
</script>
<?php
}
/**
* Handle bulk actions.
*
* @param string $redirect_to URL to redirect to.
* @param string $action Action name.
* @param array $ids List of ids.
* @return string
*/
public function handle_bulk_actions( $redirect_to, $action, $ids ) {
// Bail out if this is not a status-changing action.
if ( false === strpos( $action, 'mark_' ) ) {
return $redirect_to;
}
$order_statuses = wc_get_order_statuses();
$new_status = substr( $action, 5 ); // Get the status name from action.
$report_action = 'marked_' . $new_status;
// Sanity check: bail out if this is actually not a status, or is
// not a registered status.
if ( ! isset( $order_statuses[ 'wc-' . $new_status ] ) ) {
return $redirect_to;
}
$changed = 0;
$ids = array_map( 'absint', $ids );
foreach ( $ids as $id ) {
$order = wc_get_order( $id );
$order->update_status( $new_status, __( 'Order status changed by bulk edit:', 'woocommerce' ), true );
do_action( 'woocommerce_order_edit_status', $id, $new_status );
$changed++;
}
$redirect_to = add_query_arg( array(
'post_type' => $this->list_table_type,
$report_action => true,
'changed' => $changed,
'ids' => join( ',', $ids ),
), $redirect_to );
return esc_url_raw( $redirect_to );
}
/**
* Show confirmation message that order status changed for number of orders.
*/
public function bulk_admin_notices() {
global $post_type, $pagenow;
// Bail out if not on shop order list page.
if ( 'edit.php' !== $pagenow || 'shop_order' !== $post_type ) {
return;
}
$order_statuses = wc_get_order_statuses();
// Check if any status changes happened.
foreach ( $order_statuses as $slug => $name ) {
if ( isset( $_REQUEST[ 'marked_' . str_replace( 'wc-', '', $slug ) ] ) ) { // WPCS: input var ok.
$number = isset( $_REQUEST['changed'] ) ? absint( $_REQUEST['changed'] ) : 0; // WPCS: input var ok.
/* translators: %s: orders count */
$message = sprintf( _n( '%d order status changed.', '%d order statuses changed.', $number, 'woocommerce' ), number_format_i18n( $number ) );
echo '<div class="updated"><p>' . esc_html( $message ) . '</p></div>';
break;
}
}
}
/**
* See if we should render search filters or not.
*/
public function restrict_manage_posts() {
global $typenow;
if ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ), true ) ) {
$this->render_filters();
}
}
/**
* Render any custom filters and search inputs for the list table.
*/
protected function render_filters() {
$user_string = '';
$user_id = '';
if ( ! empty( $_GET['_customer_user'] ) ) { // WPCS: input var ok.
$user_id = absint( $_GET['_customer_user'] ); // WPCS: input var ok, sanitization ok.
$user = get_user_by( 'id', $user_id );
/* translators: 1: user display name 2: user ID 3: user email */
$user_string = sprintf(
esc_html__( '%1$s (#%2$s &ndash; %3$s)', 'woocommerce' ),
$user->display_name,
absint( $user->ID ),
$user->user_email
);
}
?>
<select class="wc-customer-search" name="_customer_user" data-placeholder="<?php esc_attr_e( 'Search for a customer&hellip;', 'woocommerce' ); ?>" data-allow_clear="true">
<option value="<?php echo esc_attr( $user_id ); ?>" selected="selected"><?php echo wp_kses_post( $user_string ); ?><option>
</select>
<?php
}
/**
* Handle any filters.
*
* @param array $query_vars Query vars.
* @return array
*/
public function request_query( $query_vars ) {
global $typenow;
if ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ), true ) ) {
return $this->query_filters( $query_vars );
}
return $query_vars;
}
/**
* Handle any custom filters.
*
* @param array $query_vars Query vars.
* @return array
*/
protected function query_filters( $query_vars ) {
global $wp_post_statuses;
// Filter the orders by the posted customer.
if ( ! empty( $_GET['_customer_user'] ) ) { // WPCS: input var ok.
// @codingStandardsIgnoreStart
$query_vars['meta_query'] = array(
array(
'key' => '_customer_user',
'value' => (int) $_GET['_customer_user'], // WPCS: input var ok, sanitization ok.
'compare' => '=',
),
);
// @codingStandardsIgnoreEnd
}
// Sorting.
if ( isset( $query_vars['orderby'] ) ) {
if ( 'order_total' === $query_vars['orderby'] ) {
// @codingStandardsIgnoreStart
$query_vars = array_merge( $query_vars, array(
'meta_key' => '_order_total',
'orderby' => 'meta_value_num',
) );
// @codingStandardsIgnoreEnd
}
}
// Status.
if ( ! isset( $query_vars['post_status'] ) ) {
$post_statuses = wc_get_order_statuses();
foreach ( $post_statuses as $status => $value ) {
if ( isset( $wp_post_statuses[ $status ] ) && false === $wp_post_statuses[ $status ]->show_in_admin_all_list ) {
unset( $post_statuses[ $status ] );
}
}
$query_vars['post_status'] = array_keys( $post_statuses );
}
return $query_vars;
}
/**
* Change the label when searching orders.
*
* @param mixed $query Current search query.
* @return string
*/
public function search_label( $query ) {
global $pagenow, $typenow;
if ( 'edit.php' !== $pagenow || 'shop_order' !== $typenow || ! get_query_var( 'shop_order_search' ) || ! isset( $_GET['s'] ) ) { // WPCS: input var ok.
return $query;
}
return wc_clean( wp_unslash( $_GET['s'] ) ); // WPCS: input var ok, sanitization ok.
}
/**
* Query vars for custom searches.
*
* @param mixed $public_query_vars Array of query vars.
* @return array
*/
public function add_custom_query_var( $public_query_vars ) {
$public_query_vars[] = 'shop_order_search';
return $public_query_vars;
}
/**
* Search custom fields as well as content.
*
* @param WP_Query $wp Query object.
*/
public function search_custom_fields( $wp ) {
global $pagenow;
if ( 'edit.php' !== $pagenow || empty( $wp->query_vars['s'] ) || 'shop_order' !== $wp->query_vars['post_type'] || ! isset( $_GET['s'] ) ) { // WPCS: input var ok.
return;
}
$post_ids = wc_order_search( wc_clean( wp_unslash( $_GET['s'] ) ) ); // WPCS: input var ok, sanitization ok.
if ( ! empty( $post_ids ) ) {
// Remove "s" - we don't want to search order name.
unset( $wp->query_vars['s'] );
// so we know we're doing this.
$wp->query_vars['shop_order_search'] = true;
// Search by found posts.
$wp->query_vars['post__in'] = array_merge( $post_ids, array( 0 ) );
}
}
}
new WC_Admin_List_Table_Orders();

View File

@ -0,0 +1,482 @@
<?php
/**
* List tables: products.
*
* @author WooCommerce
* @category Admin
* @package WooCommerce/Admin
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( class_exists( 'WC_Admin_List_Table_Products', false ) ) {
new WC_Admin_List_Table_Products();
return;
}
if ( ! class_exists( 'WC_Admin_List_Table', false ) ) {
include_once( 'abstract-class-wc-admin-list-table.php' );
}
/**
* WC_Admin_List_Table_Products Class.
*/
class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
/**
* Post type.
*
* @var string
*/
protected $list_table_type = 'product';
/**
* Constructor.
*/
public function __construct() {
parent::__construct();
add_filter( 'disable_months_dropdown', '__return_true' );
add_filter( 'query_vars', array( $this, 'add_custom_query_var' ) );
add_filter( 'posts_search', array( $this, 'sku_search' ) );
add_filter( 'views_edit-product', array( $this, 'product_views' ) );
}
/**
* Render blank state.
*/
protected function render_blank_state() {
echo '<div class="woocommerce-BlankState">';
echo '<h2 class="woocommerce-BlankState-message">' . esc_html__( 'Ready to start selling something awesome?', 'woocommerce' ) . '</h2>';
echo '<a class="woocommerce-BlankState-cta button-primary button" href="' . esc_url( admin_url( 'post-new.php?post_type=product&tutorial=true' ) ) . '">' . esc_html__( 'Create your first product!', 'woocommerce' ) . '</a>';
echo '<a class="woocommerce-BlankState-cta button" href="' . esc_url( admin_url( 'edit.php?post_type=product&page=product_importer' ) ) . '">' . esc_html__( 'Import products from a CSV file', 'woocommerce' ) . '</a>';
echo '</div>';
}
/**
* Define primary column.
*
* @return array
*/
protected function get_primary_column() {
return 'name';
}
/**
* Define which columns are sortable.
*
* @param array $columns Existing columns.
* @return array
*/
public function define_sortable_columns( $columns ) {
$custom = array(
'price' => 'price',
'sku' => 'sku',
'name' => 'title',
);
return wp_parse_args( $custom, $columns );
}
/**
* Define which columns to show on this screen.
*
* @param array $columns Existing columns.
* @return array
*/
public function define_columns( $columns ) {
if ( empty( $columns ) && ! is_array( $columns ) ) {
$columns = array();
}
unset( $columns['title'], $columns['comments'], $columns['date'] );
$show_columns = array();
$show_columns['cb'] = '<input type="checkbox" />';
$show_columns['thumb'] = '<span class="wc-image tips" data-tip="' . esc_attr__( 'Image', 'woocommerce' ) . '">' . __( 'Image', 'woocommerce' ) . '</span>';
$show_columns['name'] = __( 'Name', 'woocommerce' );
if ( wc_product_sku_enabled() ) {
$show_columns['sku'] = __( 'SKU', 'woocommerce' );
}
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
$show_columns['is_in_stock'] = __( 'Stock', 'woocommerce' );
}
$show_columns['price'] = __( 'Price', 'woocommerce' );
$show_columns['product_cat'] = __( 'Categories', 'woocommerce' );
$show_columns['product_tag'] = __( 'Tags', 'woocommerce' );
$show_columns['featured'] = '<span class="wc-featured parent-tips" data-tip="' . esc_attr__( 'Featured', 'woocommerce' ) . '">' . __( 'Featured', 'woocommerce' ) . '</span>';
$show_columns['product_type'] = '<span class="wc-type parent-tips" data-tip="' . esc_attr__( 'Type', 'woocommerce' ) . '">' . __( 'Type', 'woocommerce' ) . '</span>';
$show_columns['date'] = __( 'Date', 'woocommerce' );
return array_merge( $show_columns, $columns );
}
/**
* Pre-fetch any data for the row each column has access to it. the_product global is there for bw compat.
*
* @param int $post_id Post ID being shown.
*/
protected function prepare_row_data( $post_id ) {
global $the_product;
if ( empty( $this->object ) || $this->object->get_id() !== $post_id ) {
$this->object = $the_product = wc_get_product( $post_id );
}
}
/**
* Render columm: thumb.
*/
protected function render_thumb_column() {
echo '<a href="' . esc_url( get_edit_post_link( $this->object->get_id() ) ) . '">' . wp_kses_post( $this->object->get_image( 'thumbnail' ) ) . '</a>';
}
/**
* Render columm: name.
*/
protected function render_name_column() {
global $post;
$edit_link = get_edit_post_link( $this->object->get_id() );
$title = _draft_or_post_title();
echo '<strong><a class="row-title" href="' . esc_url( $edit_link ) . '">' . esc_html( $title ) . '</a>';
_post_states( $post );
echo '</strong>';
if ( $this->object->get_parent_id() > 0 ) {
echo '&nbsp;&nbsp;&larr; <a href="' . esc_url( get_edit_post_link( $this->object->get_parent_id() ) ) . '">' . get_the_title( $this->object->get_parent_id() ) . '</a>';
}
get_inline_data( $post );
/* Custom inline data for woocommerce. */
echo '
<div class="hidden" id="woocommerce_inline_' . absint( $this->object->get_id() ) . '">
<div class="menu_order">' . absint( $this->object->get_menu_order() ) . '</div>
<div class="sku">' . esc_html( $this->object->get_sku() ) . '</div>
<div class="regular_price">' . esc_html( $this->object->get_regular_price() ) . '</div>
<div class="sale_price">' . esc_html( $this->object->get_sale_price() ) . '</div>
<div class="weight">' . esc_html( $this->object->get_weight() ) . '</div>
<div class="length">' . esc_html( $this->object->get_length() ) . '</div>
<div class="width">' . esc_html( $this->object->get_width() ) . '</div>
<div class="height">' . esc_html( $this->object->get_height() ) . '</div>
<div class="shipping_class">' . esc_html( $this->object->get_shipping_class() ) . '</div>
<div class="visibility">' . esc_html( $this->object->get_catalog_visibility() ) . '</div>
<div class="stock_status">' . esc_html( $this->object->get_stock_status() ) . '</div>
<div class="stock">' . esc_html( $this->object->get_stock_quantity() ) . '</div>
<div class="manage_stock">' . esc_html( wc_bool_to_string( $this->object->get_manage_stock() ) ) . '</div>
<div class="featured">' . esc_html( wc_bool_to_string( $this->object->get_featured() ) ) . '</div>
<div class="product_type">' . esc_html( $this->object->get_type() ) . '</div>
<div class="product_is_virtual">' . esc_html( wc_bool_to_string( $this->object->get_virtual() ) ) . '</div>
<div class="tax_status">' . esc_html( $this->object->get_tax_status() ) . '</div>
<div class="tax_class">' . esc_html( $this->object->get_tax_class() ) . '</div>
<div class="backorders">' . esc_html( $this->object->get_backorders() ) . '</div>
</div>
';
}
/**
* Render columm: sku.
*/
protected function render_sku_column() {
echo $this->object->get_sku() ? esc_html( $this->object->get_sku() ) : '<span class="na">&ndash;</span>';
}
/**
* Render columm: product_type.
*/
protected function render_product_type_column() {
if ( $this->object->is_type( 'grouped' ) ) {
echo '<span class="product-type tips grouped" data-tip="' . esc_attr__( 'Grouped', 'woocommerce' ) . '"></span>';
} elseif ( $this->object->is_type( 'external' ) ) {
echo '<span class="product-type tips external" data-tip="' . esc_attr__( 'External/Affiliate', 'woocommerce' ) . '"></span>';
} elseif ( $this->object->is_type( 'simple' ) ) {
if ( $this->object->is_virtual() ) {
echo '<span class="product-type tips virtual" data-tip="' . esc_attr__( 'Virtual', 'woocommerce' ) . '"></span>';
} elseif ( $this->object->is_downloadable() ) {
echo '<span class="product-type tips downloadable" data-tip="' . esc_attr__( 'Downloadable', 'woocommerce' ) . '"></span>';
} else {
echo '<span class="product-type tips simple" data-tip="' . esc_attr__( 'Simple', 'woocommerce' ) . '"></span>';
}
} elseif ( $this->object->is_type( 'variable' ) ) {
echo '<span class="product-type tips variable" data-tip="' . esc_attr__( 'Variable', 'woocommerce' ) . '"></span>';
} else {
// Assuming that we have other types in future.
echo '<span class="product-type tips ' . esc_attr( sanitize_html_class( $this->object->get_type() ) ) . '" data-tip="' . esc_attr( ucfirst( $this->object->get_type() ) ) . '"></span>';
}
}
/**
* Render columm: price.
*/
protected function render_price_column() {
echo $this->object->get_price_html() ? wp_kses_post( $this->object->get_price_html() ) : '<span class="na">&ndash;</span>';
}
/**
* Render columm: product_cat.
*/
protected function render_product_cat_column() {
if ( ! $terms = get_the_terms( $this->object->get_id(), 'product_cat' ) ) {
echo '<span class="na">&ndash;</span>';
} else {
$termlist = array();
foreach ( $terms as $term ) {
$termlist[] = '<a href="' . esc_url( admin_url( 'edit.php?product_cat=' . $term->slug . '&post_type=product' ) ) . ' ">' . esc_html( $term->name ) . '</a>';
}
echo implode( ', ', $termlist ); // WPCS: XSS ok.
}
}
/**
* Render columm: product_tag.
*/
protected function render_product_tag_column() {
if ( ! $terms = get_the_terms( $this->object->get_id(), 'product_tag' ) ) {
echo '<span class="na">&ndash;</span>';
} else {
$termlist = array();
foreach ( $terms as $term ) {
$termlist[] = '<a href="' . esc_url( admin_url( 'edit.php?product_tag=' . $term->slug . '&post_type=product' ) ) . ' ">' . esc_html( $term->name ) . '</a>';
}
echo implode( ', ', $termlist ); // WPCS: XSS ok.
}
}
/**
* Render columm: featured.
*/
protected function render_featured_column() {
$url = wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_feature_product&product_id=' . $this->object->get_id() ), 'woocommerce-feature-product' );
echo '<a href="' . esc_url( $url ) . '" aria-label="' . esc_attr__( 'Toggle featured', 'woocommerce' ) . '">';
if ( $this->object->is_featured() ) {
echo '<span class="wc-featured tips" data-tip="' . esc_attr__( 'Yes', 'woocommerce' ) . '">' . esc_html__( 'Yes', 'woocommerce' ) . '</span>';
} else {
echo '<span class="wc-featured not-featured tips" data-tip="' . esc_attr__( 'No', 'woocommerce' ) . '">' . esc_html__( 'No', 'woocommerce' ) . '</span>';
}
echo '</a>';
}
/**
* Render columm: is_in_stock.
*/
protected function render_is_in_stock_column() {
if ( $this->object->is_in_stock() ) {
$stock_html = '<mark class="instock">' . __( 'In stock', 'woocommerce' ) . '</mark>';
} else {
$stock_html = '<mark class="outofstock">' . __( 'Out of stock', 'woocommerce' ) . '</mark>';
}
if ( $this->object->managing_stock() ) {
$stock_html .= ' (' . wc_stock_amount( $this->object->get_stock_quantity() ) . ')';
}
echo wp_kses_post( apply_filters( 'woocommerce_admin_stock_html', $stock_html, $this->object ) );
}
/**
* Query vars for custom searches.
*
* @param mixed $public_query_vars Array of query vars.
* @return array
*/
public function add_custom_query_var( $public_query_vars ) {
$public_query_vars[] = 'sku';
return $public_query_vars;
}
/**
* Render any custom filters and search inputs for the list table.
*/
protected function render_filters() {
$current_category_slug = isset( $_REQUEST['product_cat'] ) ? wc_clean( wp_unslash( $_REQUEST['product_cat'] ) ) : false; // WPCS: input var ok, sanitization ok.
$current_product_type = isset( $_REQUEST['product_type'] ) ? wc_clean( wp_unslash( $_REQUEST['product_type'] ) ) : false; // WPCS: input var ok, sanitization ok.
// @codingStandardsIgnoreStart
$current_category = $current_category_slug ? get_term_by( 'slug', $current_category_slug, 'product_cat' ): false;
// @codingStandardsIgnoreEnd
?>
<select class="wc-category-search" name="product_cat" data-placeholder="<?php esc_attr_e( 'Filter by category', 'woocommerce' ); ?>" data-allow_clear="true">
<?php if ( $current_category_slug && $current_category ) : ?>
<option value="<?php echo esc_attr( $current_category_slug ); ?>" selected="selected"><?php echo esc_html( $current_category->name ); ?><option>
<?php endif; ?>
</select>
<?php
$terms = get_terms( 'product_type' );
$output = '<select name="product_type" id="dropdown_product_type">';
$output .= '<option value="">' . __( 'Filter by product type', 'woocommerce' ) . '</option>';
foreach ( $terms as $term ) {
$output .= '<option value="' . sanitize_title( $term->name ) . '" ';
$output .= selected( $term->slug, $current_product_type, false );
$output .= '>';
switch ( $term->name ) {
case 'grouped' :
$output .= __( 'Grouped product', 'woocommerce' );
break;
case 'external' :
$output .= __( 'External/Affiliate product', 'woocommerce' );
break;
case 'variable' :
$output .= __( 'Variable product', 'woocommerce' );
break;
case 'simple' :
$output .= __( 'Simple product', 'woocommerce' );
break;
default :
// Assuming that we have other types in future.
$output .= ucfirst( $term->name );
break;
}
$output .= '</option>';
if ( 'simple' === $term->name ) {
$output .= '<option value="downloadable" ';
if ( isset( $wp_query->query['product_type'] ) ) {
$output .= selected( 'downloadable', $current_product_type, false );
}
$output .= '> ' . ( is_rtl() ? '&larr;' : '&rarr;' ) . ' ' . __( 'Downloadable', 'woocommerce' ) . '</option>';
$output .= '<option value="virtual" ';
$output .= selected( 'virtual', $current_product_type, false );
$output .= '> ' . ( is_rtl() ? '&larr;' : '&rarr;' ) . ' ' . __( 'Virtual', 'woocommerce' ) . '</option>';
}
}
$output .= '</select>';
echo apply_filters( 'woocommerce_product_filters', $output ); // WPCS: XSS ok.
}
/**
* Handle any custom filters.
*
* @param array $query_vars Query vars.
* @return array
*/
protected function query_filters( $query_vars ) {
if ( isset( $query_vars['orderby'] ) ) {
if ( 'price' === $vars['orderby'] ) {
// @codingStandardsIgnoreStart
$query_vars = array_merge( $query_vars, array(
'meta_key' => '_price',
'orderby' => 'meta_value_num',
) );
// @codingStandardsIgnoreEnd
}
if ( 'sku' === $query_vars['orderby'] ) {
// @codingStandardsIgnoreStart
$query_vars = array_merge( $query_vars, array(
'meta_key' => '_sku',
'orderby' => 'meta_value',
) );
// @codingStandardsIgnoreEnd
}
}
if ( isset( $query_vars['product_type'] ) ) {
// @codingStandardsIgnoreStart
if ( 'downloadable' === $query_vars['product_type'] ) {
$query_vars['product_type'] = '';
$query_vars['meta_value'] = 'yes';
$query_vars['meta_key'] = '_downloadable';
} elseif ( 'virtual' === $query_vars['product_type'] ) {
$query_vars['product_type'] = '';
$query_vars['meta_value'] = 'yes';
$query_vars['meta_key'] = '_virtual';
}
// @codingStandardsIgnoreEnd
}
if ( isset( $_GET['product_shipping_class'] ) && '0' === $_GET['product_shipping_class'] ) { // WPCS: input var ok.
$query_vars['tax_query'][] = array(
'taxonomy' => 'product_shipping_class',
'field' => 'id',
'terms' => get_terms( 'product_shipping_class', array( 'fields' => 'ids' ) ),
'operator' => 'NOT IN',
);
}
return $query_vars;
}
/**
* Search by SKU or ID for products.
*
* @param string $where Where clause SQL.
* @return string
*/
public function sku_search( $where ) {
global $pagenow, $wpdb, $wp;
if ( 'edit.php' !== $pagenow || ! is_search() || ! isset( $wp->query_vars['s'] ) || 'product' !== $wp->query_vars['post_type'] ) {
return $where;
}
$search_ids = array();
$terms = explode( ',', $wp->query_vars['s'] );
foreach ( $terms as $term ) {
if ( is_numeric( $term ) ) {
$search_ids[] = absint( $term );
} else {
$id_from_sku = wc_get_product_id_by_sku( wc_clean( $term ) );
if ( $id_from_sku ) {
$search_ids[] = absint( $id_from_sku );
}
}
}
$search_ids = array_filter( array_unique( array_map( 'absint', $search_ids ) ) );
if ( count( $search_ids ) > 0 ) {
$where = str_replace( 'AND (((', "AND ( ({$wpdb->posts}.ID IN (" . implode( ',', $search_ids ) . ')) OR ((', $where );
}
return $where;
}
/**
* Change views on the edit product screen.
*
* @param array $views Array of views.
* @return array
*/
public function product_views( $views ) {
global $wp_query;
// Products do not have authors.
unset( $views['mine'] );
// Add sorting link.
if ( current_user_can( 'edit_others_pages' ) ) {
$class = ( isset( $wp_query->query['orderby'] ) && 'menu_order title' === $wp_query->query['orderby'] ) ? 'current' : '';
$query_string = remove_query_arg( array( 'orderby', 'order' ) );
$query_string = add_query_arg( 'orderby', rawurlencode( 'menu_order title' ), $query_string );
$query_string = add_query_arg( 'order', rawurlencode( 'ASC' ), $query_string );
$views['byorder'] = '<a href="' . esc_url( $query_string ) . '" class="' . esc_attr( $class ) . '">' . __( 'Sorting', 'woocommerce' ) . '</a>';
}
return $views;
}
}
new WC_Admin_List_Table_Products();

View File

@ -117,7 +117,7 @@ class WC_Meta_Box_Coupon_Data {
'id' => 'minimum_amount', 'id' => 'minimum_amount',
'label' => __( 'Minimum spend', 'woocommerce' ), 'label' => __( 'Minimum spend', 'woocommerce' ),
'placeholder' => __( 'No minimum', 'woocommerce' ), 'placeholder' => __( 'No minimum', 'woocommerce' ),
'description' => __( 'This field allows you to set the minimum spend (subtotal, including taxes) allowed to use the coupon.', 'woocommerce' ), 'description' => __( 'This field allows you to set the minimum spend (subtotal) allowed to use the coupon.', 'woocommerce' ),
'data_type' => 'price', 'data_type' => 'price',
'desc_tip' => true, 'desc_tip' => true,
) ); ) );
@ -127,7 +127,7 @@ class WC_Meta_Box_Coupon_Data {
'id' => 'maximum_amount', 'id' => 'maximum_amount',
'label' => __( 'Maximum spend', 'woocommerce' ), 'label' => __( 'Maximum spend', 'woocommerce' ),
'placeholder' => __( 'No maximum', 'woocommerce' ), 'placeholder' => __( 'No maximum', 'woocommerce' ),
'description' => __( 'This field allows you to set the maximum spend (subtotal, including taxes) allowed when using the coupon.', 'woocommerce' ), 'description' => __( 'This field allows you to set the maximum spend (subtotal) allowed when using the coupon.', 'woocommerce' ),
'data_type' => 'price', 'data_type' => 'price',
'desc_tip' => true, 'desc_tip' => true,
) ); ) );

View File

@ -11,7 +11,7 @@
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly exit; // Exit if accessed directly.
} }
/** /**
@ -22,7 +22,7 @@ class WC_Meta_Box_Order_Actions {
/** /**
* Output the metabox. * Output the metabox.
* *
* @param WP_Post $post * @param WP_Post $post Post object.
*/ */
public static function output( $post ) { public static function output( $post ) {
global $theorder; global $theorder;
@ -44,17 +44,17 @@ class WC_Meta_Box_Order_Actions {
<li class="wide" id="actions"> <li class="wide" id="actions">
<select name="wc_order_action"> <select name="wc_order_action">
<option value=""><?php _e( 'Choose an action...', 'woocommerce' ); ?></option> <option value=""><?php esc_html_e( 'Choose an action...', 'woocommerce' ); ?></option>
<?php foreach ( $order_actions as $action => $title ) { ?> <?php foreach ( $order_actions as $action => $title ) { ?>
<option value="<?php echo $action; ?>"><?php echo $title; ?></option> <option value="<?php echo esc_attr( $action ); ?>"><?php echo esc_html( $title ); ?></option>
<?php } ?> <?php } ?>
</select> </select>
<button class="button wc-reload"><span><?php _e( 'Apply', 'woocommerce' ); ?></span></button> <button class="button wc-reload"><span><?php esc_html_e( 'Apply', 'woocommerce' ); ?></span></button>
</li> </li>
<li class="wide"> <li class="wide">
<div id="delete-action"><?php <div id="delete-action">
<?php
if ( current_user_can( 'delete_post', $post->ID ) ) { if ( current_user_can( 'delete_post', $post->ID ) ) {
if ( ! EMPTY_TRASH_DAYS ) { if ( ! EMPTY_TRASH_DAYS ) {
@ -62,11 +62,12 @@ class WC_Meta_Box_Order_Actions {
} else { } else {
$delete_text = __( 'Move to trash', 'woocommerce' ); $delete_text = __( 'Move to trash', 'woocommerce' );
} }
?><a class="submitdelete deletion" href="<?php echo esc_url( get_delete_post_link( $post->ID ) ); ?>"><?php echo $delete_text; ?></a><?php ?><a class="submitdelete deletion" href="<?php echo esc_url( get_delete_post_link( $post->ID ) ); ?>"><?php echo esc_html( $delete_text ); ?></a><?php
} }
?></div> ?>
</div>
<input type="submit" class="button save_order button-primary" name="save" value="<?php echo 'auto-draft' === $post->post_status ? esc_attr__( 'Create', 'woocommerce' ) : esc_attr__( 'Update', 'woocommerce' ); ?>" /> <button type="submit" class="button save_order button-primary" name="save" value="<?php echo 'auto-draft' === $post->post_status ? esc_attr__( 'Create', 'woocommerce' ) : esc_attr__( 'Update', 'woocommerce' ); ?>"><?php echo 'auto-draft' === $post->post_status ? esc_html__( 'Create', 'woocommerce' ) : esc_html__( 'Update', 'woocommerce' ); ?></button>
</li> </li>
<?php do_action( 'woocommerce_order_actions_end', $post->ID ); ?> <?php do_action( 'woocommerce_order_actions_end', $post->ID ); ?>
@ -78,17 +79,17 @@ class WC_Meta_Box_Order_Actions {
/** /**
* Save meta box data. * Save meta box data.
* *
* @param int $post_id * @param int $post_id Post ID.
* @param WP_Post $post * @param WP_Post $post Post Object.
*/ */
public static function save( $post_id, $post ) { public static function save( $post_id, $post ) {
// Order data saved, now get it so we can manipulate status. // Order data saved, now get it so we can manipulate status.
$order = wc_get_order( $post_id ); $order = wc_get_order( $post_id );
// Handle button actions // Handle button actions.
if ( ! empty( $_POST['wc_order_action'] ) ) { if ( ! empty( $_POST['wc_order_action'] ) ) { // @codingStandardsIgnoreLine
$action = wc_clean( $_POST['wc_order_action'] ); $action = wc_clean( wp_unslash( $_POST['wc_order_action'] ) ); // @codingStandardsIgnoreLine
if ( 'send_order_details' === $action ) { if ( 'send_order_details' === $action ) {
do_action( 'woocommerce_before_resend_order_emails', $order, 'customer_invoice' ); do_action( 'woocommerce_before_resend_order_emails', $order, 'customer_invoice' );
@ -137,12 +138,9 @@ class WC_Meta_Box_Order_Actions {
/** /**
* Set the correct message ID. * Set the correct message ID.
* *
* @param string $location * @param string $location Location.
*
* @since 2.3.0 * @since 2.3.0
*
* @static * @static
*
* @return string * @return string
*/ */
public static function set_email_sent_message( $location ) { public static function set_email_sent_message( $location ) {

View File

@ -191,7 +191,7 @@ class WC_Meta_Box_Product_Data {
$downloads[] = array( $downloads[] = array(
'name' => wc_clean( $file_names[ $i ] ), 'name' => wc_clean( $file_names[ $i ] ),
'file' => wp_unslash( trim( $file_urls[ $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> <tbody>
<tr> <tr>
<td> <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="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' ); ?>" /> <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>
<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])' ) ); ?>" /> <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>
<td> <td>
<label><?php _e( 'Customer download link', 'woocommerce' ); ?></label> <label><?php esc_html_e( 'Customer download link', 'woocommerce' ); ?></label>
<?php <?php
$download_link = add_query_arg( array( $download_link = add_query_arg( array(
'download_file' => $download->get_product_id(), '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>'; echo '<a href="' . esc_url( $download_link ) . '">' . esc_html( $file_count ) . '</a>';
?> ?>
</td> </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> </tr>
</tbody> </tbody>
</table> </table>

View File

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

View File

@ -1,7 +1,12 @@
<?php <?php
/**
* Coupon usage report functionality
*
* @package WooCommerce/Admin/Reports
*/
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly exit; // Exit if accessed directly.
} }
/** /**
@ -33,9 +38,9 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
*/ */
public function __construct() { public function __construct() {
if ( isset( $_GET['coupon_codes'] ) && is_array( $_GET['coupon_codes'] ) ) { if ( isset( $_GET['coupon_codes'] ) && is_array( $_GET['coupon_codes'] ) ) {
$this->coupon_codes = array_filter( array_map( 'sanitize_text_field', $_GET['coupon_codes'] ) ); $this->coupon_codes = array_filter( array_map( 'sanitize_text_field', wp_unslash( $_GET['coupon_codes'] ) ) );
} elseif ( isset( $_GET['coupon_codes'] ) ) { } elseif ( isset( $_GET['coupon_codes'] ) ) {
$this->coupon_codes = array_filter( array( sanitize_text_field( $_GET['coupon_codes'] ) ) ); $this->coupon_codes = array_filter( array( sanitize_text_field( wp_unslash( $_GET['coupon_codes'] ) ) ) );
} }
} }
@ -138,7 +143,7 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
'coupon_count' => '#d4d9dc', 'coupon_count' => '#d4d9dc',
); );
$current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day'; $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( wp_unslash( $_GET['range'] ) ) : '7day';
if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ) ) ) { if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ) ) ) {
$current_range = '7day'; $current_range = '7day';
@ -171,56 +176,58 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
*/ */
public function coupons_widget() { public function coupons_widget() {
?> ?>
<h4 class="section_title"><span><?php _e( 'Filter by coupon', 'woocommerce' ); ?></span></h4> <h4 class="section_title"><span><?php esc_html_e( 'Filter by coupon', 'woocommerce' ); ?></span></h4>
<div class="section"> <div class="section">
<form method="GET"> <form method="GET">
<div> <div>
<?php <?php
$used_coupons = $this->get_order_report_data( array( $used_coupons = $this->get_order_report_data( array(
'data' => array( 'data' => array(
'order_item_name' => array( 'order_item_name' => array(
'type' => 'order_item', 'type' => 'order_item',
'order_item_type' => 'coupon', 'order_item_type' => 'coupon',
'function' => '', 'function' => '',
'distinct' => true, 'distinct' => true,
'name' => 'order_item_name', 'name' => 'order_item_name',
),
), ),
'where' => array( ),
array( 'where' => array(
'key' => 'order_item_type', array(
'value' => 'coupon', 'key' => 'order_item_type',
'operator' => '=', 'value' => 'coupon',
), 'operator' => '=',
), ),
'query_type' => 'get_col', ),
'filter_range' => false, 'query_type' => 'get_col',
) ); 'filter_range' => false,
) );
if ( ! empty( $used_coupons ) && is_array( $used_coupons ) ) : if ( ! empty( $used_coupons ) && is_array( $used_coupons ) ) :
?> ?>
<select id="coupon_codes" name="coupon_codes" class="wc-enhanced-select" data-placeholder="<?php esc_attr_e( 'Choose coupons&hellip;', 'woocommerce' ); ?>" style="width:100%;"> <select id="coupon_codes" name="coupon_codes" class="wc-enhanced-select" data-placeholder="<?php esc_attr_e( 'Choose coupons&hellip;', 'woocommerce' ); ?>" style="width:100%;">
<option value=""><?php _e( 'All coupons', 'woocommerce' ); ?></option> <option value=""><?php esc_html_e( 'All coupons', 'woocommerce' ); ?></option>
<?php <?php
foreach ( $used_coupons as $coupon ) { foreach ( $used_coupons as $coupon ) {
echo '<option value="' . esc_attr( $coupon ) . '" ' . selected( in_array( $coupon, $this->coupon_codes ), true, false ) . '>' . $coupon . '</option>'; echo '<option value="' . esc_attr( $coupon ) . '" ' . selected( in_array( $coupon, $this->coupon_codes ), true, false ) . '>' . esc_html( $coupon ) . '</option>';
} }
?> ?>
</select> </select>
<input type="submit" class="submit button" value="<?php esc_attr_e( 'Show', 'woocommerce' ); ?>" /> <?php // @codingStandardsIgnoreStart ?>
<input type="hidden" name="range" value="<?php echo ( ! empty( $_GET['range'] ) ) ? esc_attr( $_GET['range'] ) : ''; ?>" /> <button type="submit" class="submit button" value="<?php esc_attr_e( 'Show', 'woocommerce' ); ?>"><?php esc_html_e( 'Show', 'woocommerce' ); ?></button>
<input type="hidden" name="start_date" value="<?php echo ( ! empty( $_GET['start_date'] ) ) ? esc_attr( $_GET['start_date'] ) : ''; ?>" /> <input type="hidden" name="range" value="<?php echo ( ! empty( $_GET['range'] ) ) ? esc_attr( wp_unslash( $_GET['range'] ) ) : ''; ?>" />
<input type="hidden" name="end_date" value="<?php echo ( ! empty( $_GET['end_date'] ) ) ? esc_attr( $_GET['end_date'] ) : ''; ?>" /> <input type="hidden" name="start_date" value="<?php echo ( ! empty( $_GET['start_date'] ) ) ? esc_attr( wp_unslash( $_GET['start_date'] ) ) : ''; ?>" />
<input type="hidden" name="page" value="<?php echo ( ! empty( $_GET['page'] ) ) ? esc_attr( $_GET['page'] ) : ''; ?>" /> <input type="hidden" name="end_date" value="<?php echo ( ! empty( $_GET['end_date'] ) ) ? esc_attr( wp_unslash( $_GET['end_date'] ) ) : ''; ?>" />
<input type="hidden" name="tab" value="<?php echo ( ! empty( $_GET['tab'] ) ) ? esc_attr( $_GET['tab'] ) : ''; ?>" /> <input type="hidden" name="page" value="<?php echo ( ! empty( $_GET['page'] ) ) ? esc_attr( wp_unslash( $_GET['page'] ) ) : ''; ?>" />
<input type="hidden" name="report" value="<?php echo ( ! empty( $_GET['report'] ) ) ? esc_attr( $_GET['report'] ) : ''; ?>" /> <input type="hidden" name="tab" value="<?php echo ( ! empty( $_GET['tab'] ) ) ? esc_attr( wp_unslash( $_GET['tab'] ) ) : ''; ?>" />
<input type="hidden" name="report" value="<?php echo ( ! empty( $_GET['report'] ) ) ? esc_attr( wp_unslash( $_GET['report'] ) ) : ''; ?>" />
<?php // @codingStandardsIgnoreEnd ?>
<?php else : ?> <?php else : ?>
<span><?php _e( 'No used coupons found', 'woocommerce' ); ?></span> <span><?php esc_html_e( 'No used coupons found', 'woocommerce' ); ?></span>
<?php endif; ?> <?php endif; ?>
</div> </div>
</form> </form>
</div> </div>
<h4 class="section_title"><span><?php _e( 'Most popular', 'woocommerce' ); ?></span></h4> <h4 class="section_title"><span><?php esc_html_e( 'Most popular', 'woocommerce' ); ?></span></h4>
<div class="section"> <div class="section">
<table cellspacing="0"> <table cellspacing="0">
<?php <?php
@ -257,17 +264,17 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
if ( ! empty( $most_popular ) && is_array( $most_popular ) ) { if ( ! empty( $most_popular ) && is_array( $most_popular ) ) {
foreach ( $most_popular as $coupon ) { foreach ( $most_popular as $coupon ) {
echo '<tr class="' . ( in_array( $coupon->coupon_code, $this->coupon_codes ) ? 'active' : '' ) . '"> echo '<tr class="' . ( in_array( $coupon->coupon_code, $this->coupon_codes ) ? 'active' : '' ) . '">
<td class="count" width="1%">' . $coupon->coupon_count . '</td> <td class="count" width="1%">' . esc_html( $coupon->coupon_count ) . '</td>
<td class="name"><a href="' . esc_url( add_query_arg( 'coupon_codes', $coupon->coupon_code ) ) . '">' . $coupon->coupon_code . '</a></td> <td class="name"><a href="' . esc_url( add_query_arg( 'coupon_codes', $coupon->coupon_code ) ) . '">' . esc_html( $coupon->coupon_code ) . '</a></td>
</tr>'; </tr>';
} }
} else { } else {
echo '<tr><td colspan="2">' . __( 'No coupons found in range', 'woocommerce' ) . '</td></tr>'; echo '<tr><td colspan="2">' . esc_html__( 'No coupons found in range', 'woocommerce' ) . '</td></tr>';
} }
?> ?>
</table> </table>
</div> </div>
<h4 class="section_title"><span><?php _e( 'Most discount', 'woocommerce' ); ?></span></h4> <h4 class="section_title"><span><?php esc_html_e( 'Most discount', 'woocommerce' ); ?></span></h4>
<div class="section"> <div class="section">
<table cellspacing="0"> <table cellspacing="0">
<?php <?php
@ -303,13 +310,15 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
if ( ! empty( $most_discount ) && is_array( $most_discount ) ) { if ( ! empty( $most_discount ) && is_array( $most_discount ) ) {
foreach ( $most_discount as $coupon ) { foreach ( $most_discount as $coupon ) {
// @codingStandardsIgnoreStart
echo '<tr class="' . ( in_array( $coupon->coupon_code, $this->coupon_codes ) ? 'active' : '' ) . '"> echo '<tr class="' . ( in_array( $coupon->coupon_code, $this->coupon_codes ) ? 'active' : '' ) . '">
<td class="count" width="1%">' . wc_price( $coupon->discount_amount ) . '</td> <td class="count" width="1%">' . wc_price( $coupon->discount_amount ) . '</td>
<td class="name"><a href="' . esc_url( add_query_arg( 'coupon_codes', $coupon->coupon_code ) ) . '">' . $coupon->coupon_code . '</a></td> <td class="name"><a href="' . esc_url( add_query_arg( 'coupon_codes', $coupon->coupon_code ) ) . '">' . esc_html( $coupon->coupon_code ) . '</a></td>
</tr>'; </tr>';
// @codingStandardsIgnoreEnd
} }
} else { } else {
echo '<tr><td colspan="3">' . __( 'No coupons found in range', 'woocommerce' ) . '</td></tr>'; echo '<tr><td colspan="3">' . esc_html__( 'No coupons found in range', 'woocommerce' ) . '</td></tr>';
} }
?> ?>
</table> </table>
@ -342,17 +351,17 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
* Output an export link. * Output an export link.
*/ */
public function get_export_button() { public function get_export_button() {
$current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day'; $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( wp_unslash( $_GET['range'] ) ) : '7day';
?> ?>
<a <a
href="#" href="#"
download="report-<?php echo esc_attr( $current_range ); ?>-<?php echo date_i18n( 'Y-m-d', current_time( 'timestamp' ) ); ?>.csv" download="report-<?php echo esc_attr( $current_range ); ?>-<?php echo esc_attr( date_i18n( 'Y-m-d', current_time( 'timestamp' ) ) ); ?>.csv"
class="export_csv" class="export_csv"
data-export="chart" data-export="chart"
data-xaxes="<?php esc_attr_e( 'Date', 'woocommerce' ); ?>" data-xaxes="<?php esc_attr_e( 'Date', 'woocommerce' ); ?>"
data-groupby="<?php echo $this->chart_groupby; ?>" data-groupby="<?php echo esc_attr( $this->chart_groupby ); ?>"
> >
<?php _e( 'Export CSV', 'woocommerce' ); ?> <?php esc_html_e( 'Export CSV', 'woocommerce' ); ?>
</a> </a>
<?php <?php
} }
@ -363,7 +372,7 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
public function get_main_chart() { public function get_main_chart() {
global $wp_locale; global $wp_locale;
// Get orders and dates in range - we want the SUM of order totals, COUNT of order items, COUNT of orders, and the date // Get orders and dates in range - we want the SUM of order totals, COUNT of order items, COUNT of orders, and the date.
$order_coupon_counts_query = array( $order_coupon_counts_query = array(
'data' => array( 'data' => array(
'order_item_name' => array( 'order_item_name' => array(
@ -435,11 +444,11 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
$order_coupon_counts = $this->get_order_report_data( $order_coupon_counts_query ); $order_coupon_counts = $this->get_order_report_data( $order_coupon_counts_query );
$order_discount_amounts = $this->get_order_report_data( $order_discount_amounts_query ); $order_discount_amounts = $this->get_order_report_data( $order_discount_amounts_query );
// Prepare data for report // Prepare data for report.
$order_coupon_counts = $this->prepare_chart_data( $order_coupon_counts, 'post_date', 'order_coupon_count' , $this->chart_interval, $this->start_date, $this->chart_groupby ); $order_coupon_counts = $this->prepare_chart_data( $order_coupon_counts, 'post_date', 'order_coupon_count' , $this->chart_interval, $this->start_date, $this->chart_groupby );
$order_discount_amounts = $this->prepare_chart_data( $order_discount_amounts, 'post_date', 'discount_amount', $this->chart_interval, $this->start_date, $this->chart_groupby ); $order_discount_amounts = $this->prepare_chart_data( $order_discount_amounts, 'post_date', 'discount_amount', $this->chart_interval, $this->start_date, $this->chart_groupby );
// Encode in json format // Encode in json format.
$chart_data = json_encode( array( $chart_data = json_encode( array(
'order_coupon_counts' => array_values( $order_coupon_counts ), 'order_coupon_counts' => array_values( $order_coupon_counts ),
'order_discount_amounts' => array_values( $order_discount_amounts ), 'order_discount_amounts' => array_values( $order_discount_amounts ),
@ -452,15 +461,15 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
var main_chart; var main_chart;
jQuery(function(){ jQuery(function(){
var order_data = jQuery.parseJSON( '<?php echo $chart_data; ?>' ); var order_data = jQuery.parseJSON( '<?php echo $chart_data; ?>' );<?php // @codingStandardsIgnoreLine ?>
var drawGraph = function( highlight ) { var drawGraph = function( highlight ) {
var series = [ var series = [
{ {
label: "<?php echo esc_js( __( 'Number of coupons used', 'woocommerce' ) ) ?>", label: "<?php echo esc_js( __( 'Number of coupons used', 'woocommerce' ) ) ?>",
data: order_data.order_coupon_counts, data: order_data.order_coupon_counts,
color: '<?php echo $this->chart_colours['coupon_count']; ?>', color: '<?php echo esc_js( $this->chart_colours['coupon_count'] ); ?>',
bars: { fillColor: '<?php echo $this->chart_colours['coupon_count']; ?>', fill: true, show: true, lineWidth: 0, barWidth: <?php echo $this->barwidth; ?> * 0.5, align: 'center' }, bars: { fillColor: '<?php echo esc_js( $this->chart_colours['coupon_count'] ); ?>', fill: true, show: true, lineWidth: 0, barWidth: <?php echo esc_js( $this->barwidth ); ?> * 0.5, align: 'center' },
shadowSize: 0, shadowSize: 0,
hoverable: false hoverable: false
}, },
@ -468,11 +477,11 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
label: "<?php echo esc_js( __( 'Discount amount', 'woocommerce' ) ) ?>", label: "<?php echo esc_js( __( 'Discount amount', 'woocommerce' ) ) ?>",
data: order_data.order_discount_amounts, data: order_data.order_discount_amounts,
yaxis: 2, yaxis: 2,
color: '<?php echo $this->chart_colours['discount_amount']; ?>', color: '<?php echo esc_js( $this->chart_colours['discount_amount'] ); ?>',
points: { show: true, radius: 5, lineWidth: 3, fillColor: '#fff', fill: true }, points: { show: true, radius: 5, lineWidth: 3, fillColor: '#fff', fill: true },
lines: { show: true, lineWidth: 4, fill: false }, lines: { show: true, lineWidth: 4, fill: false },
shadowSize: 0, shadowSize: 0,
<?php echo $this->get_currency_tooltip(); ?> <?php echo $this->get_currency_tooltip(); ?><?php // @codingStandardsIgnoreLine ?>
} }
]; ];
@ -510,7 +519,7 @@ class WC_Report_Coupon_Usage extends WC_Admin_Report {
timeformat: "<?php echo ( 'day' === $this->chart_groupby ) ? '%d %b' : '%b'; ?>", timeformat: "<?php echo ( 'day' === $this->chart_groupby ) ? '%d %b' : '%b'; ?>",
monthNames: <?php echo json_encode( array_values( $wp_locale->month_abbrev ) ) ?>, monthNames: <?php echo json_encode( array_values( $wp_locale->month_abbrev ) ) ?>,
tickLength: 1, tickLength: 1,
minTickSize: [1, "<?php echo $this->chart_groupby; ?>"], minTickSize: [1, "<?php echo esc_js( $this->chart_groupby ); ?>"],
font: { font: {
color: "#aaa" color: "#aaa"
} }

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

@ -1,7 +1,12 @@
<?php <?php
/**
* Sales by category report functionality
*
* @package WooCommerce/Admin/Reporting
*/
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly exit; // Exit if accessed directly.
} }
/** /**
@ -54,7 +59,7 @@ class WC_Report_Sales_By_Category extends WC_Admin_Report {
/** /**
* Get all product ids in a category (and its children). * Get all product ids in a category (and its children).
* *
* @param int $category_id * @param int $category_id Category ID.
* @return array * @return array
*/ */
public function get_products_in_category( $category_id ) { public function get_products_in_category( $category_id ) {
@ -119,7 +124,7 @@ class WC_Report_Sales_By_Category extends WC_Admin_Report {
$this->chart_colours = array( '#3498db', '#34495e', '#1abc9c', '#2ecc71', '#f1c40f', '#e67e22', '#e74c3c', '#2980b9', '#8e44ad', '#2c3e50', '#16a085', '#27ae60', '#f39c12', '#d35400', '#c0392b' ); $this->chart_colours = array( '#3498db', '#34495e', '#1abc9c', '#2ecc71', '#f1c40f', '#e67e22', '#e74c3c', '#2980b9', '#8e44ad', '#2c3e50', '#16a085', '#27ae60', '#f39c12', '#d35400', '#c0392b' );
$current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day'; $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( wp_unslash( $_GET['range'] ) ) : '7day';
if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ) ) ) { if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ) ) ) {
$current_range = '7day'; $current_range = '7day';
@ -128,7 +133,7 @@ class WC_Report_Sales_By_Category extends WC_Admin_Report {
$this->check_current_range_nonce( $current_range ); $this->check_current_range_nonce( $current_range );
$this->calculate_current_range( $current_range ); $this->calculate_current_range( $current_range );
// Get item sales data // Get item sales data.
if ( ! empty( $this->show_categories ) ) { if ( ! empty( $this->show_categories ) ) {
$order_items = $this->get_order_report_data( array( $order_items = $this->get_order_report_data( array(
'data' => array( 'data' => array(
@ -217,18 +222,20 @@ class WC_Report_Sales_By_Category extends WC_Admin_Report {
include_once( WC()->plugin_path() . '/includes/walkers/class-product-cat-dropdown-walker.php' ); include_once( WC()->plugin_path() . '/includes/walkers/class-product-cat-dropdown-walker.php' );
echo wc_walk_category_dropdown_tree( $categories, 0, $r ); echo wc_walk_category_dropdown_tree( $categories, 0, $r ); // @codingStandardsIgnoreLine
?> ?>
</select> </select>
<a href="#" class="select_none"><?php _e( 'None', 'woocommerce' ); ?></a> <?php // @codingStandardsIgnoreStart ?>
<a href="#" class="select_all"><?php _e( 'All', 'woocommerce' ); ?></a> <a href="#" class="select_none"><?php esc_html_e( 'None', 'woocommerce' ); ?></a>
<input type="submit" class="submit button" value="<?php esc_attr_e( 'Show', 'woocommerce' ); ?>" /> <a href="#" class="select_all"><?php esc_html_e( 'All', 'woocommerce' ); ?></a>
<input type="hidden" name="range" value="<?php echo ( ! empty( $_GET['range'] ) ) ? esc_attr( $_GET['range'] ) : ''; ?>" /> <button type="submit" class="submit button" value="<?php esc_attr_e( 'Show', 'woocommerce' ); ?>"><?php esc_html_e( 'Show', 'woocommerce' ); ?></button>
<input type="hidden" name="start_date" value="<?php echo ( ! empty( $_GET['start_date'] ) ) ? esc_attr( $_GET['start_date'] ) : ''; ?>" /> <input type="hidden" name="range" value="<?php echo ( ! empty( $_GET['range'] ) ) ? esc_attr( wp_unslash( $_GET['range'] ) ) : ''; ?>" />
<input type="hidden" name="end_date" value="<?php echo ( ! empty( $_GET['end_date'] ) ) ? esc_attr( $_GET['end_date'] ) : ''; ?>" /> <input type="hidden" name="start_date" value="<?php echo ( ! empty( $_GET['start_date'] ) ) ? esc_attr( wp_unslash( $_GET['start_date'] ) ) : ''; ?>" />
<input type="hidden" name="page" value="<?php echo ( ! empty( $_GET['page'] ) ) ? esc_attr( $_GET['page'] ) : ''; ?>" /> <input type="hidden" name="end_date" value="<?php echo ( ! empty( $_GET['end_date'] ) ) ? esc_attr( wp_unslash( $_GET['end_date'] ) ) : ''; ?>" />
<input type="hidden" name="tab" value="<?php echo ( ! empty( $_GET['tab'] ) ) ? esc_attr( $_GET['tab'] ) : ''; ?>" /> <input type="hidden" name="page" value="<?php echo ( ! empty( $_GET['page'] ) ) ? esc_attr( wp_unslash( $_GET['page'] ) ) : ''; ?>" />
<input type="hidden" name="report" value="<?php echo ( ! empty( $_GET['report'] ) ) ? esc_attr( $_GET['report'] ) : ''; ?>" /> <input type="hidden" name="tab" value="<?php echo ( ! empty( $_GET['tab'] ) ) ? esc_attr( wp_unslash( $_GET['tab'] ) ) : ''; ?>" />
<input type="hidden" name="report" value="<?php echo ( ! empty( $_GET['report'] ) ) ? esc_attr( wp_unslash( $_GET['report'] ) ) : ''; ?>" />
<?php // @codingStandardsIgnoreEnd ?>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
jQuery(function(){ jQuery(function(){
@ -255,17 +262,17 @@ class WC_Report_Sales_By_Category extends WC_Admin_Report {
*/ */
public function get_export_button() { public function get_export_button() {
$current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day'; $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( wp_unslash( $_GET['range'] ) ) : '7day';
?> ?>
<a <a
href="#" href="#"
download="report-<?php echo esc_attr( $current_range ); ?>-<?php echo date_i18n( 'Y-m-d', current_time( 'timestamp' ) ); ?>.csv" download="report-<?php echo esc_attr( $current_range ); ?>-<?php echo esc_attr( date_i18n( 'Y-m-d', current_time( 'timestamp' ) ) ); ?>.csv"
class="export_csv" class="export_csv"
data-export="chart" data-export="chart"
data-xaxes="<?php esc_attr_e( 'Date', 'woocommerce' ); ?>" data-xaxes="<?php esc_attr_e( 'Date', 'woocommerce' ); ?>"
data-groupby="<?php echo $this->chart_groupby; ?>" data-groupby="<?php echo esc_attr( $this->chart_groupby ); ?>"
> >
<?php _e( 'Export CSV', 'woocommerce' ); ?> <?php esc_html_e( 'Export CSV', 'woocommerce' ); ?>
</a> </a>
<?php <?php
} }
@ -279,7 +286,7 @@ class WC_Report_Sales_By_Category extends WC_Admin_Report {
if ( empty( $this->show_categories ) ) { if ( empty( $this->show_categories ) ) {
?> ?>
<div class="chart-container"> <div class="chart-container">
<p class="chart-prompt"><?php _e( 'Choose a category to view stats', 'woocommerce' ); ?></p> <p class="chart-prompt"><?php esc_html_e( 'Choose a category to view stats', 'woocommerce' ); ?></p>
</div> </div>
<?php <?php
} else { } else {
@ -325,6 +332,7 @@ class WC_Report_Sales_By_Category extends WC_Admin_Report {
<div class="chart-container"> <div class="chart-container">
<div class="chart-placeholder main"></div> <div class="chart-placeholder main"></div>
</div> </div>
<?php // @codingStandardsIgnoreStart ?>
<script type="text/javascript"> <script type="text/javascript">
var main_chart; var main_chart;
@ -432,6 +440,7 @@ class WC_Report_Sales_By_Category extends WC_Admin_Report {
); );
}); });
</script> </script>
<?php // @codingStandardsIgnoreEnd ?>
<?php <?php
} }
} }

View File

@ -1,7 +1,12 @@
<?php <?php
/**
* Sales By Product Reporting
*
* @package WooCommerce/Admin/Reporting
*/
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly exit; // Exit if accessed directly.
} }
/** /**
@ -48,6 +53,7 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
/** /**
* Get the legend for the main chart sidebar. * Get the legend for the main chart sidebar.
*
* @return array * @return array
*/ */
public function get_chart_legend() { public function get_chart_legend() {
@ -136,7 +142,7 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
'item_count' => '#d4d9dc', 'item_count' => '#d4d9dc',
); );
$current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day'; $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( wp_unslash( $_GET['range'] ) ) : '7day';
if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ) ) ) { if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ) ) ) {
$current_range = '7day'; $current_range = '7day';
@ -190,8 +196,8 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
} }
} }
echo '<p>' . ' <strong>' . esc_html( implode( ', ', $this->product_ids_titles ) ) . '</strong></p>'; echo '<p><strong>' . esc_html( implode( ', ', $this->product_ids_titles ) ) . '</strong></p>';
echo '<p><a class="button" href="' . esc_url( remove_query_arg( 'product_ids' ) ) . '">' . __( 'Reset', 'woocommerce' ) . '</a></p>'; echo '<p><a class="button" href="' . esc_url( remove_query_arg( 'product_ids' ) ) . '">' . esc_html__( 'Reset', 'woocommerce' ) . '</a></p>';
} }
/** /**
@ -199,12 +205,13 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
*/ */
public function products_widget() { public function products_widget() {
?> ?>
<h4 class="section_title"><span><?php _e( 'Product search', 'woocommerce' ); ?></span></h4> <h4 class="section_title"><span><?php esc_html_e( 'Product search', 'woocommerce' ); ?></span></h4>
<div class="section"> <div class="section">
<form method="GET"> <form method="GET">
<div> <div>
<?php // @codingStandardsIgnoreStart ?>
<select class="wc-product-search" style="width:203px;" multiple="multiple" id="product_ids" name="product_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations"></select> <select class="wc-product-search" style="width:203px;" multiple="multiple" id="product_ids" name="product_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations"></select>
<input type="submit" class="submit button" value="<?php esc_attr_e( 'Show', 'woocommerce' ); ?>" /> <button type="submit" class="submit button" value="<?php esc_attr_e( 'Show', 'woocommerce' ); ?>"><?php esc_html_e( 'Show', 'woocommerce' ); ?></button>
<input type="hidden" name="range" value="<?php echo ( ! empty( $_GET['range'] ) ) ? esc_attr( $_GET['range'] ) : ''; ?>" /> <input type="hidden" name="range" value="<?php echo ( ! empty( $_GET['range'] ) ) ? esc_attr( $_GET['range'] ) : ''; ?>" />
<input type="hidden" name="start_date" value="<?php echo ( ! empty( $_GET['start_date'] ) ) ? esc_attr( $_GET['start_date'] ) : ''; ?>" /> <input type="hidden" name="start_date" value="<?php echo ( ! empty( $_GET['start_date'] ) ) ? esc_attr( $_GET['start_date'] ) : ''; ?>" />
<input type="hidden" name="end_date" value="<?php echo ( ! empty( $_GET['end_date'] ) ) ? esc_attr( $_GET['end_date'] ) : ''; ?>" /> <input type="hidden" name="end_date" value="<?php echo ( ! empty( $_GET['end_date'] ) ) ? esc_attr( $_GET['end_date'] ) : ''; ?>" />
@ -212,10 +219,11 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
<input type="hidden" name="tab" value="<?php echo ( ! empty( $_GET['tab'] ) ) ? esc_attr( $_GET['tab'] ) : ''; ?>" /> <input type="hidden" name="tab" value="<?php echo ( ! empty( $_GET['tab'] ) ) ? esc_attr( $_GET['tab'] ) : ''; ?>" />
<input type="hidden" name="report" value="<?php echo ( ! empty( $_GET['report'] ) ) ? esc_attr( $_GET['report'] ) : ''; ?>" /> <input type="hidden" name="report" value="<?php echo ( ! empty( $_GET['report'] ) ) ? esc_attr( $_GET['report'] ) : ''; ?>" />
<?php wp_nonce_field( 'custom_range', 'wc_reports_nonce', false ); ?> <?php wp_nonce_field( 'custom_range', 'wc_reports_nonce', false ); ?>
<?php // @codingStandardsIgnoreEnd ?>
</div> </div>
</form> </form>
</div> </div>
<h4 class="section_title"><span><?php _e( 'Top sellers', 'woocommerce' ); ?></span></h4> <h4 class="section_title"><span><?php esc_html_e( 'Top sellers', 'woocommerce' ); ?></span></h4>
<div class="section"> <div class="section">
<table cellspacing="0"> <table cellspacing="0">
<?php <?php
@ -242,20 +250,22 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
) ); ) );
if ( $top_sellers ) { if ( $top_sellers ) {
// @codingStandardsIgnoreStart
foreach ( $top_sellers as $product ) { foreach ( $top_sellers as $product ) {
echo '<tr class="' . ( in_array( $product->product_id, $this->product_ids ) ? 'active' : '' ) . '"> echo '<tr class="' . ( in_array( $product->product_id, $this->product_ids ) ? 'active' : '' ) . '">
<td class="count">' . $product->order_item_qty . '</td> <td class="count">' . esc_html( $product->order_item_qty ) . '</td>
<td class="name"><a href="' . esc_url( add_query_arg( 'product_ids', $product->product_id ) ) . '">' . esc_html( get_the_title( $product->product_id ) ) . '</a></td> <td class="name"><a href="' . esc_url( add_query_arg( 'product_ids', $product->product_id ) ) . '">' . esc_html( get_the_title( $product->product_id ) ) . '</a></td>
<td class="sparkline">' . $this->sales_sparkline( $product->product_id, 7, 'count' ) . '</td> <td class="sparkline">' . $this->sales_sparkline( $product->product_id, 7, 'count' ) . '</td>
</tr>'; </tr>';
} }
// @codingStandardsIgnoreEnd
} else { } else {
echo '<tr><td colspan="3">' . __( 'No products found in range', 'woocommerce' ) . '</td></tr>'; echo '<tr><td colspan="3">' . esc_html__( 'No products found in range', 'woocommerce' ) . '</td></tr>';
} }
?> ?>
</table> </table>
</div> </div>
<h4 class="section_title"><span><?php _e( 'Top freebies', 'woocommerce' ); ?></span></h4> <h4 class="section_title"><span><?php esc_html_e( 'Top freebies', 'woocommerce' ); ?></span></h4>
<div class="section"> <div class="section">
<table cellspacing="0"> <table cellspacing="0">
<?php <?php
@ -290,20 +300,22 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
) ); ) );
if ( $top_freebies ) { if ( $top_freebies ) {
// @codingStandardsIgnoreStart
foreach ( $top_freebies as $product ) { foreach ( $top_freebies as $product ) {
echo '<tr class="' . ( in_array( $product->product_id, $this->product_ids ) ? 'active' : '' ) . '"> echo '<tr class="' . ( in_array( $product->product_id, $this->product_ids ) ? 'active' : '' ) . '">
<td class="count">' . $product->order_item_qty . '</td> <td class="count">' . esc_html( $product->order_item_qty ) . '</td>
<td class="name"><a href="' . esc_url( add_query_arg( 'product_ids', $product->product_id ) ) . '">' . esc_html( get_the_title( $product->product_id ) ) . '</a></td> <td class="name"><a href="' . esc_url( add_query_arg( 'product_ids', $product->product_id ) ) . '">' . esc_html( get_the_title( $product->product_id ) ) . '</a></td>
<td class="sparkline">' . $this->sales_sparkline( $product->product_id, 7, 'count' ) . '</td> <td class="sparkline">' . $this->sales_sparkline( $product->product_id, 7, 'count' ) . '</td>
</tr>'; </tr>';
} }
// @codingStandardsIgnoreEnd
} else { } else {
echo '<tr><td colspan="3">' . __( 'No products found in range', 'woocommerce' ) . '</td></tr>'; echo '<tr><td colspan="3">' . esc_html__( 'No products found in range', 'woocommerce' ) . '</td></tr>';
} }
?> ?>
</table> </table>
</div> </div>
<h4 class="section_title"><span><?php _e( 'Top earners', 'woocommerce' ); ?></span></h4> <h4 class="section_title"><span><?php esc_html_e( 'Top earners', 'woocommerce' ); ?></span></h4>
<div class="section"> <div class="section">
<table cellspacing="0"> <table cellspacing="0">
<?php <?php
@ -330,6 +342,7 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
) ); ) );
if ( $top_earners ) { if ( $top_earners ) {
// @codingStandardsIgnoreStart
foreach ( $top_earners as $product ) { foreach ( $top_earners as $product ) {
echo '<tr class="' . ( in_array( $product->product_id, $this->product_ids ) ? 'active' : '' ) . '"> echo '<tr class="' . ( in_array( $product->product_id, $this->product_ids ) ? 'active' : '' ) . '">
<td class="count">' . wc_price( $product->order_item_total ) . '</td> <td class="count">' . wc_price( $product->order_item_total ) . '</td>
@ -337,8 +350,9 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
<td class="sparkline">' . $this->sales_sparkline( $product->product_id, 7, 'sales' ) . '</td> <td class="sparkline">' . $this->sales_sparkline( $product->product_id, 7, 'sales' ) . '</td>
</tr>'; </tr>';
} }
// @codingStandardsIgnoreEnd
} else { } else {
echo '<tr><td colspan="3">' . __( 'No products found in range', 'woocommerce' ) . '</td></tr>'; echo '<tr><td colspan="3">' . esc_html__( 'No products found in range', 'woocommerce' ) . '</td></tr>';
} }
?> ?>
</table> </table>
@ -370,17 +384,17 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
*/ */
public function get_export_button() { public function get_export_button() {
$current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day'; $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( wp_unslash( $_GET['range'] ) ) : '7day';
?> ?>
<a <a
href="#" href="#"
download="report-<?php echo esc_attr( $current_range ); ?>-<?php echo date_i18n( 'Y-m-d', current_time( 'timestamp' ) ); ?>.csv" download="report-<?php echo esc_attr( $current_range ); ?>-<?php echo esc_html( date_i18n( 'Y-m-d', current_time( 'timestamp' ) ) ); ?>.csv"
class="export_csv" class="export_csv"
data-export="chart" data-export="chart"
data-xaxes="<?php esc_attr_e( 'Date', 'woocommerce' ); ?>" data-xaxes="<?php esc_attr_e( 'Date', 'woocommerce' ); ?>"
data-groupby="<?php echo $this->chart_groupby; ?>" data-groupby="<?php echo $this->chart_groupby; ?>"<?php // @codingStandardsIgnoreLine ?>
> >
<?php _e( 'Export CSV', 'woocommerce' ); ?> <?php esc_html_e( 'Export CSV', 'woocommerce' ); ?>
</a> </a>
<?php <?php
} }
@ -394,11 +408,11 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
if ( empty( $this->product_ids ) ) { if ( empty( $this->product_ids ) ) {
?> ?>
<div class="chart-container"> <div class="chart-container">
<p class="chart-prompt"><?php _e( 'Choose a product to view stats', 'woocommerce' ); ?></p> <p class="chart-prompt"><?php esc_html_e( 'Choose a product to view stats', 'woocommerce' ); ?></p>
</div> </div>
<?php <?php
} else { } else {
// Get orders and dates in range - we want the SUM of order totals, COUNT of order items, COUNT of orders, and the date // Get orders and dates in range - we want the SUM of order totals, COUNT of order items, COUNT of orders, and the date.
$order_item_counts = $this->get_order_report_data( array( $order_item_counts = $this->get_order_report_data( array(
'data' => array( 'data' => array(
'_qty' => array( '_qty' => array(
@ -469,11 +483,11 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
'filter_range' => true, 'filter_range' => true,
) ); ) );
// Prepare data for report // Prepare data for report.
$order_item_counts = $this->prepare_chart_data( $order_item_counts, 'post_date', 'order_item_count', $this->chart_interval, $this->start_date, $this->chart_groupby ); $order_item_counts = $this->prepare_chart_data( $order_item_counts, 'post_date', 'order_item_count', $this->chart_interval, $this->start_date, $this->chart_groupby );
$order_item_amounts = $this->prepare_chart_data( $order_item_amounts, 'post_date', 'order_item_amount', $this->chart_interval, $this->start_date, $this->chart_groupby ); $order_item_amounts = $this->prepare_chart_data( $order_item_amounts, 'post_date', 'order_item_amount', $this->chart_interval, $this->start_date, $this->chart_groupby );
// Encode in json format // Encode in json format.
$chart_data = json_encode( array( $chart_data = json_encode( array(
'order_item_counts' => array_values( $order_item_counts ), 'order_item_counts' => array_values( $order_item_counts ),
'order_item_amounts' => array_values( $order_item_amounts ), 'order_item_amounts' => array_values( $order_item_amounts ),
@ -482,6 +496,7 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
<div class="chart-container"> <div class="chart-container">
<div class="chart-placeholder main"></div> <div class="chart-placeholder main"></div>
</div> </div>
<?php // @codingStandardsIgnoreStart ?>
<script type="text/javascript"> <script type="text/javascript">
var main_chart; var main_chart;
@ -586,6 +601,7 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
}); });
</script> </script>
<?php <?php
// @codingStandardsIgnoreEnd
} }
} }
} }

View File

@ -9,10 +9,12 @@
*/ */
if ( ! defined( 'ABSPATH' ) ) { 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. * WC_Settings_Products.
@ -35,7 +37,6 @@ class WC_Settings_Products extends WC_Settings_Page {
* @return array * @return array
*/ */
public function get_sections() { public function get_sections() {
$sections = array( $sections = array(
'' => __( 'General', 'woocommerce' ), '' => __( 'General', 'woocommerce' ),
'display' => __( 'Display', 'woocommerce' ), 'display' => __( 'Display', 'woocommerce' ),
@ -70,22 +71,18 @@ class WC_Settings_Products extends WC_Settings_Page {
/** /**
* Get settings array. * Get settings array.
* *
* @param string $current_section * @param string $current_section Current section name.
*
* @return array * @return array
*/ */
public function get_settings( $current_section = '' ) { public function get_settings( $current_section = '' ) {
if ( 'display' == $current_section ) { if ( 'display' === $current_section ) {
$settings = array(
$settings = apply_filters( 'woocommerce_product_settings', array(
array( array(
'title' => __( 'Shop &amp; product pages', 'woocommerce' ), 'title' => __( 'Shop &amp; product pages', 'woocommerce' ),
'type' => 'title', 'type' => 'title',
'desc' => '', 'desc' => '',
'id' => 'catalog_options', 'id' => 'catalog_options',
), ),
array( array(
'title' => __( 'Shop page', 'woocommerce' ), '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' ) ), '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;', 'css' => 'min-width:300px;',
'desc_tip' => __( 'This sets the base page of your shop - this is where your product archive will be.', 'woocommerce' ), 'desc_tip' => __( 'This sets the base page of your shop - this is where your product archive will be.', 'woocommerce' ),
), ),
array( array(
'title' => __( 'Shop page display', 'woocommerce' ), 'title' => __( 'Shop page display', 'woocommerce' ),
'desc' => __( 'This controls what is shown on the product archive.', '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, 'desc_tip' => true,
), ),
array( array(
'title' => __( 'Default category display', 'woocommerce' ), 'title' => __( 'Default category display', 'woocommerce' ),
'desc' => __( 'This controls what is shown on category archives.', '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, 'desc_tip' => true,
), ),
array( array(
'title' => __( 'Default product sorting', 'woocommerce' ), 'title' => __( 'Default product sorting', 'woocommerce' ),
'desc' => __( 'This controls the default sort order of the catalog.', '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, 'desc_tip' => true,
), ),
array( array(
'title' => __( 'Add to cart behaviour', 'woocommerce' ), 'title' => __( 'Add to cart behaviour', 'woocommerce' ),
'desc' => __( 'Redirect to the cart page after successful addition', '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', 'type' => 'checkbox',
'checkboxgroup' => 'start', 'checkboxgroup' => 'start',
), ),
array( array(
'desc' => __( 'Enable AJAX add to cart buttons on archives', 'woocommerce' ), 'desc' => __( 'Enable AJAX add to cart buttons on archives', 'woocommerce' ),
'id' => 'woocommerce_enable_ajax_add_to_cart', 'id' => 'woocommerce_enable_ajax_add_to_cart',
@ -164,68 +156,73 @@ class WC_Settings_Products extends WC_Settings_Page {
'type' => 'checkbox', 'type' => 'checkbox',
'checkboxgroup' => 'end', 'checkboxgroup' => 'end',
), ),
array( array(
'type' => 'sectionend', 'type' => 'sectionend',
'id' => 'catalog_options', 'id' => 'catalog_options',
), ),
);
$theme_support = get_theme_support( 'woocommerce' );
$theme_support = is_array( $theme_support ) ? $theme_support[0]: false;
$image_settings = array(
array( array(
'title' => __( 'Product images', 'woocommerce' ), 'title' => __( 'Product images', 'woocommerce' ),
'type' => 'title', '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', 'id' => 'image_options',
), ),
'single_image_width' => array(
array( 'title' => __( 'Main image width', 'woocommerce' ),
'title' => __( 'Catalog images', 'woocommerce' ), 'desc' => __( 'This is the width used by the main image on single product pages. These images will be uncropped.', 'woocommerce' ),
'desc' => __( 'This size is usually used in product listings. (W x H)', 'woocommerce' ), 'id' => 'woocommerce_single_image_width',
'id' => 'shop_catalog_image_size',
'css' => '', 'css' => '',
'type' => 'image_width', 'type' => 'text',
'default' => array( 'custom_attributes' => array(
'width' => '300', 'size' => 3,
'height' => '300',
'crop' => 1,
), ),
'suffix' => 'px',
'default' => 600,
'desc_tip' => true, 'desc_tip' => true,
), ),
'thumbnail_image_width' => array(
array( 'title' => __( 'Thumbnail width', 'woocommerce' ),
'title' => __( 'Single product image', 'woocommerce' ), 'desc' => __( 'This size is used for product archives and product listings.', 'woocommerce' ),
'desc' => __( 'This is the size used by the main image on the product page. (W x H)', 'woocommerce' ), 'id' => 'woocommerce_thumbnail_image_width',
'id' => 'shop_single_image_size',
'css' => '', 'css' => '',
'type' => 'image_width', 'type' => 'text',
'default' => array( 'custom_attributes' => array(
'width' => '600', 'size' => 3,
'height' => '600',
'crop' => 1,
), ),
'suffix' => 'px',
'default' => 300,
'desc_tip' => true, 'desc_tip' => true,
), ),
array( array(
'title' => __( 'Product thumbnails', 'woocommerce' ), 'title' => __( 'Thumbnail cropping', 'woocommerce' ),
'desc' => __( 'This size is usually used for the gallery of images on the product page. (W x H)', 'woocommerce' ), 'desc' => __( 'This determines how thumbnails appear. Widths will be fixed, whilst heights may vary.', 'woocommerce' ),
'id' => 'shop_thumbnail_image_size', 'id' => 'woocommerce_thumbnail_cropping',
'css' => '', 'css' => '',
'type' => 'image_width', 'type' => 'thumbnail_cropping',
'default' => array( 'default' => '1:1',
'width' => '180', 'desc_tip' => false,
'height' => '180',
'crop' => 1,
),
'desc_tip' => true,
), ),
array( array(
'type' => 'sectionend', 'type' => 'sectionend',
'id' => 'image_options', 'id' => 'image_options',
), ),
);
)); if ( isset( $theme_support['single_image_width'] ) ) {
} elseif ( 'inventory' == $current_section ) { 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( $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( $settings = apply_filters( 'woocommerce_downloadable_products_settings', array(
array( array(
'title' => __( 'Downloadable products', 'woocommerce' ), 'title' => __( 'Downloadable products', 'woocommerce' ),
@ -530,6 +527,4 @@ class WC_Settings_Products extends WC_Settings_Page {
} }
} }
endif;
return new WC_Settings_Products(); return new WC_Settings_Products();

View File

@ -1,12 +1,18 @@
<?php <?php
/**
* Shipping classes admin
*
* @package WooCommerce/Admin/Shipping
*/
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
?> ?>
<h2> <h2>
<?php _e( 'Shipping classes', 'woocommerce' ); ?> <?php esc_html_e( 'Shipping classes', 'woocommerce' ); ?>
<?php echo wc_help_tip( __( 'Shipping classes can be used to group products of similar type and can be used by some Shipping Methods (such as "Flat rate shipping") to provide different rates to different classes of product.', 'woocommerce' ) ); ?> <?php echo wc_help_tip( __( 'Shipping classes can be used to group products of similar type and can be used by some Shipping Methods (such as "Flat rate shipping") to provide different rates to different classes of product.', 'woocommerce' ) ); // @codingStandardsIgnoreLine ?>
</h2> </h2>
<table class="wc-shipping-classes widefat"> <table class="wc-shipping-classes widefat">
@ -19,8 +25,8 @@ if ( ! defined( 'ABSPATH' ) ) {
</thead> </thead>
<tfoot> <tfoot>
<tr> <tr>
<td colspan="<?php echo absint( sizeof( $shipping_class_columns ) ); ?>"> <td colspan="<?php echo absint( count( $shipping_class_columns ) ); ?>">
<input type="submit" name="save" class="button button-primary wc-shipping-class-save" value="<?php esc_attr_e( 'Save shipping classes', 'woocommerce' ); ?>" disabled /> <button type="submit" name="save" class="button button-primary wc-shipping-class-save" value="<?php esc_attr_e( 'Save shipping classes', 'woocommerce' ); ?>" disabled><?php esc_html_e( 'Save shipping classes', 'woocommerce' ); ?></button>
<a class="button button-secondary wc-shipping-class-add" href="#"><?php esc_html_e( 'Add shipping class', 'woocommerce' ); ?></a> <a class="button button-secondary wc-shipping-class-add" href="#"><?php esc_html_e( 'Add shipping class', 'woocommerce' ); ?></a>
</td> </td>
</tr> </tr>
@ -30,55 +36,55 @@ if ( ! defined( 'ABSPATH' ) ) {
<script type="text/html" id="tmpl-wc-shipping-class-row-blank"> <script type="text/html" id="tmpl-wc-shipping-class-row-blank">
<tr> <tr>
<td class="wc-shipping-classes-blank-state" colspan="<?php echo absint( sizeof( $shipping_class_columns ) ); ?>"><p><?php _e( 'No shipping classes have been created.', 'woocommerce' ); ?></p></td> <td class="wc-shipping-classes-blank-state" colspan="<?php echo absint( count( $shipping_class_columns ) ); ?>"><p><?php esc_html_e( 'No shipping classes have been created.', 'woocommerce' ); ?></p></td>
</tr> </tr>
</script> </script>
<script type="text/html" id="tmpl-wc-shipping-class-row"> <script type="text/html" id="tmpl-wc-shipping-class-row">
<tr data-id="{{ data.term_id }}"> <tr data-id="{{ data.term_id }}">
<?php <?php
foreach ( $shipping_class_columns as $class => $heading ) { foreach ( $shipping_class_columns as $class => $heading ) {
echo '<td class="' . esc_attr( $class ) . '">'; echo '<td class="' . esc_attr( $class ) . '">';
switch ( $class ) { switch ( $class ) {
case 'wc-shipping-class-name' : case 'wc-shipping-class-name' :
?> ?>
<div class="view"> <div class="view">
{{ data.name }} {{ data.name }}
<div class="row-actions"> <div class="row-actions">
<a class="wc-shipping-class-edit" href="#"><?php _e( 'Edit', 'woocommerce' ); ?></a> | <a href="#" class="wc-shipping-class-delete"><?php _e( 'Remove', 'woocommerce' ); ?></a> <a class="wc-shipping-class-edit" href="#"><?php esc_html_e( 'Edit', 'woocommerce' ); ?></a> | <a href="#" class="wc-shipping-class-delete"><?php esc_html_e( 'Remove', 'woocommerce' ); ?></a>
</div>
</div> </div>
<div class="edit"> </div>
<input type="text" name="name[{{ data.term_id }}]" data-attribute="name" value="{{ data.name }}" placeholder="<?php esc_attr_e( 'Shipping class name', 'woocommerce' ); ?>" /> <div class="edit">
<div class="row-actions"> <input type="text" name="name[{{ data.term_id }}]" data-attribute="name" value="{{ data.name }}" placeholder="<?php esc_attr_e( 'Shipping class name', 'woocommerce' ); ?>" />
<a class="wc-shipping-class-cancel-edit" href="#"><?php _e( 'Cancel changes', 'woocommerce' ); ?></a> <div class="row-actions">
</div> <a class="wc-shipping-class-cancel-edit" href="#"><?php esc_html_e( 'Cancel changes', 'woocommerce' ); ?></a>
</div> </div>
<?php </div>
break; <?php
case 'wc-shipping-class-slug' : break;
?> case 'wc-shipping-class-slug' :
<div class="view">{{ data.slug }}</div> ?>
<div class="edit"><input type="text" name="slug[{{ data.term_id }}]" data-attribute="slug" value="{{ data.slug }}" placeholder="<?php esc_attr_e( 'Slug', 'woocommerce' ); ?>" /></div> <div class="view">{{ data.slug }}</div>
<?php <div class="edit"><input type="text" name="slug[{{ data.term_id }}]" data-attribute="slug" value="{{ data.slug }}" placeholder="<?php esc_attr_e( 'Slug', 'woocommerce' ); ?>" /></div>
break; <?php
case 'wc-shipping-class-description' : break;
?> case 'wc-shipping-class-description' :
<div class="view">{{ data.description }}</div> ?>
<div class="edit"><input type="text" name="description[{{ data.term_id }}]" data-attribute="description" value="{{ data.description }}" placeholder="<?php esc_attr_e( 'Description for your reference', 'woocommerce' ); ?>" /></div> <div class="view">{{ data.description }}</div>
<?php <div class="edit"><input type="text" name="description[{{ data.term_id }}]" data-attribute="description" value="{{ data.description }}" placeholder="<?php esc_attr_e( 'Description for your reference', 'woocommerce' ); ?>" /></div>
break; <?php
case 'wc-shipping-class-count' : break;
?> case 'wc-shipping-class-count' :
<a href="<?php echo esc_url( admin_url( 'edit.php?post_type=product&product_shipping_class=' ) ); ?>{{data.slug}}">{{ data.count }}</a> ?>
<?php <a href="<?php echo esc_url( admin_url( 'edit.php?post_type=product&product_shipping_class=' ) ); ?>{{data.slug}}">{{ data.count }}</a>
break; <?php
default : break;
do_action( 'woocommerce_shipping_classes_column_' . $class ); default :
break; do_action( 'woocommerce_shipping_classes_column_' . $class );
} break;
echo '</td>';
} }
echo '</td>';
}
?> ?>
</tr> </tr>
</script> </script>

View File

@ -1,11 +1,17 @@
<?php <?php
/**
* Shipping zone admin
*
* @package WooCommerce/Admin/Shipping
*/
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
?> ?>
<h2> <h2>
<a href="<?php echo admin_url( 'admin.php?page=wc-settings&tab=shipping' ); ?>"><?php _e( 'Shipping zones', 'woocommerce' ); ?></a> &gt; <a href="<?php echo esc_url( admin_url( 'admin.php?page=wc-settings&tab=shipping' ) ); ?>"><?php esc_html_e( 'Shipping zones', 'woocommerce' ); ?></a> &gt;
<span class="wc-shipping-zone-name"><?php echo esc_html( $zone->get_zone_name() ? $zone->get_zone_name() : __( 'Zone', 'woocommerce' ) ); ?></span> <span class="wc-shipping-zone-name"><?php echo esc_html( $zone->get_zone_name() ? $zone->get_zone_name() : __( 'Zone', 'woocommerce' ) ); ?></span>
</h2> </h2>
@ -17,43 +23,43 @@ if ( ! defined( 'ABSPATH' ) ) {
<tr valign="top" class=""> <tr valign="top" class="">
<th scope="row" class="titledesc"> <th scope="row" class="titledesc">
<label for="zone_name"><?php esc_html_e( 'Zone name', 'woocommerce' ); ?></label> <label for="zone_name"><?php esc_html_e( 'Zone name', 'woocommerce' ); ?></label>
<?php echo wc_help_tip( __( 'This is the name of the zone for your reference.', 'woocommerce' ) ); ?> <?php echo wc_help_tip( __( 'This is the name of the zone for your reference.', 'woocommerce' ) ); // @codingStandardsIgnoreLine ?>
</th> </th>
<td class="forminp"> <td class="forminp">
<input type="text" data-attribute="zone_name" name="zone_name" id="zone_name" value="<?php echo esc_attr( $zone->get_zone_name( 'edit' ) ); ?>" placeholder="<?php _e( 'Zone name', 'woocommerce' ); ?>"> <input type="text" data-attribute="zone_name" name="zone_name" id="zone_name" value="<?php echo esc_attr( $zone->get_zone_name( 'edit' ) ); ?>" placeholder="<?php esc_attr_e( 'Zone name', 'woocommerce' ); ?>">
</td> </td>
</tr> </tr>
<tr valign="top" class=""> <tr valign="top" class="">
<th scope="row" class="titledesc"> <th scope="row" class="titledesc">
<label for="zone_locations"><?php esc_html_e( 'Zone regions', 'woocommerce' ); ?></label> <label for="zone_locations"><?php esc_html_e( 'Zone regions', 'woocommerce' ); ?></label>
<?php echo wc_help_tip( __( 'These are regions inside this zone. Customers will be matched against these regions.', 'woocommerce' ) ); ?> <?php echo wc_help_tip( __( 'These are regions inside this zone. Customers will be matched against these regions.', 'woocommerce' ) ); // @codingStandardsIgnoreLine ?>
</th> </th>
<td class="forminp"> <td class="forminp">
<select multiple="multiple" data-attribute="zone_locations" id="zone_locations" name="zone_locations" data-placeholder="<?php _e( 'Select regions within this zone', 'woocommerce' ); ?>" class="wc-shipping-zone-region-select chosen_select"> <select multiple="multiple" data-attribute="zone_locations" id="zone_locations" name="zone_locations" data-placeholder="<?php esc_html_e( 'Select regions within this zone', 'woocommerce' ); ?>" class="wc-shipping-zone-region-select chosen_select">
<?php <?php
foreach ( $continents as $continent_code => $continent ) { foreach ( $continents as $continent_code => $continent ) {
echo '<option value="continent:' . esc_attr( $continent_code ) . '" ' . selected( in_array( "continent:$continent_code", $locations ), true, false ) . ' alt="">' . esc_html( $continent['name'] ) . '</option>'; echo '<option value="continent:' . esc_attr( $continent_code ) . '" ' . selected( in_array( "continent:$continent_code", $locations ), true, false ) . ' alt="">' . esc_html( $continent['name'] ) . '</option>';
$countries = array_intersect( array_keys( $allowed_countries ), $continent['countries'] ); $countries = array_intersect( array_keys( $allowed_countries ), $continent['countries'] );
foreach ( $countries as $country_code ) { foreach ( $countries as $country_code ) {
echo '<option value="country:' . esc_attr( $country_code ) . '" ' . selected( in_array( "country:$country_code", $locations ), true, false ) . ' alt="' . esc_attr( $continent['name'] ) . '">' . esc_html( '&nbsp;&nbsp; ' . $allowed_countries[ $country_code ] ) . '</option>'; echo '<option value="country:' . esc_attr( $country_code ) . '" ' . selected( in_array( "country:$country_code", $locations ), true, false ) . ' alt="' . esc_attr( $continent['name'] ) . '">' . esc_html( '&nbsp;&nbsp; ' . $allowed_countries[ $country_code ] ) . '</option>';
if ( $states = WC()->countries->get_states( $country_code ) ) { if ( $states = WC()->countries->get_states( $country_code ) ) {
foreach ( $states as $state_code => $state_name ) { foreach ( $states as $state_code => $state_name ) {
echo '<option value="state:' . esc_attr( $country_code . ':' . $state_code ) . '" ' . selected( in_array( "state:$country_code:$state_code", $locations ), true, false ) . ' alt="' . esc_attr( $continent['name'] . ' ' . $allowed_countries[ $country_code ] ) . '">' . esc_html( '&nbsp;&nbsp;&nbsp;&nbsp; ' . $state_name ) . '</option>'; echo '<option value="state:' . esc_attr( $country_code . ':' . $state_code ) . '" ' . selected( in_array( "state:$country_code:$state_code", $locations ), true, false ) . ' alt="' . esc_attr( $continent['name'] . ' ' . $allowed_countries[ $country_code ] ) . '">' . esc_html( '&nbsp;&nbsp;&nbsp;&nbsp; ' . $state_name ) . '</option>';
}
} }
} }
} }
}
?> ?>
</select> </select>
<?php if ( empty( $postcodes ) ) : ?> <?php if ( empty( $postcodes ) ) : ?>
<a class="wc-shipping-zone-postcodes-toggle" href="#"><?php _e( 'Limit to specific ZIP/postcodes', 'woocommerce' ); ?></a> <a class="wc-shipping-zone-postcodes-toggle" href="#"><?php esc_html_e( 'Limit to specific ZIP/postcodes', 'woocommerce' ); ?></a>
<?php endif; ?> <?php endif; ?>
<div class="wc-shipping-zone-postcodes"> <div class="wc-shipping-zone-postcodes">
<textarea name="zone_postcodes" data-attribute="zone_postcodes" id="zone_postcodes" placeholder="<?php esc_attr_e( 'List 1 postcode per line', 'woocommerce' ); ?>" class="input-text large-text" cols="25" rows="5"><?php echo esc_textarea( implode( "\n", $postcodes ) ); ?></textarea> <textarea name="zone_postcodes" data-attribute="zone_postcodes" id="zone_postcodes" placeholder="<?php esc_attr_e( 'List 1 postcode per line', 'woocommerce' ); ?>" class="input-text large-text" cols="25" rows="5"><?php echo esc_textarea( implode( "\n", $postcodes ) ); ?></textarea>
<span class="description"><?php _e( 'Postcodes containing wildcards (e.g. CB23*) and fully numeric ranges (e.g. <code>90210...99000</code>) are also supported.', 'woocommerce' ) ?></span> <span class="description"><?php esc_html_e( 'Postcodes containing wildcards (e.g. CB23*) and fully numeric ranges (e.g. <code>90210...99000</code>) are also supported.', 'woocommerce' ) ?></span>
</div> </div>
</td> </td>
<?php endif; ?> <?php endif; ?>
@ -61,7 +67,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<tr valign="top" class=""> <tr valign="top" class="">
<th scope="row" class="titledesc"> <th scope="row" class="titledesc">
<label><?php esc_html_e( 'Shipping methods', 'woocommerce' ); ?></label> <label><?php esc_html_e( 'Shipping methods', 'woocommerce' ); ?></label>
<?php echo wc_help_tip( __( 'The following shipping methods apply to customers with shipping addresses within this zone.', 'woocommerce' ) ); ?> <?php echo wc_help_tip( __( 'The following shipping methods apply to customers with shipping addresses within this zone.', 'woocommerce' ) ); // @codingStandardsIgnoreLine ?>
</th> </th>
<td class=""> <td class="">
<table class="wc-shipping-zone-methods widefat"> <table class="wc-shipping-zone-methods widefat">
@ -76,7 +82,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<tfoot> <tfoot>
<tr> <tr>
<td colspan="4"> <td colspan="4">
<input type="submit" class="button wc-shipping-zone-add-method" value="<?php esc_attr_e( 'Add shipping method', 'woocommerce' ); ?>" /> <button type="submit" class="button wc-shipping-zone-add-method" value="<?php esc_attr_e( 'Add shipping method', 'woocommerce' ); ?>"><?php esc_html_e( 'Add shipping method', 'woocommerce' ); ?></button>
</td> </td>
</tr> </tr>
</tfoot> </tfoot>
@ -87,13 +93,13 @@ if ( ! defined( 'ABSPATH' ) ) {
</tbody> </tbody>
</table> </table>
<p class="submit"> <p class="submit">
<input type="submit" name="submit" id="submit" class="button button-primary button-large wc-shipping-zone-method-save" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>" disabled /> <button type="submit" name="submit" id="submit" class="button button-primary button-large wc-shipping-zone-method-save" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>" disabled><?php esc_html_e( 'Save changes', 'woocommerce' ); ?></button>
</p> </p>
<script type="text/html" id="tmpl-wc-shipping-zone-method-row-blank"> <script type="text/html" id="tmpl-wc-shipping-zone-method-row-blank">
<tr> <tr>
<td class="wc-shipping-zone-method-blank-state" colspan="4"> <td class="wc-shipping-zone-method-blank-state" colspan="4">
<p><?php _e( 'You can add multiple shipping methods within this zone. Only customers within the zone will see them.', 'woocommerce' ); ?></p> <p><?php esc_html_e( 'You can add multiple shipping methods within this zone. Only customers within the zone will see them.', 'woocommerce' ); ?></p>
</td> </td>
</tr> </tr>
</script> </script>
@ -104,7 +110,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<td class="wc-shipping-zone-method-title"> <td class="wc-shipping-zone-method-title">
<a class="wc-shipping-zone-method-settings" href="admin.php?page=wc-settings&amp;tab=shipping&amp;instance_id={{ data.instance_id }}">{{{ data.title }}}</a> <a class="wc-shipping-zone-method-settings" href="admin.php?page=wc-settings&amp;tab=shipping&amp;instance_id={{ data.instance_id }}">{{{ data.title }}}</a>
<div class="row-actions"> <div class="row-actions">
<a class="wc-shipping-zone-method-settings" href="admin.php?page=wc-settings&amp;tab=shipping&amp;instance_id={{ data.instance_id }}"><?php _e( 'Edit', 'woocommerce' ); ?></a> | <a href="#" class="wc-shipping-zone-method-delete"><?php _e( 'Delete', 'woocommerce' ); ?></a> <a class="wc-shipping-zone-method-settings" href="admin.php?page=wc-settings&amp;tab=shipping&amp;instance_id={{ data.instance_id }}"><?php esc_html_e( 'Edit', 'woocommerce' ); ?></a> | <a href="#" class="wc-shipping-zone-method-delete"><?php esc_html_e( 'Delete', 'woocommerce' ); ?></a>
</div> </div>
</td> </td>
<td width="1%" class="wc-shipping-zone-method-enabled"><a href="#">{{{ data.enabled_icon }}}</a></td> <td width="1%" class="wc-shipping-zone-method-enabled"><a href="#">{{{ data.enabled_icon }}}</a></td>
@ -128,7 +134,7 @@ if ( ! defined( 'ABSPATH' ) ) {
); );
?></h1> ?></h1>
<button class="modal-close modal-close-link dashicons dashicons-no-alt"> <button class="modal-close modal-close-link dashicons dashicons-no-alt">
<span class="screen-reader-text"><?php _e( 'Close modal panel', 'woocommerce' ); ?></span> <span class="screen-reader-text"><?php esc_html_e( 'Close modal panel', 'woocommerce' ); ?></span>
</button> </button>
</header> </header>
<article class="wc-modal-shipping-method-settings"> <article class="wc-modal-shipping-method-settings">
@ -139,7 +145,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</article> </article>
<footer> <footer>
<div class="inner"> <div class="inner">
<button id="btn-ok" class="button button-primary button-large"><?php _e( 'Save changes', 'woocommerce' ); ?></button> <button id="btn-ok" class="button button-primary button-large"><?php esc_html_e( 'Save changes', 'woocommerce' ); ?></button>
</div> </div>
</footer> </footer>
</section> </section>
@ -153,9 +159,9 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="wc-backbone-modal-content"> <div class="wc-backbone-modal-content">
<section class="wc-backbone-modal-main" role="main"> <section class="wc-backbone-modal-main" role="main">
<header class="wc-backbone-modal-header"> <header class="wc-backbone-modal-header">
<h1><?php _e( 'Add shipping method', 'woocommerce' ); ?></h1> <h1><?php esc_html_e( 'Add shipping method', 'woocommerce' ); ?></h1>
<button class="modal-close modal-close-link dashicons dashicons-no-alt"> <button class="modal-close modal-close-link dashicons dashicons-no-alt">
<span class="screen-reader-text"><?php _e( 'Close modal panel', 'woocommerce' ); ?></span> <span class="screen-reader-text"><?php esc_html_e( 'Close modal panel', 'woocommerce' ); ?></span>
</button> </button>
</header> </header>
<article> <article>
@ -165,12 +171,12 @@ if ( ! defined( 'ABSPATH' ) ) {
<select name="add_method_id"> <select name="add_method_id">
<?php <?php
foreach ( WC()->shipping->load_shipping_methods() as $method ) { foreach ( WC()->shipping->load_shipping_methods() as $method ) {
if ( ! $method->supports( 'shipping-zones' ) ) { if ( ! $method->supports( 'shipping-zones' ) ) {
continue; continue;
}
echo '<option data-description="' . esc_attr( wp_kses_post( wpautop( $method->get_method_description() ) ) ) . '" value="' . esc_attr( $method->id ) . '">' . esc_attr( $method->get_method_title() ) . '</li>';
} }
echo '<option data-description="' . esc_attr( wp_kses_post( wpautop( $method->get_method_description() ) ) ) . '" value="' . esc_attr( $method->id ) . '">' . esc_attr( $method->get_method_title() ) . '</li>';
}
?> ?>
</select> </select>
</div> </div>
@ -178,7 +184,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</article> </article>
<footer> <footer>
<div class="inner"> <div class="inner">
<button id="btn-ok" class="button button-primary button-large"><?php _e( 'Add shipping method', 'woocommerce' ); ?></button> <button id="btn-ok" class="button button-primary button-large"><?php esc_html_e( 'Add shipping method', 'woocommerce' ); ?></button>
</div> </div>
</footer> </footer>
</section> </section>

View File

@ -2,7 +2,7 @@
/** /**
* Admin View: Edit Webhooks * Admin View: Edit Webhooks
* *
* @package WooCommerce/Admin/Webhooks/Views * @package WooCommerce\Admin\Webhooks\Views
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
@ -87,7 +87,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<tr valign="top" id="webhook-action-event-wrap"> <tr valign="top" id="webhook-action-event-wrap">
<th scope="row" class="titledesc"> <th scope="row" class="titledesc">
<label for="webhook_action_event"><?php esc_html_e( 'Action event', 'woocommerce' ); ?></label> <label for="webhook_action_event"><?php esc_html_e( 'Action event', 'woocommerce' ); ?></label>
<?php echo wc_help_tip( esc_html__( 'Enter the action that will trigger this webhook.', 'woocommerce' ) ); ?> <?php echo wc_help_tip( __( 'Enter the action that will trigger this webhook.', 'woocommerce' ) ); ?>
</th> </th>
<td class="forminp"> <td class="forminp">
<input name="webhook_action_event" id="webhook_action_event" type="text" class="input-text regular-input" value="<?php echo esc_attr( $topic_data['event'] ); ?>" /> <input name="webhook_action_event" id="webhook_action_event" type="text" class="input-text regular-input" value="<?php echo esc_attr( $topic_data['event'] ); ?>" />
@ -96,7 +96,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<tr valign="top" id="webhook-custom-topic-wrap"> <tr valign="top" id="webhook-custom-topic-wrap">
<th scope="row" class="titledesc"> <th scope="row" class="titledesc">
<label for="webhook_custom_topic"><?php esc_html_e( 'Custom topic', 'woocommerce' ); ?></label> <label for="webhook_custom_topic"><?php esc_html_e( 'Custom topic', 'woocommerce' ); ?></label>
<?php echo wc_help_tip( esc_html__( 'Enter the custom topic that will trigger this webhook.', 'woocommerce' ) ); ?> <?php echo wc_help_tip( __( 'Enter the custom topic that will trigger this webhook.', 'woocommerce' ) ); ?>
</th> </th>
<td class="forminp"> <td class="forminp">
<input name="webhook_custom_topic" id="webhook_custom_topic" type="text" class="input-text regular-input" value="<?php echo esc_attr( $webhook->get_topic() ); ?>" /> <input name="webhook_custom_topic" id="webhook_custom_topic" type="text" class="input-text regular-input" value="<?php echo esc_attr( $webhook->get_topic() ); ?>" />
@ -105,7 +105,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<tr valign="top"> <tr valign="top">
<th scope="row" class="titledesc"> <th scope="row" class="titledesc">
<label for="webhook_delivery_url"><?php esc_html_e( 'Delivery URL', 'woocommerce' ); ?></label> <label for="webhook_delivery_url"><?php esc_html_e( 'Delivery URL', 'woocommerce' ); ?></label>
<?php echo wc_help_tip( esc_html__( 'URL where the webhook payload is delivered.', 'woocommerce' ) ); ?> <?php echo wc_help_tip( __( 'URL where the webhook payload is delivered.', 'woocommerce' ) ); ?>
</th> </th>
<td class="forminp"> <td class="forminp">
<input name="webhook_delivery_url" id="webhook_delivery_url" type="text" class="input-text regular-input" value="<?php echo esc_attr( $webhook->get_delivery_url() ); ?>" /> <input name="webhook_delivery_url" id="webhook_delivery_url" type="text" class="input-text regular-input" value="<?php echo esc_attr( $webhook->get_delivery_url() ); ?>" />
@ -114,7 +114,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<tr valign="top"> <tr valign="top">
<th scope="row" class="titledesc"> <th scope="row" class="titledesc">
<label for="webhook_secret"><?php esc_html_e( 'Secret', 'woocommerce' ); ?></label> <label for="webhook_secret"><?php esc_html_e( 'Secret', 'woocommerce' ); ?></label>
<?php echo wc_help_tip( esc_html__( 'The secret key is used to generate a hash of the delivered webhook and provided in the request headers.', 'woocommerce' ) ); ?> <?php echo wc_help_tip( __( 'The secret key is used to generate a hash of the delivered webhook and provided in the request headers.', 'woocommerce' ) ); ?>
</th> </th>
<td class="forminp"> <td class="forminp">
<input name="webhook_secret" id="webhook_secret" type="text" class="input-text regular-input" value="<?php echo esc_attr( $webhook->get_secret() ); ?>" /> <input name="webhook_secret" id="webhook_secret" type="text" class="input-text regular-input" value="<?php echo esc_attr( $webhook->get_secret() ); ?>" />
@ -123,7 +123,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<tr valign="top"> <tr valign="top">
<th scope="row" class="titledesc"> <th scope="row" class="titledesc">
<label for="webhook_api_version"><?php esc_html_e( 'API Version', 'woocommerce' ); ?></label> <label for="webhook_api_version"><?php esc_html_e( 'API Version', 'woocommerce' ); ?></label>
<?php echo wc_help_tip( esc_html__( 'REST API version used in the webhook deliveries.', 'woocommerce' ) ); ?> <?php echo wc_help_tip( __( 'REST API version used in the webhook deliveries.', 'woocommerce' ) ); ?>
</th> </th>
<td class="forminp"> <td class="forminp">
<select name="webhook_api_version" id="webhook_api_version"> <select name="webhook_api_version" id="webhook_api_version">
@ -175,7 +175,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<tr valign="top"> <tr valign="top">
<td colspan="2" scope="row" style="padding-left: 0;"> <td colspan="2" scope="row" style="padding-left: 0;">
<p class="submit"> <p class="submit">
<input type="submit" class="button button-primary button-large" name="save" id="publish" accesskey="p" value="<?php esc_attr_e( 'Save webhook', 'woocommerce' ); ?>" /> <button type="submit" class="button button-primary button-large" name="save" id="publish" accesskey="p"><?php esc_html_e( 'Save webhook', 'woocommerce' ); ?></button>
<?php <?php
if ( $webhook->get_id() ) : if ( $webhook->get_id() ) :
$delete_url = wp_nonce_url( add_query_arg( array( $delete_url = wp_nonce_url( add_query_arg( array(

View File

@ -1,7 +1,10 @@
<?php <?php
/** /**
* Admin View: Product Export * Admin View: Product Export
*
* @package WooCommerce/Admin/Export
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
@ -33,9 +36,9 @@ $total_rows = $product_count->publish + $product_count->private + $variatio
<td> <td>
<select id="woocommerce-exporter-columns" class="woocommerce-exporter-columns wc-enhanced-select" style="width:100%;" multiple data-placeholder="<?php esc_attr_e( 'Export all columns', 'woocommerce' ); ?>"> <select id="woocommerce-exporter-columns" class="woocommerce-exporter-columns wc-enhanced-select" style="width:100%;" multiple data-placeholder="<?php esc_attr_e( 'Export all columns', 'woocommerce' ); ?>">
<?php <?php
foreach ( $exporter->get_default_column_names() as $column_id => $column_name ) { foreach ( $exporter->get_default_column_names() as $column_id => $column_name ) {
echo '<option value="' . esc_attr( $column_id ) . '">' . esc_html( $column_name ) . '</option>'; echo '<option value="' . esc_attr( $column_id ) . '">' . esc_html( $column_name ) . '</option>';
} }
?> ?>
<option value="downloads"><?php esc_html_e( 'Downloads', 'woocommerce' ); ?></option> <option value="downloads"><?php esc_html_e( 'Downloads', 'woocommerce' ); ?></option>
<option value="attributes"><?php esc_html_e( 'Attributes', 'woocommerce' ); ?></option> <option value="attributes"><?php esc_html_e( 'Attributes', 'woocommerce' ); ?></option>
@ -49,9 +52,9 @@ $total_rows = $product_count->publish + $product_count->private + $variatio
<td> <td>
<select id="woocommerce-exporter-types" class="woocommerce-exporter-types wc-enhanced-select" style="width:100%;" multiple data-placeholder="<?php esc_attr_e( 'Export all products', 'woocommerce' ); ?>"> <select id="woocommerce-exporter-types" class="woocommerce-exporter-types wc-enhanced-select" style="width:100%;" multiple data-placeholder="<?php esc_attr_e( 'Export all products', 'woocommerce' ); ?>">
<?php <?php
foreach ( wc_get_product_types() as $value => $label ) { foreach ( wc_get_product_types() as $value => $label ) {
echo '<option value="' . esc_attr( $value ) . '">' . esc_html( $label ) . '</option>'; echo '<option value="' . esc_attr( $value ) . '">' . esc_html( $label ) . '</option>';
} }
?> ?>
<option value="variation"><?php esc_html_e( 'Product variations', 'woocommerce' ); ?></option> <option value="variation"><?php esc_html_e( 'Product variations', 'woocommerce' ); ?></option>
</select> </select>
@ -71,7 +74,7 @@ $total_rows = $product_count->publish + $product_count->private + $variatio
<progress class="woocommerce-exporter-progress" max="100" value="0"></progress> <progress class="woocommerce-exporter-progress" max="100" value="0"></progress>
</section> </section>
<div class="wc-actions"> <div class="wc-actions">
<input type="submit" class="woocommerce-exporter-button button button-primary" value="<?php esc_attr_e( 'Generate CSV', 'woocommerce' ); ?>" /> <button type="submit" class="woocommerce-exporter-button button button-primary" value="<?php esc_attr_e( 'Generate CSV', 'woocommerce' ); ?>"><?php esc_html_e( 'Generate CSV', 'woocommerce' ); ?></button>
</div> </div>
</form> </form>
</div> </div>

View File

@ -1,14 +1,17 @@
<?php <?php
/** /**
* Admin View: Page - Status Database Logs * Admin View: Page - Status Database Logs
*
* @package WooCommerce/Admin/Logs
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; 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(); ?> <?php $log_table_list->display(); ?>
<input type="hidden" name="page" value="wc-status" /> <input type="hidden" name="page" value="wc-status" />

View File

@ -1,6 +1,8 @@
<?php <?php
/** /**
* Admin View: Page - Status Logs * Admin View: Page - Status Logs
*
* @package WooCommerce/Admin/Logs
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
@ -19,13 +21,13 @@ if ( ! defined( 'ABSPATH' ) ) {
</h2> </h2>
</div> </div>
<div class="alignright"> <div class="alignright">
<form action="<?php echo admin_url( 'admin.php?page=wc-status&tab=logs' ); ?>" method="post"> <form action="<?php echo esc_url( admin_url( 'admin.php?page=wc-status&tab=logs' ) ); ?>" method="post">
<select name="log_file"> <select name="log_file">
<?php foreach ( $logs as $log_key => $log_file ) : ?> <?php foreach ( $logs as $log_key => $log_file ) : ?>
<option value="<?php echo esc_attr( $log_key ); ?>" <?php selected( sanitize_title( $viewed_log ), $log_key ); ?>><?php echo esc_html( $log_file ); ?> (<?php echo date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), filemtime( WC_LOG_DIR . $log_file ) ); ?>)</option> <option value="<?php echo esc_attr( $log_key ); ?>" <?php selected( sanitize_title( $viewed_log ), $log_key ); ?>><?php echo esc_html( $log_file ); ?> (<?php echo esc_html( date_i18n( get_option( 'date_format' ) ) . ' ' . get_option( 'time_format' ), filemtime( WC_LOG_DIR . $log_file ) ); ?>)</option>
<?php endforeach; ?> <?php endforeach; ?>
</select> </select>
<input type="submit" class="button" value="<?php esc_attr_e( 'View', 'woocommerce' ); ?>" /> <button type="submit" class="button" value="<?php esc_attr_e( 'View', 'woocommerce' ); ?>"><?php esc_html_e( 'View', 'woocommerce' ); ?></button>
</form> </form>
</div> </div>
<div class="clear"></div> <div class="clear"></div>
@ -34,5 +36,5 @@ if ( ! defined( 'ABSPATH' ) ) {
<pre><?php echo esc_html( file_get_contents( WC_LOG_DIR . $viewed_log ) ); ?></pre> <pre><?php echo esc_html( file_get_contents( WC_LOG_DIR . $viewed_log ) ); ?></pre>
</div> </div>
<?php else : ?> <?php else : ?>
<div class="updated woocommerce-message inline"><p><?php _e( 'There are currently no logs to view.', 'woocommerce' ); ?></p></div> <div class="updated woocommerce-message inline"><p><?php esc_html_e( 'There are currently no logs to view.', 'woocommerce' ); ?></p></div>
<?php endif; ?> <?php endif; ?>

View File

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

View File

@ -41,7 +41,7 @@ if ( ! $tab_exists ) {
?> ?>
<p class="submit"> <p class="submit">
<?php if ( empty( $GLOBALS['hide_save_button'] ) ) : ?> <?php if ( empty( $GLOBALS['hide_save_button'] ) ) : ?>
<input name="save" class="button-primary woocommerce-save-button" type="submit" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>" /> <button name="save" class="button-primary woocommerce-save-button" type="submit" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>"><?php esc_html_e( 'Save changes', 'woocommerce' ); ?></button>
<?php endif; ?> <?php endif; ?>
<?php wp_nonce_field( 'woocommerce-settings' ); ?> <?php wp_nonce_field( 'woocommerce-settings' ); ?>
</p> </p>

View File

@ -308,6 +308,6 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php do_action( 'woocommerce_product_bulk_edit_end' ); ?> <?php do_action( 'woocommerce_product_bulk_edit_end' ); ?>
<input type="hidden" name="woocommerce_bulk_edit" value="1" /> <input type="hidden" name="woocommerce_bulk_edit" value="1" />
<input type="hidden" name="woocommerce_bulk_edit_nonce" value="<?php echo wp_create_nonce( 'woocommerce_bulk_edit_nonce' ); ?>" /> <input type="hidden" name="woocommerce_quick_edit_nonce" value="<?php echo wp_create_nonce( 'woocommerce_quick_edit_nonce' ); ?>" />
</div> </div>
</fieldset> </fieldset>

View File

@ -11,7 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<div id="message" class="updated woocommerce-message wc-connect"> <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> <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"> <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="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> <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

@ -1,10 +1,12 @@
<?php <?php
/** /**
* Admin View: Report by Date (with date filters) * Admin View: Report by Date (with date filters)
*
* @package WooCommerce/Admin/Reporting
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly exit; // Exit if accessed directly.
} }
?> ?>
@ -13,14 +15,16 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="postbox"> <div class="postbox">
<?php if ( 'custom' === $current_range && isset( $_GET['start_date'], $_GET['end_date'] ) ) : ?> <?php if ( 'custom' === $current_range && isset( $_GET['start_date'], $_GET['end_date'] ) ) : ?>
<h3 class="screen-reader-text"><?php <h3 class="screen-reader-text">
<?php
/* translators: 1: start date 2: end date */ /* translators: 1: start date 2: end date */
printf( printf(
esc_html__( 'From %1$s to %2$s', 'woocommerce' ), esc_html__( 'From %1$s to %2$s', 'woocommerce' ),
esc_html( wc_clean( $_GET['start_date'] ) ), esc_html( wc_clean( wp_unslash( $_GET['start_date'] ) ) ),
esc_html( wc_clean( $_GET['end_date'] ) ) esc_html( wc_clean( wp_unslash( $_GET['end_date'] ) ) )
); );
?></h3> ?>
</h3>
<?php else : ?> <?php else : ?>
<h3 class="screen-reader-text"><?php echo esc_html( $ranges[ $current_range ] ); ?></h3> <h3 class="screen-reader-text"><?php echo esc_html( $ranges[ $current_range ] ); ?></h3>
<?php endif; ?> <?php endif; ?>
@ -29,31 +33,31 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php $this->get_export_button(); ?> <?php $this->get_export_button(); ?>
<ul> <ul>
<?php <?php
foreach ( $ranges as $range => $name ) { foreach ( $ranges as $range => $name ) {
echo '<li class="' . ( $current_range == $range ? 'active' : '' ) . '"><a href="' . esc_url( remove_query_arg( array( 'start_date', 'end_date' ), add_query_arg( 'range', $range ) ) ) . '">' . $name . '</a></li>'; echo '<li class="' . ( $current_range == $range ? 'active' : '' ) . '"><a href="' . esc_url( remove_query_arg( array( 'start_date', 'end_date' ), add_query_arg( 'range', $range ) ) ) . '">' . esc_html( $name ) . '</a></li>';
} }
?> ?>
<li class="custom <?php echo ( 'custom' === $current_range ) ? 'active' : ''; ?>"> <li class="custom <?php echo ( 'custom' === $current_range ) ? 'active' : ''; ?>">
<?php _e( 'Custom:', 'woocommerce' ); ?> <?php esc_html_e( 'Custom:', 'woocommerce' ); ?>
<form method="GET"> <form method="GET">
<div> <div>
<?php <?php
// Maintain query string // Maintain query string.
foreach ( $_GET as $key => $value ) { foreach ( $_GET as $key => $value ) {
if ( is_array( $value ) ) { if ( is_array( $value ) ) {
foreach ( $value as $v ) { foreach ( $value as $v ) {
echo '<input type="hidden" name="' . esc_attr( sanitize_text_field( $key ) ) . '[]" value="' . esc_attr( sanitize_text_field( $v ) ) . '" />'; echo '<input type="hidden" name="' . esc_attr( sanitize_text_field( $key ) ) . '[]" value="' . esc_attr( sanitize_text_field( $v ) ) . '" />';
}
} else {
echo '<input type="hidden" name="' . esc_attr( sanitize_text_field( $key ) ) . '" value="' . esc_attr( sanitize_text_field( $value ) ) . '" />';
} }
} else {
echo '<input type="hidden" name="' . esc_attr( sanitize_text_field( $key ) ) . '" value="' . esc_attr( sanitize_text_field( $value ) ) . '" />';
} }
}
?> ?>
<input type="hidden" name="range" value="custom" /> <input type="hidden" name="range" value="custom" />
<input type="text" size="11" placeholder="yyyy-mm-dd" value="<?php echo ( ! empty( $_GET['start_date'] ) ) ? esc_attr( $_GET['start_date'] ) : ''; ?>" name="start_date" class="range_datepicker from" /> <input type="text" size="11" placeholder="yyyy-mm-dd" value="<?php echo ( ! empty( $_GET['start_date'] ) ) ? esc_attr( wp_unslash( $_GET['start_date'] ) ) : ''; ?>" name="start_date" class="range_datepicker from" /><?php //@codingStandardsIgnoreLine ?>
<span>&ndash;</span> <span>&ndash;</span>
<input type="text" size="11" placeholder="yyyy-mm-dd" value="<?php echo ( ! empty( $_GET['end_date'] ) ) ? esc_attr( $_GET['end_date'] ) : ''; ?>" name="end_date" class="range_datepicker to" /> <input type="text" size="11" placeholder="yyyy-mm-dd" value="<?php echo ( ! empty( $_GET['end_date'] ) ) ? esc_attr( wp_unslash( $_GET['end_date'] ) ) : ''; ?>" name="end_date" class="range_datepicker to" /><?php //@codingStandardsIgnoreLine ?>
<input type="submit" class="button" value="<?php esc_attr_e( 'Go', 'woocommerce' ); ?>" /> <button type="submit" class="button" value="<?php esc_attr_e( 'Go', 'woocommerce' ); ?>"><?php esc_html_e( 'Go', 'woocommerce' ); ?></button>
<?php wp_nonce_field( 'custom_range', 'wc_reports_nonce', false ); ?> <?php wp_nonce_field( 'custom_range', 'wc_reports_nonce', false ); ?>
</div> </div>
</form> </form>
@ -66,17 +70,18 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( $legends = $this->get_chart_legend() ) : ?> <?php if ( $legends = $this->get_chart_legend() ) : ?>
<ul class="chart-legend"> <ul class="chart-legend">
<?php foreach ( $legends as $legend ) : ?> <?php foreach ( $legends as $legend ) : ?>
<?php // @codingStandardsIgnoreLine ?> <?php // @codingStandardsIgnoreStart ?>
<li style="border-color: <?php echo $legend['color']; ?>" <?php if ( isset( $legend['highlight_series'] ) ) echo 'class="highlight_series ' . ( isset( $legend['placeholder'] ) ? 'tips' : '' ) . '" data-series="' . esc_attr( $legend['highlight_series'] ) . '"'; ?> data-tip="<?php echo isset( $legend['placeholder'] ) ? $legend['placeholder'] : ''; ?>"> <li style="border-color: <?php echo $legend['color']; ?>" <?php if ( isset( $legend['highlight_series'] ) ) echo 'class="highlight_series ' . ( isset( $legend['placeholder'] ) ? 'tips' : '' ) . '" data-series="' . esc_attr( $legend['highlight_series'] ) . '"'; ?> data-tip="<?php echo isset( $legend['placeholder'] ) ? $legend['placeholder'] : ''; ?>">
<?php echo $legend['title']; ?> <?php echo $legend['title']; ?>
</li> </li>
<?php // @codingStandardsIgnoreEnd ?>
<?php endforeach; ?> <?php endforeach; ?>
</ul> </ul>
<?php endif; ?> <?php endif; ?>
<ul class="chart-widgets"> <ul class="chart-widgets">
<?php foreach ( $this->get_chart_widgets() as $widget ) : ?> <?php foreach ( $this->get_chart_widgets() as $widget ) : ?>
<li class="chart-widget"> <li class="chart-widget">
<?php if ( $widget['title'] ) : ?><h4><?php echo $widget['title']; ?></h4><?php endif; ?> <?php if ( $widget['title'] ) : ?><h4><?php echo esc_html( $widget['title'] ); ?></h4><?php endif; ?>
<?php call_user_func( $widget['callback'] ); ?> <?php call_user_func( $widget['callback'] ); ?>
</li> </li>
<?php endforeach; ?> <?php endforeach; ?>

View File

@ -234,7 +234,8 @@ function wc_save_order_items( $order_id, $items ) {
if ( isset( $items['meta_key'][ $item_id ], $items['meta_value'][ $item_id ] ) ) { if ( isset( $items['meta_key'][ $item_id ], $items['meta_value'][ $item_id ] ) ) {
foreach ( $items['meta_key'][ $item_id ] as $meta_id => $meta_key ) { foreach ( $items['meta_key'][ $item_id ] as $meta_id => $meta_key ) {
$meta_value = isset( $items['meta_value'][ $item_id ][ $meta_id ] ) ? wp_unslash( $items['meta_value'][ $item_id ][ $meta_id ] ) : ''; $meta_key = wp_unslash( $meta_key );
$meta_value = isset( $items['meta_value'][ $item_id ][ $meta_id ] ) ? wp_unslash( $items['meta_value'][ $item_id ][ $meta_id ] ): '';
if ( '' === $meta_key && '' === $meta_value ) { if ( '' === $meta_key && '' === $meta_value ) {
if ( ! strstr( $meta_id, 'new-' ) ) { if ( ! strstr( $meta_id, 'new-' ) ) {

View File

@ -82,7 +82,7 @@ class WC_REST_Customer_Downloads_Controller extends WC_REST_Customer_Downloads_V
'type' => 'object', 'type' => 'object',
'properties' => array( 'properties' => array(
'download_id' => array( 'download_id' => array(
'description' => __( 'Download ID (MD5).', 'woocommerce' ), 'description' => __( 'Download ID.', 'woocommerce' ),
'type' => 'string', 'type' => 'string',
'context' => array( 'view' ), 'context' => array( 'view' ),
'readonly' => true, '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 * @return WP_Error|WP_REST_Response
*/ */
public function prepare_object_for_response( $object, $request ) { public function prepare_object_for_response( $object, $request ) {
$this->request = $request; $this->request = $request;
$order = wc_get_order( (int) $request['order_id'] ); $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 ) { if ( ! $order ) {
return new WP_Error( 'woocommerce_rest_invalid_order_id', __( 'Invalid order ID.', 'woocommerce' ), 404 ); 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 * @return WP_REST_Response
*/ */
public function prepare_object_for_response( $object, $request ) { public function prepare_object_for_response( $object, $request ) {
$this->request = $request; $this->request = $request;
$data = $this->get_formatted_item_data( $object ); $this->request['dp'] = is_null( $this->request['dp'] ) ? wc_get_price_decimals() : absint( $this->request['dp'] );
$context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $data = $this->get_formatted_item_data( $object );
$data = $this->add_additional_fields_to_object( $data, $request ); $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
$data = $this->filter_response_by_context( $data, $context ); $data = $this->add_additional_fields_to_object( $data, $request );
$response = rest_ensure_response( $data ); $data = $this->filter_response_by_context( $data, $context );
$response = rest_ensure_response( $data );
$response->add_links( $this->prepare_links( $object, $request ) ); $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. * 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 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 * @return WC_Order_Item_Product
* @throws WC_REST_Exception Invalid data, server error. * @throws WC_REST_Exception Invalid data, server error.
*/ */
protected function prepare_line_items( $posted, $action = 'create' ) { protected function prepare_line_items( $posted, $action = 'create', $item = null ) {
$item = new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ); $item = is_null( $item ) ? new WC_Order_Item_Product( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item;
$product = wc_get_product( $this->get_product_id( $posted ) ); $product = wc_get_product( $this->get_product_id( $posted ) );
if ( $product !== $item->get_product() ) { 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. * 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 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 * @return WC_Order_Item_Shipping
* @throws WC_REST_Exception Invalid data, server error. * @throws WC_REST_Exception Invalid data, server error.
*/ */
protected function prepare_shipping_lines( $posted, $action ) { protected function prepare_shipping_lines( $posted, $action = 'create', $item = null ) {
$item = new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ); $item = is_null( $item ) ? new WC_Order_Item_Shipping( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item;
if ( 'create' === $action ) { if ( 'create' === $action ) {
if ( empty( $posted['method_id'] ) ) { 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. * 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 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 * @return WC_Order_Item_Fee
* @throws WC_REST_Exception Invalid data, server error. * @throws WC_REST_Exception Invalid data, server error.
*/ */
protected function prepare_fee_lines( $posted, $action ) { protected function prepare_fee_lines( $posted, $action = 'create', $item = null ) {
$item = new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ); $item = is_null( $item ) ? new WC_Order_Item_Fee( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item;
if ( 'create' === $action ) { if ( 'create' === $action ) {
if ( empty( $posted['name'] ) ) { 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. * 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 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 * @return WC_Order_Item_Coupon
* @throws WC_REST_Exception Invalid data, server error. * @throws WC_REST_Exception Invalid data, server error.
*/ */
protected function prepare_coupon_lines( $posted, $action ) { protected function prepare_coupon_lines( $posted, $action = 'create', $item = null ) {
$item = new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ); $item = is_null( $item ) ? new WC_Order_Item_Coupon( ! empty( $posted['id'] ) ? $posted['id'] : '' ) : $item;
if ( 'create' === $action ) { if ( 'create' === $action ) {
if ( empty( $posted['code'] ) ) { 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 * When updating, the item ID provided is checked to ensure it is associated
* with the order. * with the order.
* *
* @param WC_Order $order order * @param WC_Order $order order object.
* @param string $item_type * @param string $item_type The item type.
* @param array $posted item provided in the request body * @param array $posted item provided in the request body.
* @throws WC_REST_Exception If item ID is not associated with order * @throws WC_REST_Exception If item ID is not associated with order.
*/ */
protected function set_item( $order, $item_type, $posted ) { protected function set_item( $order, $item_type, $posted ) {
global $wpdb; global $wpdb;
@ -725,29 +726,23 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
} }
$method = 'prepare_' . $item_type; $method = 'prepare_' . $item_type;
$item = null;
// Verify provided line item ID is associated with order. // Verify provided line item ID is associated with order.
if ( 'update' === $action ) { if ( 'update' === $action ) {
$result = $wpdb->get_row( $item = $order->get_item( absint( $posted['id'] ), false );
$wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d AND order_id = %d",
absint( $posted['id'] ), if ( ! $item ) {
absint( $order->get_id() )
) );
if ( is_null( $result ) ) {
throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 ); throw new WC_REST_Exception( 'woocommerce_rest_invalid_item_id', __( 'Order item ID provided is not associated with order.', 'woocommerce' ), 400 );
} }
} }
// Prepare item data // Prepare item data.
$item = $this->$method( $posted, $action ); $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 ); 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 ) { if ( 'create' === $action ) {
$order->add_item( $item ); $order->add_item( $item );
} else { } else {
@ -1647,7 +1642,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
'validate_callback' => 'rest_validate_request_arg', 'validate_callback' => 'rest_validate_request_arg',
); );
$params['dp'] = array( $params['dp'] = array(
'default' => 2, 'default' => wc_get_price_decimals(),
'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ),
'type' => 'integer', 'type' => 'integer',
'sanitize_callback' => 'absint', 'sanitize_callback' => 'absint',

View File

@ -2029,7 +2029,7 @@ class WC_REST_Products_Controller extends WC_REST_Legacy_Products_Controller {
'validate_callback' => 'rest_validate_request_arg', 'validate_callback' => 'rest_validate_request_arg',
); );
$params['sku'] = array( $params['sku'] = array(
'description' => __( 'Limit result set to products with a specific SKU.', 'woocommerce' ), 'description' => __( 'Limit result set to products with specific SKU(s). Use commas to separate.', 'woocommerce' ),
'type' => 'string', 'type' => 'string',
'sanitize_callback' => 'sanitize_text_field', 'sanitize_callback' => 'sanitize_text_field',
'validate_callback' => 'rest_validate_request_arg', 'validate_callback' => 'rest_validate_request_arg',

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 * 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. * to make sure we return these consistently the same we accept them.
* *
* @todo remove in 4.0
* @since 3.0.0 * @since 3.0.0
* @param array $setting * @param array $setting
* @return array * @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). 'radio', // Validates with validate_setting_radio_field (-> validate_setting_select_field).
'checkbox', // Validates with validate_setting_checkbox_field. 'checkbox', // Validates with validate_setting_checkbox_field.
'image_width', // Validates with validate_setting_image_width_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', 'sanitize_callback' => 'sanitize_text_field',
), ),
'context' => array( 'view', 'edit' ), '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, 'readonly' => true,
), ),
'options' => array( '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 ), 'version_latest' => WC_Admin_Status::get_latest_theme_version( $active_theme ),
'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ),
'is_child_theme' => is_child_theme(), '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_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ),
'has_outdated_templates' => $outdated_templates, 'has_outdated_templates' => $outdated_templates,
'overrides' => $override_files, '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. * that don't have address indexes yet.
*/ */
$sql = "INSERT INTO {$wpdb->postmeta}( post_id, meta_key, meta_value ) $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} 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} 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' ) 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='%3\$s' ) ) AND post_id IN ( SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='%s' ) )
GROUP BY post_id"; 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, '_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' ) ); $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 ); $message = sprintf( __( '%d indexes added', 'woocommerce' ), $rows );
break; break;

View File

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

View File

@ -619,7 +619,8 @@ class WC_API_Server {
* @return string * @return string
*/ */
public function get_raw_data() { 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', '>=' ) ) { if ( function_exists( 'phpversion' ) && version_compare( phpversion(), '5.6', '>=' ) ) {
return file_get_contents( 'php://input' ); return file_get_contents( 'php://input' );
} }
@ -633,6 +634,7 @@ class WC_API_Server {
} }
return $HTTP_RAW_POST_DATA; return $HTTP_RAW_POST_DATA;
// @codingStandardsIgnoreEnd
} }
/** /**

View File

@ -651,7 +651,8 @@ class WC_API_Server {
* @return string * @return string
*/ */
public function get_raw_data() { 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', '>=' ) ) { if ( function_exists( 'phpversion' ) && version_compare( phpversion(), '5.6', '>=' ) ) {
return file_get_contents( 'php://input' ); return file_get_contents( 'php://input' );
} }
@ -665,6 +666,7 @@ class WC_API_Server {
} }
return $HTTP_RAW_POST_DATA; return $HTTP_RAW_POST_DATA;
// @codingStandardsIgnoreEnd
} }
/** /**

View File

@ -658,7 +658,8 @@ class WC_API_Server {
* @return string * @return string
*/ */
public function get_raw_data() { 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', '>=' ) ) { if ( function_exists( 'phpversion' ) && version_compare( phpversion(), '5.6', '>=' ) ) {
return file_get_contents( 'php://input' ); return file_get_contents( 'php://input' );
} }
@ -672,6 +673,7 @@ class WC_API_Server {
} }
return $HTTP_RAW_POST_DATA; 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 ); 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( $data = array(
'id' => $refund->get_id(), '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 = parent::get_collection_params();
$params['dp'] = array( $params['dp'] = array(
'default' => 2, 'default' => wc_get_price_decimals(),
'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ),
'type' => 'integer', 'type' => 'integer',
'sanitize_callback' => 'absint', '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 ) { public function prepare_item_for_response( $post, $request ) {
$order = wc_get_order( $post ); $order = wc_get_order( $post );
$dp = $request['dp']; $dp = is_null( $request['dp'] ) ? wc_get_price_decimals() : absint( $request['dp'] );
$data = array( $data = array(
'id' => $order->get_id(), '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', 'validate_callback' => 'rest_validate_request_arg',
); );
$params['dp'] = array( $params['dp'] = array(
'default' => 2, 'default' => wc_get_price_decimals(),
'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ), 'description' => __( 'Number of decimal points to use in each resource.', 'woocommerce' ),
'type' => 'integer', 'type' => 'integer',
'sanitize_callback' => 'absint', 'sanitize_callback' => 'absint',

View File

@ -59,7 +59,7 @@ class WC_AJAX {
@header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) ); @header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
@header( 'X-Robots-Tag: noindex' ); @header( 'X-Robots-Tag: noindex' );
send_nosniff_header(); send_nosniff_header();
nocache_headers(); wc_nocache_headers();
status_header( 200 ); status_header( 200 );
} }
@ -99,6 +99,7 @@ class WC_AJAX {
'get_customer_location' => true, 'get_customer_location' => true,
'feature_product' => false, 'feature_product' => false,
'mark_order_status' => false, 'mark_order_status' => false,
'get_order_details' => false,
'add_attribute' => false, 'add_attribute' => false,
'add_new_attribute' => false, 'add_new_attribute' => false,
'remove_variation' => false, 'remove_variation' => false,
@ -472,6 +473,97 @@ class WC_AJAX {
exit; exit;
} }
/**
* Get order details.
*/
public static function get_order_details() {
check_admin_referer( 'woocommerce-preview-order', 'security' );
if ( ! current_user_can( 'edit_shop_orders' ) ) {
wp_die( -1 );
}
if ( $order = wc_get_order( absint( $_GET['order_id'] ) ) ) {
ob_start();
$hidden_order_itemmeta = apply_filters( 'woocommerce_hidden_order_itemmeta', array(
'_qty',
'_tax_class',
'_product_id',
'_variation_id',
'_line_subtotal',
'_line_subtotal_tax',
'_line_total',
'_line_tax',
'method_id',
'cost',
) );
?>
<div class="wc-order-preview__table-wrapper">
<table cellspacing="0" class="wc-order-preview__table">
<tr>
<th><?php _e( 'Product', 'woocommerce' ); ?></th>
<th><?php _e( 'Quantity', 'woocommerce' ); ?></th>
<th><?php _e( 'Tax', 'woocommerce' ); ?></th>
<th><?php _e( 'Total', 'woocommerce' ); ?></th>
</tr>
<?php
foreach ( $order->get_items() as $item_id => $item ) {
if ( apply_filters( 'woocommerce_order_item_visible', true, $item ) ) {
?>
<tr class="<?php echo esc_attr( apply_filters( 'woocommerce_order_item_class', 'order_item', $item, $order ) ); ?>">
<td><?php
echo apply_filters( 'woocommerce_order_item_name', $item->get_name(), $item, false );
if ( is_callable( array( $item, 'get_product' ) ) && ( $product = $item->get_product() ) && is_object( $product ) && $product->get_sku() ) {
echo '<div class="wc-order-item-sku">' . esc_html( $product->get_sku() ) . '</div>';
}
if ( $meta_data = $item->get_formatted_meta_data( '' ) ) : ?>
<table cellspacing="0" class="wc-order-item-meta">
<?php foreach ( $meta_data as $meta_id => $meta ) :
if ( in_array( $meta->key, $hidden_order_itemmeta ) ) {
continue;
}
?>
<tr>
<th><?php echo wp_kses_post( $meta->display_key ); ?>:</th>
<td><?php echo wp_kses_post( force_balance_tags( $meta->display_value ) ); ?></td>
</tr>
<?php endforeach; ?>
</table>
<?php endif;
?></td>
<td><?php echo esc_html( $item->get_quantity() ); ?></td>
<td><?php echo wc_price( $item->get_total_tax(), array( 'currency' => $order->get_currency() ) );; ?></td>
<td><?php echo wc_price( $item->get_total(), array( 'currency' => $order->get_currency() ) );; ?></td>
</tr>
<?php
}
}
?>
</table>
</div>
<?php
$item_html = ob_get_clean();
wp_send_json_success( array(
'data' => $order->get_data(),
'order_number' => $order->get_order_number(),
'item_html' => $item_html,
'ship_to_billing' => wc_ship_to_billing_address_only(),
'needs_shipping' => $order->needs_shipping_address(),
'formatted_billing_address' => ( $address = $order->get_formatted_billing_address() ) ? $address : __( 'N/A', 'woocommerce' ),
'formatted_shipping_address' => ( $address = $order->get_formatted_shipping_address() ) ? $address: __( 'N/A', 'woocommerce' ),
'shipping_address_map_url' => $order->get_shipping_address_map_url(),
'payment_via' => $order->get_payment_method_title() . ( $order->get_transaction_id() ? ' (' . $order->get_transaction_id() . ')' : '' ),
'shipping_via' => $order->get_shipping_method(),
) );
}
exit;
}
/** /**
* Add an attribute row. * Add an attribute row.
*/ */
@ -580,14 +672,13 @@ class WC_AJAX {
* Add variation via ajax function. * Add variation via ajax function.
*/ */
public static function add_variation() { public static function add_variation() {
check_ajax_referer( 'add-variation', 'security' ); check_ajax_referer( 'add-variation', 'security' );
if ( ! current_user_can( 'edit_products' ) ) { if ( ! current_user_can( 'edit_products' ) ) {
wp_die( -1 ); 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'] ); $product_id = intval( $_POST['post_id'] );
$post = get_post( $product_id ); $post = get_post( $product_id );
@ -595,6 +686,7 @@ class WC_AJAX {
$product_object = wc_get_product( $product_id ); $product_object = wc_get_product( $product_id );
$variation_object = new WC_Product_Variation(); $variation_object = new WC_Product_Variation();
$variation_object->set_parent_id( $product_id ); $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_id = $variation_object->save();
$variation = get_post( $variation_id ); $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. $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(); ob_start();
// No cache headers. // No cache headers.
nocache_headers(); wc_nocache_headers();
// Clean the API request. // Clean the API request.
$api_request = $wp->query_vars['wc-api']; $api_request = $wp->query_vars['wc-api'];

View File

@ -1,9 +1,4 @@
<?php <?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/** /**
* WC_Cache_Helper class. * WC_Cache_Helper class.
* *
@ -13,6 +8,14 @@ if ( ! defined( 'ABSPATH' ) ) {
* @category Class * @category Class
* @author WooThemes * @author WooThemes
*/ */
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC_Cache_Helper.
*/
class WC_Cache_Helper { class WC_Cache_Helper {
/** /**
@ -20,18 +23,19 @@ class WC_Cache_Helper {
*/ */
public static function init() { public static function init() {
add_action( 'template_redirect', array( __CLASS__, 'geolocation_ajax_redirect' ) ); 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( 'admin_notices', array( __CLASS__, 'notices' ) );
add_action( 'delete_version_transients', array( __CLASS__, 'delete_version_transients' ) ); 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. * 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 * @return string
*/ */
public static function get_cache_prefix( $group ) { 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 ); $prefix = wp_cache_get( 'wc_' . $group . '_cache_prefix', $group );
if ( false === $prefix ) { if ( false === $prefix ) {
@ -44,7 +48,8 @@ class WC_Cache_Helper {
/** /**
* Increment group cache prefix (invalidates cache). * Increment group cache prefix (invalidates cache).
* @param string $group *
* @param string $group Group of cache to clear.
*/ */
public static function incr_cache_prefix( $group ) { public static function incr_cache_prefix( $group ) {
wp_cache_incr( 'wc_' . $group . '_cache_prefix', 1, $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. * Get a hash of the customer location.
*
* @return string * @return string
*/ */
public static function geolocation_ajax_get_location_hash() { public static function geolocation_ajax_get_location_hash() {
@ -64,22 +70,37 @@ class WC_Cache_Helper {
return substr( md5( implode( '', $location ) ), 0, 12 ); 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. * 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. * This prevents caching of the wrong data for this request.
*/ */
public static function geolocation_ajax_redirect() { 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(); $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 ) { if ( empty( $current_hash ) || $current_hash !== $location_hash ) {
global $wp; global $wp;
$redirect_url = trailingslashit( home_url( $wp->request ) ); $redirect_url = trailingslashit( home_url( $wp->request ) );
if ( ! empty( $_SERVER['QUERY_STRING'] ) ) { if ( ! empty( $_SERVER['QUERY_STRING'] ) ) { // WPCS: Input var ok.
$redirect_url = add_query_arg( $_SERVER['QUERY_STRING'], '', $redirect_url ); $redirect_url = add_query_arg( wp_unslash( $_SERVER['QUERY_STRING'] ), '', $redirect_url ); // WPCS: sanitization ok, Input var ok.
} }
if ( ! get_option( 'permalink_structure' ) ) { if ( ! get_option( 'permalink_structure' ) ) {
@ -110,9 +131,9 @@ class WC_Cache_Helper {
* Raised in issue https://github.com/woocommerce/woocommerce/issues/5777. * Raised in issue https://github.com/woocommerce/woocommerce/issues/5777.
* Adapted from ideas in http://tollmanz.com/invalidation-schemes/. * Adapted from ideas in http://tollmanz.com/invalidation-schemes/.
* *
* @param string $group Name for the group of transients we need to invalidate * @param string $group Name for the group of transients we need to invalidate.
* @param boolean $refresh true to force a new version * @param boolean $refresh true to force a new version.
* @return string transient version based on time(), 10 digits * @return string transient version based on time(), 10 digits.
*/ */
public static function get_transient_version( $group, $refresh = false ) { public static function get_transient_version( $group, $refresh = false ) {
$transient_name = $group . '-transient-version'; $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. * Note; this only works on transients appended with the transient version, and when object caching is not being used.
* *
* @since 2.3.10 * @since 2.3.10
* * @param string $version Version of the transient to remove.
* @param string $version
*/ */
public static function delete_version_transients( $version = '' ) { public static function delete_version_transients( $version = '' ) {
if ( ! wp_using_ext_object_cache() && ! empty( $version ) ) { if ( ! wp_using_ext_object_cache() && ! empty( $version ) ) {
global $wpdb; global $wpdb;
$limit = apply_filters( 'woocommerce_delete_version_transients_limit', 1000 ); $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 rows is equal to limit, there are more rows to delete. Delete in 10 secs.
if ( $affected === $limit ) { 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. * Set constants to prevent caching by some plugins.
* *
* Hooked into nocache_headers filter but does not change headers. * @param mixed $return Value to return. Previously hooked into a filter.
* * @return mixed
* @param array $value
* @return array
*/ */
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( 'DONOTCACHEPAGE', true );
wc_maybe_define_constant( 'DONOTCACHEOBJECT', true ); wc_maybe_define_constant( 'DONOTCACHEOBJECT', true );
wc_maybe_define_constant( 'DONOTCACHEDB', true ); wc_maybe_define_constant( 'DONOTCACHEDB', true );
return $value; return $return;
} }
/** /**
* notices function. * Notices function.
*/ */
public static function notices() { public static function notices() {
if ( ! function_exists( 'w3tc_pgcache_flush' ) || ! function_exists( 'w3_instance' ) ) { if ( ! function_exists( 'w3tc_pgcache_flush' ) || ! function_exists( 'w3_instance' ) ) {
@ -190,10 +193,10 @@ class WC_Cache_Helper {
$enabled = $config->get_integer( 'dbcache.enabled' ); $enabled = $config->get_integer( 'dbcache.enabled' );
$settings = array_map( 'trim', $config->get_array( 'dbcache.reject.sql' ) ); $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"> <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> </div>
<?php <?php
} }

View File

@ -63,6 +63,12 @@ final class WC_Cart_Fees {
} }
$this->cart = $cart; $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_emptied', array( $this, 'remove_all_fees' ) );
add_action( 'woocommerce_cart_reset', 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; $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( 'wp_loaded', array( $this, 'get_cart_from_session' ) );
add_action( 'woocommerce_cart_emptied', array( $this, 'destroy_cart_session' ) ); add_action( 'woocommerce_cart_emptied', array( $this, 'destroy_cart_session' ) );
add_action( 'wp', array( $this, 'maybe_set_cart_cookies' ), 99 ); add_action( 'wp', array( $this, 'maybe_set_cart_cookies' ), 99 );
@ -104,7 +109,7 @@ final class WC_Cart_Session {
do_action( 'woocommerce_cart_loaded_from_session', $this->cart ); do_action( 'woocommerce_cart_loaded_from_session', $this->cart );
if ( $update_cart_session || is_null( $totals ) ) { if ( $update_cart_session || is_null( WC()->session->get( 'cart_totals', null ) ) ) {
WC()->session->set( 'cart', $this->get_cart_for_session() ); WC()->session->set( 'cart', $this->get_cart_for_session() );
$this->cart->calculate_totals(); $this->cart->calculate_totals();
} }

View File

@ -109,6 +109,10 @@ class WC_Cart extends WC_Legacy_Cart {
$this->fees_api = new WC_Cart_Fees( $this ); $this->fees_api = new WC_Cart_Fees( $this );
$this->tax_display_cart = get_option( 'woocommerce_tax_display_cart' ); $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_add_to_cart', array( $this, 'calculate_totals' ), 20, 0 );
add_action( 'woocommerce_applied_coupon', 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 ); 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 ); 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. | Getters.
@ -1688,10 +1702,6 @@ class WC_Cart extends WC_Legacy_Cart {
* @return bool * @return bool
*/ */
public function remove_coupon( $coupon_code ) { public function remove_coupon( $coupon_code ) {
if ( ! wc_coupons_enabled() ) {
return false;
}
$coupon_code = wc_format_coupon_code( $coupon_code ); $coupon_code = wc_format_coupon_code( $coupon_code );
$position = array_search( $coupon_code, $this->get_applied_coupons(), true ); $position = array_search( $coupon_code, $this->get_applied_coupons(), true );
@ -1768,7 +1778,7 @@ class WC_Cart extends WC_Legacy_Cart {
* @return string formatted price * @return string formatted price
*/ */
public function get_total_ex_tax() { 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

@ -32,11 +32,11 @@ class WC_Comments {
// Secure order notes // Secure order notes
add_filter( 'comments_clauses', array( __CLASS__, 'exclude_order_comments' ), 10, 1 ); add_filter( 'comments_clauses', array( __CLASS__, 'exclude_order_comments' ), 10, 1 );
add_action( 'comment_feed_where', array( __CLASS__, 'exclude_order_comments_from_feed_where' ) ); add_filter( 'comment_feed_where', array( __CLASS__, 'exclude_order_comments_from_feed_where' ) );
// Secure webhook comments // Secure webhook comments
add_filter( 'comments_clauses', array( __CLASS__, 'exclude_webhook_comments' ), 10, 1 ); add_filter( 'comments_clauses', array( __CLASS__, 'exclude_webhook_comments' ), 10, 1 );
add_action( 'comment_feed_where', array( __CLASS__, 'exclude_webhook_comments_from_feed_where' ) ); add_filter( 'comment_feed_where', array( __CLASS__, 'exclude_webhook_comments_from_feed_where' ) );
// Count comments // Count comments
add_filter( 'wp_count_comments', array( __CLASS__, 'wp_count_comments' ), 10, 2 ); add_filter( 'wp_count_comments', array( __CLASS__, 'wp_count_comments' ), 10, 2 );

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 * @return integer
*/ */
public function get_download_count( $context = 'view' ) { 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 * @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 * @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 * @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 * @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 * @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. * @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. * @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 * @param int $value
*/ */
@ -266,6 +281,53 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
$this->set_prop( 'download_count', absint( $value ) ); $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 | CRUD methods
@ -345,7 +407,7 @@ class WC_Customer_Download extends WC_Data implements ArrayAccess {
* @return bool * @return bool
*/ */
public function __isset( $key ) { 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`. * Ran through `woocommerce_data_stores`.
*/ */
private $stores = array( private $stores = array(
'coupon' => 'WC_Coupon_Data_Store_CPT', 'coupon' => 'WC_Coupon_Data_Store_CPT',
'customer' => 'WC_Customer_Data_Store', 'customer' => 'WC_Customer_Data_Store',
'customer-download' => 'WC_Customer_Download_Data_Store', 'customer-download' => 'WC_Customer_Download_Data_Store',
'customer-session' => 'WC_Customer_Data_Store_Session', 'customer-download-log' => 'WC_Customer_Download_Log_Data_Store',
'order' => 'WC_Order_Data_Store_CPT', 'customer-session' => 'WC_Customer_Data_Store_Session',
'order-refund' => 'WC_Order_Refund_Data_Store_CPT', 'order' => 'WC_Order_Data_Store_CPT',
'order-item' => 'WC_Order_Item_Data_Store', 'order-refund' => 'WC_Order_Refund_Data_Store_CPT',
'order-item-coupon' => 'WC_Order_Item_Coupon_Data_Store', 'order-item' => 'WC_Order_Item_Data_Store',
'order-item-fee' => 'WC_Order_Item_Fee_Data_Store', 'order-item-coupon' => 'WC_Order_Item_Coupon_Data_Store',
'order-item-product' => 'WC_Order_Item_Product_Data_Store', 'order-item-fee' => 'WC_Order_Item_Fee_Data_Store',
'order-item-shipping' => 'WC_Order_Item_Shipping_Data_Store', 'order-item-product' => 'WC_Order_Item_Product_Data_Store',
'order-item-tax' => 'WC_Order_Item_Tax_Data_Store', 'order-item-shipping' => 'WC_Order_Item_Shipping_Data_Store',
'payment-token' => 'WC_Payment_Token_Data_Store', 'order-item-tax' => 'WC_Order_Item_Tax_Data_Store',
'product' => 'WC_Product_Data_Store_CPT', 'payment-token' => 'WC_Payment_Token_Data_Store',
'product-grouped' => 'WC_Product_Grouped_Data_Store_CPT', 'product' => 'WC_Product_Data_Store_CPT',
'product-variable' => 'WC_Product_Variable_Data_Store_CPT', 'product-grouped' => 'WC_Product_Grouped_Data_Store_CPT',
'product-variation' => 'WC_Product_Variation_Data_Store_CPT', 'product-variable' => 'WC_Product_Variable_Data_Store_CPT',
'shipping-zone' => 'WC_Shipping_Zone_Data_Store', 'product-variation' => 'WC_Product_Variation_Data_Store_CPT',
'webhook' => 'WC_Webhook_Data_Store', '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; $price_to_discount = ( 'yes' === get_option( 'woocommerce_calc_discounts_sequentially', 'no' ) ) ? $discounted_price : $item->price;
// See how many and what price to apply to. // 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; $price_to_discount = ( $price_to_discount / $item->quantity ) * $apply_quantity;
// Run coupon calculations. // Run coupon calculations.
@ -416,10 +417,11 @@ class WC_Discounts {
// Run coupon calculations. // Run coupon calculations.
if ( $limit_usage_qty ) { 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; $discount = min( $amount, $item->price / $item->quantity ) * $apply_quantity;
} else { } else {
$apply_quantity = $item->quantity; $apply_quantity = apply_filters( 'woocommerce_coupon_get_apply_quantity', $item->quantity, $item, $coupon, $this );
$discount = $amount * $apply_quantity; $discount = $amount * $apply_quantity;
} }
@ -611,8 +613,7 @@ class WC_Discounts {
* @return bool * @return bool
*/ */
protected function validate_coupon_minimum_amount( $coupon ) { protected function validate_coupon_minimum_amount( $coupon ) {
$subtotal = wc_remove_number_precision( array_sum( wp_list_pluck( $this->items, 'price' ) ) ); $subtotal = wc_remove_number_precision( $this->get_object_subtotal() );
if ( $coupon->get_minimum_amount() > 0 && apply_filters( 'woocommerce_coupon_validate_minimum_amount', $coupon->get_minimum_amount() > $subtotal, $coupon, $subtotal ) ) { if ( $coupon->get_minimum_amount() > 0 && apply_filters( 'woocommerce_coupon_validate_minimum_amount', $coupon->get_minimum_amount() > $subtotal, $coupon, $subtotal ) ) {
/* translators: %s: coupon minimum amount */ /* translators: %s: coupon minimum amount */
throw new Exception( sprintf( __( 'The minimum spend for this coupon is %s.', 'woocommerce' ), wc_price( $coupon->get_minimum_amount() ) ), 108 ); throw new Exception( sprintf( __( 'The minimum spend for this coupon is %s.', 'woocommerce' ), wc_price( $coupon->get_minimum_amount() ) ), 108 );
@ -630,8 +631,7 @@ class WC_Discounts {
* @return bool * @return bool
*/ */
protected function validate_coupon_maximum_amount( $coupon ) { protected function validate_coupon_maximum_amount( $coupon ) {
$subtotal = wc_remove_number_precision( array_sum( wp_list_pluck( $this->items, 'price' ) ) ); $subtotal = wc_remove_number_precision( $this->get_object_subtotal() );
if ( $coupon->get_maximum_amount() > 0 && apply_filters( 'woocommerce_coupon_validate_maximum_amount', $coupon->get_maximum_amount() < $subtotal, $coupon ) ) { if ( $coupon->get_maximum_amount() > 0 && apply_filters( 'woocommerce_coupon_validate_maximum_amount', $coupon->get_maximum_amount() < $subtotal, $coupon ) ) {
/* translators: %s: coupon maximum amount */ /* translators: %s: coupon maximum amount */
throw new Exception( sprintf( __( 'The maximum spend for this coupon is %s.', 'woocommerce' ), wc_price( $coupon->get_maximum_amount() ) ), 112 ); throw new Exception( sprintf( __( 'The maximum spend for this coupon is %s.', 'woocommerce' ), wc_price( $coupon->get_maximum_amount() ) ), 112 );
@ -845,6 +845,21 @@ class WC_Discounts {
return true; return true;
} }
/**
* Get the object subtotal
*
* @return int
*/
protected function get_object_subtotal() {
if ( is_a( $this->object, 'WC_Cart' ) ) {
return wc_add_number_precision( $this->object->get_displayed_subtotal() );
} elseif ( is_a( $this->object, 'WC_Order' ) ) {
return wc_add_number_precision( $this->object->get_subtotal() );
} else {
return array_sum( wp_list_pluck( $this->items, 'price' ) );
}
}
/** /**
* Check if a coupon is valid. * Check if a coupon is valid.
* *

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