Merge Commit

This commit is contained in:
Jonathan Belcher 2017-12-06 12:07:27 -05:00
commit c43f4c65be
158 changed files with 7316 additions and 5673 deletions

View File

@ -6,7 +6,6 @@ sudo: false
php:
- 5.6
- 7.0
- 7.1
env:
- WP_VERSION=latest WP_MULTISITE=0
@ -20,6 +19,8 @@ matrix:
dist: precise
- php: 5.2
dist: precise
- php: 7.1
env: WP_VERSION=latest WP_MULTISITE=0 RUN_PHPCS=1
- php: 7.1
env: WP_VERSION=latest WP_MULTISITE=0 RUN_CODE_COVERAGE=1
allow_failures:
@ -27,7 +28,6 @@ matrix:
before_script:
- export PATH="$HOME/.composer/vendor/bin:$PATH"
- if [[ $TRAVIS_PHP_VERSION == '7.1' ]]; then composer install; fi
- bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION
- bash tests/bin/travis.sh before
@ -37,3 +37,10 @@ script:
after_script:
- bash tests/bin/travis.sh after
# Specifies that Travis should create builds for master and release branches and also tags.
branches:
only:
- master
- /^\d+\.\d+(\.\d+)?(-\S*)?$/
- /^release\//

View File

@ -334,9 +334,9 @@ module.exports = function( grunt ) {
// Register tasks
grunt.registerTask( 'default', [
'jshint',
'uglify',
'css'
'js',
'css',
'i18n'
]);
grunt.registerTask( 'js', [
@ -358,8 +358,13 @@ module.exports = function( grunt ) {
'shell:apigen'
]);
// Only an alias to 'default' task.
grunt.registerTask( 'dev', [
'default',
'default'
]);
grunt.registerTask( 'i18n', [
'checktextdomain',
'makepot'
]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1878,17 +1878,21 @@ ul.wc_coupon_list_block {
width: 11%;
}
.column-order_actions,
.column-user_actions,
.column-wc_actions {
width: 110px;
a.button {
float: left;
margin: 0 4px 2px 0;
cursor: pointer;
padding: 3px 4px;
height: auto;
@include ir();
display: inline-block;
margin: 2px 4px 2px 0;
padding: 0 !important;
height: 2em !important;
width: 2em;
&::after {
@include icon_dashicons;
line-height: 1.85;
}
img {
display: block;
@ -1896,6 +1900,32 @@ ul.wc_coupon_list_block {
height: auto;
}
}
a.edit::after {
content: '\f464';
}
a.link::after {
content: '\e00d';
}
a.view::after {
content: '\f177';
}
a.refresh::after {
font-family: 'WooCommerce';
content: '\e031';
}
a.processing::after {
font-family: 'WooCommerce';
content: '\e00f';
}
a.complete::after {
content: '\f147';
}
}
small.meta {
@ -1912,11 +1942,50 @@ ul.wc_coupon_list_block {
}
.wp-list-table {
margin-top: 1em;
th {
padding: .75em 1em;
thead,
tfoot {
th {
padding: .75em 1em;
}
th.sortable a, th.sorted a {
padding: 0;
}
th:first-child {
padding-left: 2em;
}
th:last-child {
padding-right: 2em;
}
}
th.sortable a, th.sorted a {
padding: 0;
tbody {
td,
th {
padding: 1em;
line-height: 26px;
}
td:first-child {
padding-left: 2em;
}
td:last-child {
padding-right: 2em;
}
}
tbody tr {
border-top: 1px solid #f5f5f5;
}
tbody tr:hover:not(.status-trash) td {
cursor: pointer;
}
// Columns.
td,
th {
width: 12ch;
vertical-align: middle;
p {
margin: 0;
}
}
.check-column {
width: 1px;
@ -1928,147 +1997,122 @@ ul.wc_coupon_list_block {
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;
&::before {
@include icon( '\e010' );
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 {
width: 10ch;
}
.column-order_number {
width: 35ch;
}
.column-order_status {
width: 20ch;
}
.column-order_total {
width: 8ch;
text-align: right;
width: 10ch;
a span {
float:right;
}
}
.column-order_date,
.column-order_status {
width: 10ch;
}
.column-order_status {
width: 14ch;
}
.column-shipping_address,
.column-billing_address {
width: 20ch;
}
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;
line-height: 1.5em;
.description {
display: block;
color: #999;
}
td {
vertical-align: middle;
padding: 1em;
}
.column-wc_actions {
text-align: right;
.post-row-actions {
display: none;
}
.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;
}
}
a.button {
text-indent: 9999px;
margin: 2px 0 2px 4px;
}
tr:hover:not(.status-trash) {
td, th {
cursor: pointer;
}
}
.order-preview {
float:right;
width: 16px;
padding: 20px 4px 4px 4px;
height: 0;
overflow: hidden;
position: relative;
border: 2px solid transparent;
border-radius: 4px;
&::before {
@include icon( '\e010' );
line-height: 16px;
font-size: 14px;
vertical-align:middle;
top: 4px;
}
&:hover {
border: 2px solid #00a0d2;
}
}
.order-preview.disabled {
&::before {
content: '';
background: url('../images/wpspin.gif') no-repeat center top;
}
}
}
}
// Hide some columns on smaller screens.
@media only screen and (max-width: 1400px) {
.post-type-shop_order .wp-list-table {
.column-billing_address {
display:none;
visibility:hidden;
}
.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: -.25em 0;
cursor: inherit !important;
white-space: nowrap;
&.status-completed {
background: #C8D7E1;
color: #2e4453;
}
}
@media only screen and (max-width: 1200px) {
.post-type-shop_order .wp-list-table {
.column-shipping_address,
.column-order_total {
display:none;
visibility:hidden;
}
&.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;
}
}
.wc-order-preview {
.order-status {
float: right;
margin-right: 54px;
}
article {
padding: 0 !important;
}
.wc-order-preview__table {
.modal-close {
border-radius: 0;
}
.wc-order-preview-table {
width: 100%;
margin: 0;
border-bottom: 1px solid #ccc;
@ -2126,6 +2170,58 @@ ul.wc_coupon_list_block {
}
}
}
.wc-action-button,
.wc-action-button-group {
float: left;
margin-right: 4px;
}
}
@media screen and (max-width: 782px) {
.wc-action-button-group {
label {
display: none;
}
}
}
.wc-action-button-group {
vertical-align: middle;
line-height: 26px;
text-align: left;
margin-bottom: 4px;
label {
margin-right: 6px;
cursor: default;
font-weight: bold;
}
.wc-action-button-group__items {
white-space: nowrap;
}
.wc-action-button {
margin: -1px !important;
border: 1px solid #ccc;
padding: 1px 10px !important;
border-radius: 0 !important;
float: none;
line-height: 28px;
height: auto;
z-index: 1;
position:relative;
}
.wc-action-button:hover,
.wc-action-button:focus {
border: 1px solid #999;
z-index: 2;
}
.wc-action-button:first-child {
border-top-left-radius: 3px !important;
border-bottom-left-radius: 3px !important;
}
.wc-action-button:last-child {
border-top-right-radius: 3px !important;
border-bottom-right-radius: 3px !important;
}
}
.column-customer_message .note-on {
@ -2150,66 +2246,6 @@ ul.wc_coupon_list_block {
}
}
.order_actions {
.processing,
.complete,
.view {
@include ir();
padding: 0 !important;
height: 2em !important;
width: 2em;
}
.processing::after {
@include icon( '\e00f' );
line-height: 1.85;
}
.complete::after {
@include icon_dashicons( '\f147' );
line-height: 1.85;
}
.view::after {
@include icon_dashicons( '\f177' );
line-height: 1.85;
}
}
.user_actions {
.edit,
.link,
.view,
.refresh {
@include ir();
padding: 0 !important;
height: 2em !important;
width: 2em;
&::after {
@include icon;
line-height: 1.85;
}
}
.edit::after {
font-family: 'Dashicons';
content: '\f464';
}
.link::after {
content: '\e00d';
}
.view::after {
content: '\e010';
}
.refresh::after {
content: '\e031';
}
}
.attributes-table {
td,
th {
@ -2468,18 +2504,26 @@ table.wp-list-table {
}
}
mark.instock {
font-weight: 700;
color: $green;
background: transparent none;
line-height: 1;
}
mark {
&.instock,
&.outofstock,
&.onbackorder {
font-weight: 700;
background: transparent none;
line-height: 1;
}
mark.outofstock {
font-weight: 700;
color: #aa4444;
background: transparent none;
line-height: 1;
&.instock {
color: $green;
}
&.outofstock {
color: #aa4444;
}
&.onbackorder {
color: #eaa600;
}
}
.order-notes_head,
@ -5232,29 +5276,6 @@ img.ui-datepicker-trigger {
width: 49.5%;
float: right;
}
.column-wc_actions {
a.edit,
a.view {
@include ir();
padding: 0 !important;
height: 2em !important;
width: 2em;
&::after {
@include icon_dashicons;
line-height: 1.85;
}
}
a.edit::after {
content: '\f464';
}
a.view::after {
content: '\f177';
}
}
}
.woocommerce-wide-reports-wrap {
@ -5781,7 +5802,7 @@ table.bar_chart {
box-shadow: 0 -4px 4px -4px rgba(0, 0, 0, 0.1);
.inner {
float: right;
text-align: right;
line-height: 23px;
.button {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 25 KiB

BIN
assets/images/wpspin-2x.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

BIN
assets/images/wpspin.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -232,8 +232,12 @@ jQuery( function( $ ) {
$( 'input#_manage_stock' ).change( function() {
if ( $( this ).is( ':checked' ) ) {
$( 'div.stock_fields' ).show();
$( 'p.stock_status_field' ).hide();
} else {
var product_type = $( 'select#product-type' ).val();
$( 'div.stock_fields' ).hide();
$( 'p.stock_status_field:not( .hide_if_' + product_type + ' )' ).show();
}
}).change();

File diff suppressed because one or more lines are too long

View File

@ -60,10 +60,12 @@ jQuery(function( $ ) {
}
if ( 'yes' === manage_stock ) {
$( '.stock_qty_field', '.inline-edit-row' ).show().removeAttr( 'style' );
$( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).show().removeAttr( 'style' );
$( '.stock_status_field' ).hide();
$( 'input[name="_manage_stock"]', '.inline-edit-row' ).attr( 'checked', 'checked' );
} else {
$( '.stock_qty_field', '.inline-edit-row' ).hide();
$( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).hide();
$( '.stock_status_field' ).show().removeAttr( 'style' );
$( 'input[name="_manage_stock"]', '.inline-edit-row' ).removeAttr( 'checked' );
}
@ -96,9 +98,11 @@ jQuery(function( $ ) {
$( '#the-list' ).on( 'change', '.inline-edit-row input[name="_manage_stock"]', function() {
if ( $( this ).is( ':checked' ) ) {
$( '.stock_qty_field', '.inline-edit-row' ).show().removeAttr( 'style' );
$( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).show().removeAttr( 'style' );
$( '.stock_status_field' ).hide();
} else {
$( '.stock_qty_field', '.inline-edit-row' ).hide();
$( '.stock_qty_field, .backorder_field', '.inline-edit-row' ).hide();
$( '.stock_status_field' ).show().removeAttr( 'style' );
}
});

View File

@ -1 +1 @@
jQuery(function(e){e("#the-list").on("click",".editinline",function(){inlineEditPost.revert();var t=e(this).closest("tr").attr("id");t=t.replace("post-","");var i=e("#woocommerce_inline_"+t),n=i.find(".sku").text(),o=i.find(".regular_price").text(),l=i.find(".sale_price ").text(),d=i.find(".weight").text(),s=i.find(".length").text(),c=i.find(".width").text(),a=i.find(".height").text(),r=i.find(".shipping_class").text(),_=i.find(".visibility").text(),m=i.find(".stock_status").text(),p=i.find(".stock").text(),u=i.find(".featured").text(),w=i.find(".manage_stock").text(),h=i.find(".menu_order").text(),f=i.find(".tax_status").text(),v=i.find(".tax_class").text(),k=i.find(".backorders").text(),x=o.replace(".",woocommerce_admin.mon_decimal_point),g=l.replace(".",woocommerce_admin.mon_decimal_point);e('input[name="_sku"]',".inline-edit-row").val(n),e('input[name="_regular_price"]',".inline-edit-row").val(x),e('input[name="_sale_price"]',".inline-edit-row").val(g),e('input[name="_weight"]',".inline-edit-row").val(d),e('input[name="_length"]',".inline-edit-row").val(s),e('input[name="_width"]',".inline-edit-row").val(c),e('input[name="_height"]',".inline-edit-row").val(a),e('select[name="_shipping_class"] option:selected',".inline-edit-row").attr("selected",!1).change(),e('select[name="_shipping_class"] option[value="'+r+'"]').attr("selected","selected").change(),e('input[name="_stock"]',".inline-edit-row").val(p),e('input[name="menu_order"]',".inline-edit-row").val(h),e('select[name="_tax_status"] option, select[name="_tax_class"] option, select[name="_visibility"] option, select[name="_stock_status"] option, select[name="_backorders"] option').removeAttr("selected"),e('select[name="_tax_status"] option[value="'+f+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_tax_class"] option[value="'+v+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_visibility"] option[value="'+_+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_stock_status"] option[value="'+m+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_backorders"] option[value="'+k+'"]',".inline-edit-row").attr("selected","selected"),"yes"===u?e('input[name="_featured"]',".inline-edit-row").attr("checked","checked"):e('input[name="_featured"]',".inline-edit-row").removeAttr("checked"),"yes"===w?(e(".stock_qty_field",".inline-edit-row").show().removeAttr("style"),e('input[name="_manage_stock"]',".inline-edit-row").attr("checked","checked")):(e(".stock_qty_field",".inline-edit-row").hide(),e('input[name="_manage_stock"]',".inline-edit-row").removeAttr("checked"));var y=i.find(".product_type").text(),b=i.find(".product_is_virtual").text();"simple"===y||"external"===y?e(".price_fields",".inline-edit-row").show().removeAttr("style"):e(".price_fields",".inline-edit-row").hide(),"yes"===b?e(".dimension_fields",".inline-edit-row").hide():e(".dimension_fields",".inline-edit-row").show().removeAttr("style"),"grouped"===y?e(".stock_fields",".inline-edit-row").hide():e(".stock_fields",".inline-edit-row").show().removeAttr("style"),e('input[name="comment_status"]').parent().find(".checkbox-title").text(woocommerce_quick_edit.strings.allow_reviews)}),e("#the-list").on("change",'.inline-edit-row input[name="_manage_stock"]',function(){e(this).is(":checked")?e(".stock_qty_field",".inline-edit-row").show().removeAttr("style"):e(".stock_qty_field",".inline-edit-row").hide()}),e("#wpbody").on("click","#doaction, #doaction2",function(){e("input.text",".inline-edit-row").val(""),e("#woocommerce-fields").find("select").prop("selectedIndex",0),e("#woocommerce-fields-bulk").find(".inline-edit-group .change-input").hide()}),e("#wpbody").on("change","#woocommerce-fields-bulk .inline-edit-group .change_to",function(){0<e(this).val()?e(this).closest("div").find(".change-input").show():e(this).closest("div").find(".change-input").hide()}),e("#wpbody").on("click",".trash-product",function(){return window.confirm(woocommerce_admin.i18_delete_product_notice)})});
jQuery(function(e){e("#the-list").on("click",".editinline",function(){inlineEditPost.revert();var t=e(this).closest("tr").attr("id");t=t.replace("post-","");var i=e("#woocommerce_inline_"+t),n=i.find(".sku").text(),o=i.find(".regular_price").text(),d=i.find(".sale_price ").text(),l=i.find(".weight").text(),s=i.find(".length").text(),c=i.find(".width").text(),r=i.find(".height").text(),a=i.find(".shipping_class").text(),_=i.find(".visibility").text(),m=i.find(".stock_status").text(),p=i.find(".stock").text(),u=i.find(".featured").text(),w=i.find(".manage_stock").text(),f=i.find(".menu_order").text(),h=i.find(".tax_status").text(),k=i.find(".tax_class").text(),v=i.find(".backorders").text(),x=o.replace(".",woocommerce_admin.mon_decimal_point),g=d.replace(".",woocommerce_admin.mon_decimal_point);e('input[name="_sku"]',".inline-edit-row").val(n),e('input[name="_regular_price"]',".inline-edit-row").val(x),e('input[name="_sale_price"]',".inline-edit-row").val(g),e('input[name="_weight"]',".inline-edit-row").val(l),e('input[name="_length"]',".inline-edit-row").val(s),e('input[name="_width"]',".inline-edit-row").val(c),e('input[name="_height"]',".inline-edit-row").val(r),e('select[name="_shipping_class"] option:selected',".inline-edit-row").attr("selected",!1).change(),e('select[name="_shipping_class"] option[value="'+a+'"]').attr("selected","selected").change(),e('input[name="_stock"]',".inline-edit-row").val(p),e('input[name="menu_order"]',".inline-edit-row").val(f),e('select[name="_tax_status"] option, select[name="_tax_class"] option, select[name="_visibility"] option, select[name="_stock_status"] option, select[name="_backorders"] option').removeAttr("selected"),e('select[name="_tax_status"] option[value="'+h+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_tax_class"] option[value="'+k+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_visibility"] option[value="'+_+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_stock_status"] option[value="'+m+'"]',".inline-edit-row").attr("selected","selected"),e('select[name="_backorders"] option[value="'+v+'"]',".inline-edit-row").attr("selected","selected"),"yes"===u?e('input[name="_featured"]',".inline-edit-row").attr("checked","checked"):e('input[name="_featured"]',".inline-edit-row").removeAttr("checked"),"yes"===w?(e(".stock_qty_field, .backorder_field",".inline-edit-row").show().removeAttr("style"),e(".stock_status_field").hide(),e('input[name="_manage_stock"]',".inline-edit-row").attr("checked","checked")):(e(".stock_qty_field, .backorder_field",".inline-edit-row").hide(),e(".stock_status_field").show().removeAttr("style"),e('input[name="_manage_stock"]',".inline-edit-row").removeAttr("checked"));var y=i.find(".product_type").text(),b=i.find(".product_is_virtual").text();"simple"===y||"external"===y?e(".price_fields",".inline-edit-row").show().removeAttr("style"):e(".price_fields",".inline-edit-row").hide(),"yes"===b?e(".dimension_fields",".inline-edit-row").hide():e(".dimension_fields",".inline-edit-row").show().removeAttr("style"),"grouped"===y?e(".stock_fields",".inline-edit-row").hide():e(".stock_fields",".inline-edit-row").show().removeAttr("style"),e('input[name="comment_status"]').parent().find(".checkbox-title").text(woocommerce_quick_edit.strings.allow_reviews)}),e("#the-list").on("change",'.inline-edit-row input[name="_manage_stock"]',function(){e(this).is(":checked")?(e(".stock_qty_field, .backorder_field",".inline-edit-row").show().removeAttr("style"),e(".stock_status_field").hide()):(e(".stock_qty_field, .backorder_field",".inline-edit-row").hide(),e(".stock_status_field").show().removeAttr("style"))}),e("#wpbody").on("click","#doaction, #doaction2",function(){e("input.text",".inline-edit-row").val(""),e("#woocommerce-fields").find("select").prop("selectedIndex",0),e("#woocommerce-fields-bulk").find(".inline-edit-group .change-input").hide()}),e("#wpbody").on("change","#woocommerce-fields-bulk .inline-edit-group .change_to",function(){0<e(this).val()?e(this).closest("div").find(".change-input").show():e(this).closest("div").find(".change-input").hide()}),e("#wpbody").on("click",".trash-product",function(){return window.confirm(woocommerce_admin.i18_delete_product_notice)})});

View File

@ -26,7 +26,13 @@ jQuery( function( $ ) {
href = $row.find( 'a.order-view' ).attr( 'href' );
if ( href.length ) {
window.location = href;
e.preventDefault();
if ( e.metaKey ) {
window.open( href, '_blank' );
} else {
window.location = href;
}
}
};

View File

@ -1 +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});
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&&(r.preventDefault(),r.metaKey?window.open(a,"_blank"):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

@ -145,7 +145,7 @@
classes = _.indexBy( model.get( 'classes' ), 'term_id' ),
changes = {},
size = _.size( classes ),
newRow = _.extend( {}, data.default_class, {
newRow = _.extend( {}, data.default_shipping_class, {
term_id: 'new-' + size + '-' + Date.now(),
editing: true,
newRow : true

View File

@ -1 +1 @@
!function(e,i,s,n){e(function(){var t=e(".wc-shipping-class-rows"),a=e(".wc-shipping-class-save"),o=s.template("wc-shipping-class-row"),d=s.template("wc-shipping-class-row-blank"),c=Backbone.Model.extend({changes:{},logChanges:function(e){var i=this.changes||{};_.each(e,function(e,s){i[s]=_.extend(i[s]||{term_id:s},e)}),this.changes=i,this.trigger("change:classes")},save:function(){_.size(this.changes)?e.post(n+(n.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_classes_save_changes",{wc_shipping_classes_nonce:i.wc_shipping_classes_nonce,changes:this.changes},this.onSaveResponse,"json"):r.trigger("saved:classes")},discardChanges:function(e){delete(this.changes||{})[e],0===_.size(this.changes)&&h.clearUnloadConfirmation()},onSaveResponse:function(e,s){"success"===s&&(e.success?(r.set("classes",e.data.shipping_classes),r.trigger("change:classes"),r.changes={},r.trigger("saved:classes")):e.data?window.alert(e.data):window.alert(i.strings.save_failed)),h.unblock()}}),l=Backbone.View.extend({rowTemplate:o,initialize:function(){this.listenTo(this.model,"change:classes",this.setUnloadConfirmation),this.listenTo(this.model,"saved:classes",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:classes",this.render),t.on("change",{view:this},this.updateModelOnChange),e(window).on("beforeunload",{view:this},this.unloadConfirmation),a.on("click",{view:this},this.onSubmit),e(document.body).on("click",".wc-shipping-class-add",{view:this},this.onAddNewRow),e(document.body).on("click",".wc-shipping-class-save-changes",{view:this},this.onSubmit)},block:function(){e(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){e(this.el).unblock()},render:function(){var i=_.indexBy(this.model.get("classes"),"term_id"),s=this;this.$el.empty(),this.unblock(),_.size(i)?(i=_.sortBy(i,function(e){return e.name}),e.each(i,function(e,i){s.renderRow(i)})):s.$el.append(d)},renderRow:function(e){var i=this;i.$el.append(i.rowTemplate(e)),i.initRow(e)},initRow:function(i){var s=this.$el.find('tr[data-id="'+i.term_id+'"]');s.find("select").each(function(){var s=e(this).data("attribute");e(this).find('option[value="'+i[s]+'"]').prop("selected",!0)}),s.find(".view").show(),s.find(".edit").hide(),s.find(".wc-shipping-class-edit").on("click",{view:this},this.onEditRow),s.find(".wc-shipping-class-delete").on("click",{view:this},this.onDeleteRow),s.find(".editing .wc-shipping-class-edit").trigger("click"),s.find(".wc-shipping-class-cancel-edit").on("click",{view:this},this.onCancelEditRow),!0===i.editing&&(s.addClass("editing"),s.find(".wc-shipping-class-edit").trigger("click"))},onSubmit:function(e){e.data.view.block(),e.data.view.model.save(),e.preventDefault()},onAddNewRow:function(s){s.preventDefault();var n=s.data.view,t=n.model,a=_.indexBy(t.get("classes"),"term_id"),o={},d=_.size(a),c=_.extend({},i.default_class,{term_id:"new-"+d+"-"+Date.now(),editing:!0,newRow:!0});o[c.term_id]=c,t.logChanges(o),n.renderRow(c),e(".wc-shipping-classes-blank-state").remove()},onEditRow:function(i){i.preventDefault(),e(this).closest("tr").addClass("editing"),e(this).closest("tr").find(".view").hide(),e(this).closest("tr").find(".edit").show(),i.data.view.model.trigger("change:classes")},onDeleteRow:function(i){var s=i.data.view,n=s.model,t=_.indexBy(n.get("classes"),"term_id"),a={},o=e(this).closest("tr").data("id");i.preventDefault(),t[o]&&(delete t[o],a[o]=_.extend(a[o]||{},{deleted:"deleted"}),n.set("classes",t),n.logChanges(a)),s.render()},onCancelEditRow:function(i){var s=i.data.view,n=s.model,t=e(this).closest("tr"),a=e(this).closest("tr").data("id"),o=_.indexBy(n.get("classes"),"term_id");i.preventDefault(),n.discardChanges(a),o[a]&&(o[a].editing=!1,t.after(s.rowTemplate(o[a])),s.initRow(o[a])),t.remove()},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,a.removeAttr("disabled")},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,a.attr("disabled","disabled")},unloadConfirmation:function(e){if(e.data.view.needsUnloadConfirm)return e.returnValue=i.strings.unload_confirmation_msg,window.event.returnValue=i.strings.unload_confirmation_msg,i.strings.unload_confirmation_msg},updateModelOnChange:function(i){var s=i.data.view.model,n=e(i.target),t=n.closest("tr").data("id"),a=n.data("attribute"),o=n.val(),d=_.indexBy(s.get("classes"),"term_id"),c={};d[t]&&d[t][a]===o||(c[t]={},c[t][a]=o),s.logChanges(c)}}),r=new c({classes:i.classes}),h=new l({model:r,el:t});h.render()})}(jQuery,shippingClassesLocalizeScript,wp,ajaxurl);
!function(e,i,s,n){e(function(){var t=e(".wc-shipping-class-rows"),a=e(".wc-shipping-class-save"),o=s.template("wc-shipping-class-row"),d=s.template("wc-shipping-class-row-blank"),c=Backbone.Model.extend({changes:{},logChanges:function(e){var i=this.changes||{};_.each(e,function(e,s){i[s]=_.extend(i[s]||{term_id:s},e)}),this.changes=i,this.trigger("change:classes")},save:function(){_.size(this.changes)?e.post(n+(n.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_classes_save_changes",{wc_shipping_classes_nonce:i.wc_shipping_classes_nonce,changes:this.changes},this.onSaveResponse,"json"):r.trigger("saved:classes")},discardChanges:function(e){delete(this.changes||{})[e],0===_.size(this.changes)&&h.clearUnloadConfirmation()},onSaveResponse:function(e,s){"success"===s&&(e.success?(r.set("classes",e.data.shipping_classes),r.trigger("change:classes"),r.changes={},r.trigger("saved:classes")):e.data?window.alert(e.data):window.alert(i.strings.save_failed)),h.unblock()}}),l=Backbone.View.extend({rowTemplate:o,initialize:function(){this.listenTo(this.model,"change:classes",this.setUnloadConfirmation),this.listenTo(this.model,"saved:classes",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:classes",this.render),t.on("change",{view:this},this.updateModelOnChange),e(window).on("beforeunload",{view:this},this.unloadConfirmation),a.on("click",{view:this},this.onSubmit),e(document.body).on("click",".wc-shipping-class-add",{view:this},this.onAddNewRow),e(document.body).on("click",".wc-shipping-class-save-changes",{view:this},this.onSubmit)},block:function(){e(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){e(this.el).unblock()},render:function(){var i=_.indexBy(this.model.get("classes"),"term_id"),s=this;this.$el.empty(),this.unblock(),_.size(i)?(i=_.sortBy(i,function(e){return e.name}),e.each(i,function(e,i){s.renderRow(i)})):s.$el.append(d)},renderRow:function(e){var i=this;i.$el.append(i.rowTemplate(e)),i.initRow(e)},initRow:function(i){var s=this.$el.find('tr[data-id="'+i.term_id+'"]');s.find("select").each(function(){var s=e(this).data("attribute");e(this).find('option[value="'+i[s]+'"]').prop("selected",!0)}),s.find(".view").show(),s.find(".edit").hide(),s.find(".wc-shipping-class-edit").on("click",{view:this},this.onEditRow),s.find(".wc-shipping-class-delete").on("click",{view:this},this.onDeleteRow),s.find(".editing .wc-shipping-class-edit").trigger("click"),s.find(".wc-shipping-class-cancel-edit").on("click",{view:this},this.onCancelEditRow),!0===i.editing&&(s.addClass("editing"),s.find(".wc-shipping-class-edit").trigger("click"))},onSubmit:function(e){e.data.view.block(),e.data.view.model.save(),e.preventDefault()},onAddNewRow:function(s){s.preventDefault();var n=s.data.view,t=n.model,a=_.indexBy(t.get("classes"),"term_id"),o={},d=_.size(a),c=_.extend({},i.default_shipping_class,{term_id:"new-"+d+"-"+Date.now(),editing:!0,newRow:!0});o[c.term_id]=c,t.logChanges(o),n.renderRow(c),e(".wc-shipping-classes-blank-state").remove()},onEditRow:function(i){i.preventDefault(),e(this).closest("tr").addClass("editing"),e(this).closest("tr").find(".view").hide(),e(this).closest("tr").find(".edit").show(),i.data.view.model.trigger("change:classes")},onDeleteRow:function(i){var s=i.data.view,n=s.model,t=_.indexBy(n.get("classes"),"term_id"),a={},o=e(this).closest("tr").data("id");i.preventDefault(),t[o]&&(delete t[o],a[o]=_.extend(a[o]||{},{deleted:"deleted"}),n.set("classes",t),n.logChanges(a)),s.render()},onCancelEditRow:function(i){var s=i.data.view,n=s.model,t=e(this).closest("tr"),a=e(this).closest("tr").data("id"),o=_.indexBy(n.get("classes"),"term_id");i.preventDefault(),n.discardChanges(a),o[a]&&(o[a].editing=!1,t.after(s.rowTemplate(o[a])),s.initRow(o[a])),t.remove()},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,a.removeAttr("disabled")},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,a.attr("disabled","disabled")},unloadConfirmation:function(e){if(e.data.view.needsUnloadConfirm)return e.returnValue=i.strings.unload_confirmation_msg,window.event.returnValue=i.strings.unload_confirmation_msg,i.strings.unload_confirmation_msg},updateModelOnChange:function(i){var s=i.data.view.model,n=e(i.target),t=n.closest("tr").data("id"),a=n.data("attribute"),o=n.val(),d=_.indexBy(s.get("classes"),"term_id"),c={};d[t]&&d[t][a]===o||(c[t]={},c[t][a]=o),s.logChanges(c)}}),r=new c({classes:i.classes}),h=new l({model:r,el:t});h.render()})}(jQuery,shippingClassesLocalizeScript,wp,ajaxurl);

View File

@ -134,18 +134,27 @@ jQuery( function ( $ ) {
})
.on( 'init_tooltips', function() {
var tiptip_args = {
$( '.tips, .help_tip, .woocommerce-help-tip' ).tipTip( {
'attribute': 'data-tip',
'fadeIn': 50,
'fadeOut': 50,
'delay': 200
};
} );
$( '.tips, .help_tip, .woocommerce-help-tip' ).tipTip( tiptip_args );
$( '.column-wc_actions .wc-action-button' ).tipTip( {
'fadeIn': 50,
'fadeOut': 50,
'delay': 200
} );
// Add tiptip to parent element for widefat tables
$( '.parent-tips' ).each( function() {
$( this ).closest( 'a, th' ).attr( 'data-tip', $( this ).data( 'tip' ) ).tipTip( tiptip_args ).css( 'cursor', 'help' );
$( this ).closest( 'a, th' ).attr( 'data-tip', $( this ).data( 'tip' ) ).tipTip( {
'attribute': 'data-tip',
'fadeIn': 50,
'fadeOut': 50,
'delay': 200
} ).css( 'cursor', 'help' );
});
});

File diff suppressed because one or more lines are too long

View File

@ -181,8 +181,6 @@ jQuery( function( $ ) {
/**
* Handles when a shipping method is selected.
*
* @param {Object} evt The JQuery event.
*/
shipping_method_selected: function() {
var shipping_methods = {};

File diff suppressed because one or more lines are too long

View File

@ -1475,8 +1475,14 @@ S2.define('select2/selection/base',[
}
var $element = $this.data('element');
$element.select2('close');
// Remove any focus when dropdown is closed by clicking outside the select area.
// Timeout of 1 required for close to finish wrapping up.
setTimeout(function(){
$this.find('*:focus').blur();
$target.focus();
}, 1);
});
});
};
@ -1675,6 +1681,11 @@ S2.define('select2/selection/multiple',[
container.open();
}
});
// Focus on the search field when the container is focused instead of the main container.
container.on( 'focus', function(){
self.focusOnSearch();
});
};
MultipleSelection.prototype.clear = function () {
@ -1700,8 +1711,25 @@ S2.define('select2/selection/multiple',[
return $container;
};
MultipleSelection.prototype.update = function (data) {
/**
* Focus on the search field instead of the main multiselect container.
*/
MultipleSelection.prototype.focusOnSearch = function() {
var self = this;
if ('undefined' !== typeof self.$search) {
// Needs 1 ms delay because of other 1 ms setTimeouts when rendering.
setTimeout(function(){
// Prevent the dropdown opening again when focused from this.
// This gets reset automatically when focus is triggered.
self._keyUpPrevented = true;
self.$search.focus();
}, 1);
}
}
MultipleSelection.prototype.update = function (data) {
this.clear();
if (data.length === 0) {
@ -1727,14 +1755,6 @@ S2.define('select2/selection/multiple',[
var $rendered = this.$selection.find('.select2-selection__rendered');
Utils.appendMany($rendered, $selections);
// Return cursor to search field after updating.
// Needs 1 ms delay because of other 1 ms setTimeouts when rendering.
if ('undefined' !== typeof this.$search) {
setTimeout(function(){
self.$search.focus();
}, 1);
}
};
return MultipleSelection;
@ -1980,6 +2000,9 @@ S2.define('select2/selection/search',[
evt.preventDefault();
}
} else if (evt.which === KEYS.ENTER) {
container.open();
evt.preventDefault();
}
});
@ -5480,18 +5503,9 @@ S2.define('select2/core',[
self.focusOnActiveElement();
}, 1000);
}
// If focus is in the search field, select the current active element on Enter key.
$searchField.on('keydown', function (evt) {
if (evt.which === KEYS.ENTER) {
self.trigger('results:select', {});
evt.preventDefault();
}
});
} else if (self.hasFocus()) {
if (key === KEYS.ENTER || key === KEYS.SPACE ||
(key === KEYS.DOWN && evt.altKey)) {
key === KEYS.DOWN) {
self.open();
evt.preventDefault();
}
@ -5501,7 +5515,7 @@ S2.define('select2/core',[
Select2.prototype.focusOnActiveElement = function () {
// Don't mess with the focus on touchscreens because it causes havoc with on-screen keyboards.
if (! Utils.isTouchscreen()) {
if (this.isOpen() && ! Utils.isTouchscreen()) {
this.$results.find('li.select2-results__option--highlighted').focus();
}
};

File diff suppressed because one or more lines are too long

View File

@ -1475,8 +1475,14 @@ S2.define('select2/selection/base',[
}
var $element = $this.data('element');
$element.select2('close');
// Remove any focus when dropdown is closed by clicking outside the select area.
// Timeout of 1 required for close to finish wrapping up.
setTimeout(function(){
$this.find('*:focus').blur();
$target.focus();
}, 1);
});
});
};
@ -1675,6 +1681,11 @@ S2.define('select2/selection/multiple',[
container.open();
}
});
// Focus on the search field when the container is focused instead of the main container.
container.on( 'focus', function(){
self.focusOnSearch();
});
};
MultipleSelection.prototype.clear = function () {
@ -1700,8 +1711,25 @@ S2.define('select2/selection/multiple',[
return $container;
};
MultipleSelection.prototype.update = function (data) {
/**
* Focus on the search field instead of the main multiselect container.
*/
MultipleSelection.prototype.focusOnSearch = function() {
var self = this;
if ('undefined' !== typeof self.$search) {
// Needs 1 ms delay because of other 1 ms setTimeouts when rendering.
setTimeout(function(){
// Prevent the dropdown opening again when focused from this.
// This gets reset automatically when focus is triggered.
self._keyUpPrevented = true;
self.$search.focus();
}, 1);
}
}
MultipleSelection.prototype.update = function (data) {
this.clear();
if (data.length === 0) {
@ -1727,14 +1755,6 @@ S2.define('select2/selection/multiple',[
var $rendered = this.$selection.find('.select2-selection__rendered');
Utils.appendMany($rendered, $selections);
// Return cursor to search field after updating.
// Needs 1 ms delay because of other 1 ms setTimeouts when rendering.
if ('undefined' !== typeof this.$search) {
setTimeout(function(){
self.$search.focus();
}, 1);
}
};
return MultipleSelection;
@ -1980,6 +2000,9 @@ S2.define('select2/selection/search',[
evt.preventDefault();
}
} else if (evt.which === KEYS.ENTER) {
container.open();
evt.preventDefault();
}
});
@ -5480,18 +5503,9 @@ S2.define('select2/core',[
self.focusOnActiveElement();
}, 1000);
}
// If focus is in the search field, select the current active element on Enter key.
$searchField.on('keydown', function (evt) {
if (evt.which === KEYS.ENTER) {
self.trigger('results:select', {});
evt.preventDefault();
}
});
} else if (self.hasFocus()) {
if (key === KEYS.ENTER || key === KEYS.SPACE ||
(key === KEYS.DOWN && evt.altKey)) {
key === KEYS.DOWN) {
self.open();
evt.preventDefault();
}
@ -5501,7 +5515,7 @@ S2.define('select2/core',[
Select2.prototype.focusOnActiveElement = function () {
// Don't mess with the focus on touchscreens because it causes havoc with on-screen keyboards.
if (! Utils.isTouchscreen()) {
if (this.isOpen() && ! Utils.isTouchscreen()) {
this.$results.find('li.select2-results__option--highlighted').focus();
}
};

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@
},
"require-dev": {
"squizlabs/php_codesniffer": "*",
"wp-coding-standards/wpcs": "0.13.1",
"wp-coding-standards/wpcs": "^0.14",
"phpunit/phpunit": "6.2.3",
"woocommerce/woocommerce-git-hooks": "1.0.3",
"wimg/php-compatibility": "^8.0",
@ -27,6 +27,22 @@
],
"post-update-cmd": [
"WooCommerce\\GitHooks\\Hooks::postHooks"
],
"test": [
"phpunit"
],
"phpcs": [
"phpcs -s -p --standard=./phpcs.ruleset.xml"
],
"phpcbf": [
"phpcbf -p --standard=./phpcs.ruleset.xml"
]
},
"extra": {
"scripts-description": {
"test": "Run unit tests",
"phpcs": "Analyze code against the WordPress coding standards with PHP_CodeSniffer",
"phpcbf": "Fix coding standards warnings/errors automatically with PHP Code Beautifier"
}
}
}

14
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "9a9c7e81cc3a30935c03b1b2d64c201c",
"content-hash": "f8dbe5807f695e87ad3453a8b629b6bf",
"packages": [
{
"name": "composer/installers",
@ -1783,16 +1783,16 @@
},
{
"name": "wp-coding-standards/wpcs",
"version": "0.13.1",
"version": "0.14.0",
"source": {
"type": "git",
"url": "https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards.git",
"reference": "1f64b1a0b5b789822d0303436ee4e30e0135e4dc"
"reference": "8cadf48fa1c70b2381988e0a79e029e011a8f41c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/WordPress-Coding-Standards/WordPress-Coding-Standards/zipball/1f64b1a0b5b789822d0303436ee4e30e0135e4dc",
"reference": "1f64b1a0b5b789822d0303436ee4e30e0135e4dc",
"url": "https://api.github.com/repos/WordPress-Coding-Standards/WordPress-Coding-Standards/zipball/8cadf48fa1c70b2381988e0a79e029e011a8f41c",
"reference": "8cadf48fa1c70b2381988e0a79e029e011a8f41c",
"shasum": ""
},
"require": {
@ -1800,7 +1800,7 @@
"squizlabs/php_codesniffer": "^2.9.0 || ^3.0.2"
},
"suggest": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.1"
"dealerdirect/phpcodesniffer-composer-installer": "^0.4.3"
},
"type": "phpcodesniffer-standard",
"notification-url": "https://packagist.org/downloads/",
@ -1819,7 +1819,7 @@
"standards",
"wordpress"
],
"time": "2017-08-05T16:08:58+00:00"
"time": "2017-11-01T15:10:46+00:00"
}
],
"aliases": [],

File diff suppressed because it is too large Load Diff

View File

@ -14,30 +14,30 @@ if ( ! defined( 'ABSPATH' ) ) {
}
$states['IE'] = array(
'CW' => __( 'Carlow', 'woocommerce' ),
'CN' => __( 'Cavan', 'woocommerce' ),
'CE' => __( 'Clare', 'woocommerce' ),
'CK' => __( 'Cork', 'woocommerce' ),
'CN' => __( 'Cavan', 'woocommerce' ),
'CW' => __( 'Carlow', 'woocommerce' ),
'DL' => __( 'Donegal', 'woocommerce' ),
'DN' => __( 'Dublin', 'woocommerce' ),
'GY' => __( 'Galway', 'woocommerce' ),
'KY' => __( 'Kerry', 'woocommerce' ),
'KE' => __( 'Kildare', 'woocommerce' ),
'KK' => __( 'Kilkenny', 'woocommerce' ),
'KY' => __( 'Kerry', 'woocommerce' ),
'LS' => __( 'Laois', 'woocommerce' ),
'LM' => __( 'Leitrim', 'woocommerce' ),
'LK' => __( 'Limerick', 'woocommerce' ),
'LD' => __( 'Longford', 'woocommerce' ),
'LH' => __( 'Louth', 'woocommerce' ),
'LK' => __( 'Limerick', 'woocommerce' ),
'LM' => __( 'Leitrim', 'woocommerce' ),
'LS' => __( 'Laois', 'woocommerce' ),
'MO' => __( 'Mayo', 'woocommerce' ),
'MH' => __( 'Meath', 'woocommerce' ),
'MN' => __( 'Monaghan', 'woocommerce' ),
'MO' => __( 'Mayo', 'woocommerce' ),
'OY' => __( 'Offaly', 'woocommerce' ),
'RN' => __( 'Roscommon', 'woocommerce' ),
'SO' => __( 'Sligo', 'woocommerce' ),
'TY' => __( 'Tipperary', 'woocommerce' ),
'WD' => __( 'Waterford', 'woocommerce' ),
'WH' => __( 'Westmeath', 'woocommerce' ),
'WW' => __( 'Wicklow', 'woocommerce' ),
'WX' => __( 'Wexford', 'woocommerce' ),
'WW' => __( 'Wicklow', 'woocommerce' )
);

View File

@ -15,50 +15,50 @@ if ( ! defined( 'ABSPATH' ) ) {
$states['JP'] = array(
'JP01' => __( 'Hokkaido', 'woocommerce' ),
'JP02' => __( 'Aomori', 'woocommerce' ),
'JP03' => __( 'Iwate', 'woocommerce' ),
'JP04' => __( 'Miyagi', 'woocommerce' ),
'JP05' => __( 'Akita', 'woocommerce' ),
'JP06' => __( 'Yamagata', 'woocommerce' ),
'JP07' => __( 'Fukushima', 'woocommerce' ),
'JP08' => __( 'Ibaraki', 'woocommerce' ),
'JP09' => __( 'Tochigi', 'woocommerce' ),
'JP10' => __( 'Gunma', 'woocommerce' ),
'JP11' => __( 'Saitama', 'woocommerce' ),
'JP12' => __( 'Chiba', 'woocommerce' ),
'JP13' => __( 'Tokyo', 'woocommerce' ),
'JP14' => __( 'Kanagawa', 'woocommerce' ),
'JP15' => __( 'Niigata', 'woocommerce' ),
'JP16' => __( 'Toyama', 'woocommerce' ),
'JP17' => __( 'Ishikawa', 'woocommerce' ),
'JP18' => __( 'Fukui', 'woocommerce' ),
'JP19' => __( 'Yamanashi', 'woocommerce' ),
'JP20' => __( 'Nagano', 'woocommerce' ),
'JP21' => __( 'Gifu', 'woocommerce' ),
'JP22' => __( 'Shizuoka', 'woocommerce' ),
'JP23' => __( 'Aichi', 'woocommerce' ),
'JP24' => __( 'Mie', 'woocommerce' ),
'JP25' => __( 'Shiga', 'woocommerce' ),
'JP26' => __( 'Kyoto', 'woocommerce' ),
'JP27' => __( 'Osaka', 'woocommerce' ),
'JP28' => __( 'Hyogo', 'woocommerce' ),
'JP29' => __( 'Nara', 'woocommerce' ),
'JP30' => __( 'Wakayama', 'woocommerce' ),
'JP31' => __( 'Tottori', 'woocommerce' ),
'JP32' => __( 'Shimane', 'woocommerce' ),
'JP33' => __( 'Okayama', 'woocommerce' ),
'JP34' => __( 'Hiroshima', 'woocommerce' ),
'JP35' => __( 'Yamaguchi', 'woocommerce' ),
'JP36' => __( 'Tokushima', 'woocommerce' ),
'JP37' => __( 'Kagawa', 'woocommerce' ),
'JP38' => __( 'Ehime', 'woocommerce' ),
'JP39' => __( 'Kochi', 'woocommerce' ),
'JP40' => __( 'Fukuoka', 'woocommerce' ),
'JP41' => __( 'Saga', 'woocommerce' ),
'JP42' => __( 'Nagasaki', 'woocommerce' ),
'JP43' => __( 'Kumamoto', 'woocommerce' ),
'JP44' => __( 'Oita', 'woocommerce' ),
'JP45' => __( 'Miyazaki', 'woocommerce' ),
'JP46' => __( 'Kagoshima', 'woocommerce' ),
'JP47' => __( 'Okinawa', 'woocommerce' ),
'JP02' => __( 'Aomori-ken', 'woocommerce' ),
'JP03' => __( 'Iwate-ken', 'woocommerce' ),
'JP04' => __( 'Miyagi-ken', 'woocommerce' ),
'JP05' => __( 'Akita-ken', 'woocommerce' ),
'JP06' => __( 'Yamagata-ken', 'woocommerce' ),
'JP07' => __( 'Fukushima-ken', 'woocommerce' ),
'JP08' => __( 'Ibaraki-ken', 'woocommerce' ),
'JP09' => __( 'Tochigi-ken', 'woocommerce' ),
'JP10' => __( 'Gunma-ken', 'woocommerce' ),
'JP11' => __( 'Saitama-ken', 'woocommerce' ),
'JP12' => __( 'Chiba-ken', 'woocommerce' ),
'JP13' => __( 'Tokyo-to', 'woocommerce' ),
'JP14' => __( 'Kanagawa-ken', 'woocommerce' ),
'JP15' => __( 'Niigata-ken', 'woocommerce' ),
'JP16' => __( 'Toyama-ken', 'woocommerce' ),
'JP17' => __( 'Ishikawa-ken', 'woocommerce' ),
'JP18' => __( 'Fukui-ken', 'woocommerce' ),
'JP19' => __( 'Yamanashi-ken', 'woocommerce' ),
'JP20' => __( 'Nagano-ken', 'woocommerce' ),
'JP21' => __( 'Gifu-ken', 'woocommerce' ),
'JP22' => __( 'Shizuoka-ken', 'woocommerce' ),
'JP23' => __( 'Aichi-ken', 'woocommerce' ),
'JP24' => __( 'Mie-ken', 'woocommerce' ),
'JP25' => __( 'Shiga-ken', 'woocommerce' ),
'JP26' => __( 'Kyoto-fu', 'woocommerce' ),
'JP27' => __( 'Osaka-fu', 'woocommerce' ),
'JP28' => __( 'Hyogo-ken', 'woocommerce' ),
'JP29' => __( 'Nara-ken', 'woocommerce' ),
'JP30' => __( 'Wakayama-ken', 'woocommerce' ),
'JP31' => __( 'Tottori-ken', 'woocommerce' ),
'JP32' => __( 'Shimane-ken', 'woocommerce' ),
'JP33' => __( 'Okayama-ken', 'woocommerce' ),
'JP34' => __( 'Hiroshima-ken', 'woocommerce' ),
'JP35' => __( 'Yamaguchi-ken', 'woocommerce' ),
'JP36' => __( 'Tokushima-ken', 'woocommerce' ),
'JP37' => __( 'Kagawa-ken', 'woocommerce' ),
'JP38' => __( 'Ehime-ken', 'woocommerce' ),
'JP39' => __( 'Kochi-ken', 'woocommerce' ),
'JP40' => __( 'Fukuoka-ken', 'woocommerce' ),
'JP41' => __( 'Saga-ken', 'woocommerce' ),
'JP42' => __( 'Nagasaki-ken', 'woocommerce' ),
'JP43' => __( 'Kumamoto-ken', 'woocommerce' ),
'JP44' => __( 'Oita-ken', 'woocommerce' ),
'JP45' => __( 'Miyazaki-ken', 'woocommerce' ),
'JP46' => __( 'Kagoshima-ken', 'woocommerce' ),
'JP47' => __( 'Okinawa-ken', 'woocommerce' ),
);

View File

@ -263,7 +263,7 @@ abstract class WC_Data {
*/
public function get_meta_data() {
$this->maybe_read_meta_data();
return array_filter( $this->meta_data, array( $this, 'filter_null_meta' ) );
return array_values( array_filter( $this->meta_data, array( $this, 'filter_null_meta' ) ) );
}
/**
@ -285,7 +285,7 @@ abstract class WC_Data {
if ( ! $has_setter_or_getter ) {
return false;
}
/* translators: %s: $key Key to check */
wc_doing_it_wrong( __FUNCTION__, sprintf( __( 'Generic add/update/get meta methods should not be used for internal meta data, including "%s". Use getters and setters.', 'woocommerce' ), $key ), '3.2.0' );
return true;
@ -400,7 +400,7 @@ abstract class WC_Data {
* @param string $value
* @param int $meta_id
*/
public function update_meta_data( $key, $value, $meta_id = '' ) {
public function update_meta_data( $key, $value, $meta_id = 0 ) {
if ( $this->is_internal_meta_key( $key ) ) {
$function = 'set_' . $key;

View File

@ -1,4 +1,12 @@
<?php
/**
* Abstract deprecated hooks
*
* @package WooCommerce\Abstracts
* @since 3.0.0
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -7,8 +15,6 @@ if ( ! defined( 'ABSPATH' ) ) {
* WC_Deprecated_Hooks class maps old actions and filters to new ones. This is the base class for handling those deprecated hooks.
*
* Based on the WCS_Hook_Deprecator class by Prospress.
*
* @since 3.0.0
*/
abstract class WC_Deprecated_Hooks {
@ -19,6 +25,13 @@ abstract class WC_Deprecated_Hooks {
*/
protected $deprecated_hooks = array();
/**
* Array of versions on each hook has been deprecated.
*
* @var array
*/
protected $deprecated_version = array();
/**
* Constructor.
*/
@ -30,14 +43,14 @@ abstract class WC_Deprecated_Hooks {
/**
* Hook into the new hook so we can handle deprecated hooks once fired.
*
* @param string $hook_name
* @param string $hook_name Hook name.
*/
abstract function hook_in( $hook_name );
abstract public function hook_in( $hook_name );
/**
* Get old hooks to map to new hook.
*
* @param string $new_hook
* @param string $new_hook New hook name.
* @return array
*/
public function get_old_hooks( $new_hook ) {
@ -66,29 +79,39 @@ abstract class WC_Deprecated_Hooks {
/**
* If the old hook is in-use, trigger it.
*
* @param string $new_hook
* @param string $old_hook
* @param array $new_callback_args
* @param mixed $return_value
* @param string $new_hook New hook name.
* @param string $old_hook Old hook name.
* @param array $new_callback_args New callback args.
* @param mixed $return_value Returned value.
* @return mixed
*/
abstract function handle_deprecated_hook( $new_hook, $old_hook, $new_callback_args, $return_value );
abstract public function handle_deprecated_hook( $new_hook, $old_hook, $new_callback_args, $return_value );
/**
* Get deprecated version.
*
* @param string $old_hook Old hook name.
* @return string
*/
protected function get_deprecated_version( $old_hook ) {
return ! empty( $this->deprecated_version[ $old_hook ] ) ? $this->deprecated_version[ $old_hook ] : WC_VERSION;
}
/**
* Display a deprecated notice for old hooks.
*
* @param string $old_hook
* @param string $new_hook
* @param string $old_hook Old hook.
* @param string $new_hook New hook.
*/
protected function display_notice( $old_hook, $new_hook ) {
wc_deprecated_function( sprintf( 'The "%s" hook uses out of date data structures and', esc_html( $old_hook ) ), WC_VERSION, esc_html( $new_hook ) );
wc_deprecated_hook( esc_html( $old_hook ), esc_html( $this->get_deprecated_version( $old_hook ) ), esc_html( $new_hook ) );
}
/**
* Fire off a legacy hook with it's args.
*
* @param string $old_hook
* @param array $new_callback_args
* @param string $old_hook Old hook name.
* @param array $new_callback_args New callback args.
* @return mixed
*/
abstract protected function trigger_hook( $old_hook, $new_callback_args );

View File

@ -708,7 +708,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
}
}
return apply_filters( 'woocommerce_order_get_items', $items, $this );
return apply_filters( 'woocommerce_order_get_items', $items, $this, $types );
}
/**
@ -1599,7 +1599,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
public function get_subtotal_to_display( $compound = false, $tax_display = '' ) {
$tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' );
$subtotal = 0;
if ( ! $compound ) {
foreach ( $this->get_items() as $item ) {
$subtotal += $item->get_subtotal();

View File

@ -945,8 +945,14 @@ class WC_Product extends WC_Abstract_Legacy_Product {
*
* @param string $status New status.
*/
public function set_stock_status( $status = '' ) {
$this->set_prop( 'stock_status', 'outofstock' === $status ? 'outofstock' : 'instock' );
public function set_stock_status( $status = 'instock' ) {
$valid_statuses = wc_get_product_stock_status_options();
if ( isset( $valid_statuses[ $status ] ) ) {
$this->set_prop( 'stock_status', $status );
} else {
$this->set_prop( 'stock_status', 'instock' );
}
}
/**
@ -1300,11 +1306,15 @@ class WC_Product extends WC_Abstract_Legacy_Product {
$this->set_backorders( 'no' );
// If we are stock managing and we don't have stock, force out of stock status.
} elseif ( $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount' ) && 'no' === $this->get_backorders() ) {
} elseif ( $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount', 0 ) && 'no' === $this->get_backorders() ) {
$this->set_stock_status( 'outofstock' );
// If we are stock managing, backorders are allowed, and we don't have stock, force on backorder status.
} elseif ( $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount', 0 ) && 'no' !== $this->get_backorders() ) {
$this->set_stock_status( 'onbackorder' );
// If the stock level is changing and we do now have enough, force in stock status.
} elseif ( $this->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount' ) && array_key_exists( 'stock_quantity', $this->get_changes() ) ) {
} elseif ( $this->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount', 0 ) && array_key_exists( 'stock_quantity', $this->get_changes() ) ) {
$this->set_stock_status( 'instock' );
}
}
@ -1488,12 +1498,13 @@ class WC_Product extends WC_Abstract_Legacy_Product {
}
/**
* Returns whether or not the product is in stock.
* Returns whether or not the product can be purchased.
* This returns true for 'instock' and 'onbackorder' stock statuses.
*
* @return bool
*/
public function is_in_stock() {
return apply_filters( 'woocommerce_product_is_in_stock', 'instock' === $this->get_stock_status(), $this );
return apply_filters( 'woocommerce_product_is_in_stock', 'outofstock' !== $this->get_stock_status(), $this );
}
/**
@ -1520,7 +1531,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
* @return bool
*/
public function is_shipping_taxable() {
return $this->get_tax_status() === 'taxable' || $this->get_tax_status() === 'shipping';
return $this->needs_shipping() && ( $this->get_tax_status() === 'taxable' || $this->get_tax_status() === 'shipping' );
}
/**
@ -1560,6 +1571,10 @@ class WC_Product extends WC_Abstract_Legacy_Product {
* @return bool
*/
public function is_on_backorder( $qty_in_cart = 0 ) {
if ( 'onbackorder' === $this->get_stock_status() ) {
return true;
}
return $this->managing_stock() && $this->backorders_allowed() && ( $this->get_stock_quantity() - $qty_in_cart ) < 0 ? true : false;
}

View File

@ -111,7 +111,7 @@ class WC_Admin_Assets {
wp_register_script( 'wc-shipping-classes', WC()->plugin_url() . '/assets/js/admin/wc-shipping-classes' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone' ), WC_VERSION );
wp_register_script( 'wc-clipboard', WC()->plugin_url() . '/assets/js/admin/wc-clipboard' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
wp_register_script( 'select2', WC()->plugin_url() . '/assets/js/select2/select2.full' . $suffix . '.js', array( 'jquery' ), '4.0.3' );
wp_register_script( 'selectWoo', WC()->plugin_url() . '/assets/js/selectWoo/selectWoo.full' . $suffix . '.js', array( 'jquery' ), '1.0.1' );
wp_register_script( 'selectWoo', WC()->plugin_url() . '/assets/js/selectWoo/selectWoo.full' . $suffix . '.js', array( 'jquery' ), '1.0.2' );
wp_register_script( 'wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array( 'jquery', 'selectWoo' ), WC_VERSION );
wp_localize_script( 'wc-enhanced-select', 'wc_enhanced_select_params', array(
'i18n_no_matches' => _x( 'No matches found', 'enhanced select', 'woocommerce' ),

View File

@ -13,7 +13,9 @@ if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WC_Admin_Permalink_Settings', false ) ) :
if ( class_exists( 'WC_Admin_Permalink_Settings', false ) ) {
return new WC_Admin_Permalink_Settings();
}
/**
* WC_Admin_Permalink_Settings Class.
@ -39,30 +41,28 @@ class WC_Admin_Permalink_Settings {
* Init our settings.
*/
public function settings_init() {
// Add a section to the permalinks page
add_settings_section( 'woocommerce-permalink', __( 'Product permalinks', 'woocommerce' ), array( $this, 'settings' ), 'permalink' );
// Add our settings
add_settings_field(
'woocommerce_product_category_slug', // id
__( 'Product category base', 'woocommerce' ), // setting title
array( $this, 'product_category_slug_input' ), // display callback
'permalink', // settings page
'optional' // settings section
'woocommerce_product_category_slug',
__( 'Product category base', 'woocommerce' ),
array( $this, 'product_category_slug_input' ),
'permalink',
'optional'
);
add_settings_field(
'woocommerce_product_tag_slug', // id
__( 'Product tag base', 'woocommerce' ), // setting title
array( $this, 'product_tag_slug_input' ), // display callback
'permalink', // settings page
'optional' // settings section
'woocommerce_product_tag_slug',
__( 'Product tag base', 'woocommerce' ),
array( $this, 'product_tag_slug_input' ),
'permalink',
'optional'
);
add_settings_field(
'woocommerce_product_attribute_slug', // id
__( 'Product attribute base', 'woocommerce' ), // setting title
array( $this, 'product_attribute_slug_input' ), // display callback
'permalink', // settings page
'optional' // settings section
'woocommerce_product_attribute_slug',
__( 'Product attribute base', 'woocommerce' ),
array( $this, 'product_attribute_slug_input' ),
'permalink',
'optional'
);
$this->permalinks = wc_get_permalink_structure();
@ -99,9 +99,9 @@ class WC_Admin_Permalink_Settings {
* Show the settings.
*/
public function settings() {
echo wpautop( __( 'These settings control the permalinks used specifically for products.', 'woocommerce' ) );
/* translators: %s: Home URL */
echo wp_kses_post( wpautop( sprintf( __( 'If you like, you may enter custom structures for your product URLs here. For example, using <code>shop</code> would make your product links like <code>%sshop/sample-product/</code>. This setting affects product URLs only, not things such as product categories.', 'woocommerce' ), esc_url( home_url( '/' ) ) ) ) );
// Get shop page
$shop_page_id = wc_get_page_id( 'shop' );
$base_slug = urldecode( ( $shop_page_id > 0 && get_post( $shop_page_id ) ) ? get_page_uri( $shop_page_id ) : _x( 'shop', 'default-slug', 'woocommerce' ) );
$product_base = _x( 'product', 'default-slug', 'woocommerce' );
@ -115,28 +115,29 @@ class WC_Admin_Permalink_Settings {
<table class="form-table wc-permalink-structure">
<tbody>
<tr>
<th><label><input name="product_permalink" type="radio" value="<?php echo esc_attr( $structures[0] ); ?>" class="wctog" <?php checked( $structures[0], $this->permalinks['product_base'] ); ?> /> <?php _e( 'Default', 'woocommerce' ); ?></label></th>
<th><label><input name="product_permalink" type="radio" value="<?php echo esc_attr( $structures[0] ); ?>" class="wctog" <?php checked( $structures[0], $this->permalinks['product_base'] ); ?> /> <?php esc_html_e( 'Default', 'woocommerce' ); ?></label></th>
<td><code class="default-example"><?php echo esc_html( home_url() ); ?>/?product=sample-product</code> <code class="non-default-example"><?php echo esc_html( home_url() ); ?>/<?php echo esc_html( $product_base ); ?>/sample-product/</code></td>
</tr>
<?php if ( $shop_page_id ) : ?>
<tr>
<th><label><input name="product_permalink" type="radio" value="<?php echo esc_attr( $structures[1] ); ?>" class="wctog" <?php checked( $structures[1], $this->permalinks['product_base'] ); ?> /> <?php _e( 'Shop base', 'woocommerce' ); ?></label></th>
<th><label><input name="product_permalink" type="radio" value="<?php echo esc_attr( $structures[1] ); ?>" class="wctog" <?php checked( $structures[1], $this->permalinks['product_base'] ); ?> /> <?php esc_html_e( 'Shop base', 'woocommerce' ); ?></label></th>
<td><code><?php echo esc_html( home_url() ); ?>/<?php echo esc_html( $base_slug ); ?>/sample-product/</code></td>
</tr>
<tr>
<th><label><input name="product_permalink" type="radio" value="<?php echo esc_attr( $structures[2] ); ?>" class="wctog" <?php checked( $structures[2], $this->permalinks['product_base'] ); ?> /> <?php _e( 'Shop base with category', 'woocommerce' ); ?></label></th>
<th><label><input name="product_permalink" type="radio" value="<?php echo esc_attr( $structures[2] ); ?>" class="wctog" <?php checked( $structures[2], $this->permalinks['product_base'] ); ?> /> <?php esc_html_e( 'Shop base with category', 'woocommerce' ); ?></label></th>
<td><code><?php echo esc_html( home_url() ); ?>/<?php echo esc_html( $base_slug ); ?>/product-category/sample-product/</code></td>
</tr>
<?php endif; ?>
<tr>
<th><label><input name="product_permalink" id="woocommerce_custom_selection" type="radio" value="custom" class="tog" <?php checked( in_array( $this->permalinks['product_base'], $structures ), false ); ?> />
<?php _e( 'Custom base', 'woocommerce' ); ?></label></th>
<th><label><input name="product_permalink" id="woocommerce_custom_selection" type="radio" value="custom" class="tog" <?php checked( in_array( $this->permalinks['product_base'], $structures, true ), false ); ?> />
<?php esc_html_e( 'Custom base', 'woocommerce' ); ?></label></th>
<td>
<input name="product_permalink_structure" id="woocommerce_permalink_structure" type="text" value="<?php echo esc_attr( $this->permalinks['product_base'] ? trailingslashit( $this->permalinks['product_base'] ) : '' ); ?>" class="regular-text code"> <span class="description"><?php _e( 'Enter a custom base to use. A base <strong>must</strong> be set or WordPress will use default instead.', 'woocommerce' ); ?></span>
<input name="product_permalink_structure" id="woocommerce_permalink_structure" type="text" value="<?php echo esc_attr( $this->permalinks['product_base'] ? trailingslashit( $this->permalinks['product_base'] ) : '' ); ?>" class="regular-text code"> <span class="description"><?php esc_html_e( 'Enter a custom base to use. A base must be set or WordPress will use default instead.', 'woocommerce' ); ?></span>
</td>
</tr>
</tbody>
</table>
<?php wp_nonce_field( 'wc-permalinks', 'wc-permalinks-nonce' ); ?>
<script type="text/javascript">
jQuery( function() {
jQuery('input.wctog').change(function() {
@ -171,20 +172,20 @@ class WC_Admin_Permalink_Settings {
}
// We need to save the options ourselves; settings api does not trigger save for the permalinks page.
if ( isset( $_POST['permalink_structure'] ) ) {
if ( isset( $_POST['permalink_structure'], $_POST['wc-permalinks-nonce'], $_POST['woocommerce_product_category_slug'], $_POST['woocommerce_product_tag_slug'], $_POST['woocommerce_product_attribute_slug'] ) && wp_verify_nonce( wp_unslash( $_POST['wc-permalinks-nonce'] ), 'wc-permalinks' ) ) { // WPCS: input var ok, sanitization ok.
wc_switch_to_site_locale();
$permalinks = (array) get_option( 'woocommerce_permalinks', array() );
$permalinks['category_base'] = wc_sanitize_permalink( trim( $_POST['woocommerce_product_category_slug'] ) );
$permalinks['tag_base'] = wc_sanitize_permalink( trim( $_POST['woocommerce_product_tag_slug'] ) );
$permalinks['attribute_base'] = wc_sanitize_permalink( trim( $_POST['woocommerce_product_attribute_slug'] ) );
$permalinks['category_base'] = wc_sanitize_permalink( wp_unslash( $_POST['woocommerce_product_category_slug'] ) ); // WPCS: input var ok, sanitization ok.
$permalinks['tag_base'] = wc_sanitize_permalink( wp_unslash( $_POST['woocommerce_product_tag_slug'] ) ); // WPCS: input var ok, sanitization ok.
$permalinks['attribute_base'] = wc_sanitize_permalink( wp_unslash( $_POST['woocommerce_product_attribute_slug'] ) ); // WPCS: input var ok, sanitization ok.
// Generate product base.
$product_base = isset( $_POST['product_permalink'] ) ? wc_clean( $_POST['product_permalink'] ) : '';
$product_base = isset( $_POST['product_permalink'] ) ? wc_clean( wp_unslash( $_POST['product_permalink'] ) ) : ''; // WPCS: input var ok, sanitization ok.
if ( 'custom' === $product_base ) {
if ( isset( $_POST['product_permalink_structure'] ) ) {
$product_base = preg_replace( '#/+#', '/', '/' . str_replace( '#', '', trim( $_POST['product_permalink_structure'] ) ) );
if ( isset( $_POST['product_permalink_structure'] ) ) { // WPCS: input var ok.
$product_base = preg_replace( '#/+#', '/', '/' . str_replace( '#', '', trim( wp_unslash( $_POST['product_permalink_structure'] ) ) ) ); // WPCS: input var ok, sanitization ok.
} else {
$product_base = '/';
}
@ -213,6 +214,4 @@ class WC_Admin_Permalink_Settings {
}
}
endif;
return new WC_Admin_Permalink_Settings();

View File

@ -90,12 +90,15 @@ class WC_Admin_Post_Types {
switch ( $screen_id ) {
case 'edit-shop_order' :
include_once( 'list-tables/class-wc-admin-list-table-orders.php' );
new WC_Admin_List_Table_Orders();
break;
case 'edit-shop_coupon' :
include_once( 'list-tables/class-wc-admin-list-table-coupons.php' );
new WC_Admin_List_Table_Coupons();
break;
case 'edit-product' :
include_once( 'list-tables/class-wc-admin-list-table-products.php' );
new WC_Admin_List_Table_Products();
break;
}
}

View File

@ -83,11 +83,11 @@ class WC_Admin_Settings {
self::add_message( __( 'Your settings have been saved.', 'woocommerce' ) );
self::check_download_folder_protection();
// Clear any unwanted data and flush rules
// Clear any unwanted data and flush rules on next init.
add_option( 'woocommerce_queue_flush_rewrite_rules', 'true' );
delete_transient( 'woocommerce_cache_excluded_uris' );
WC()->query->init_query_vars();
WC()->query->add_endpoints();
wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' );
do_action( 'woocommerce_settings_saved' );
}

View File

@ -1664,7 +1664,7 @@ class WC_Admin_Setup_Wizard {
$docs_url = 'https://docs.woocommerce.com/documentation/plugins/woocommerce/getting-started/?utm_source=setupwizard&utm_medium=product&utm_content=docs&utm_campaign=woocommerceplugin';
$help_text = sprintf(
/* translators: %1$s: link to videos, %2$s: link to docs */
__( 'Watch our <a href="%1$s" target="_blank">guided tour videos</a> to learn more about WooCommerce, and visit WooCommerce.com to learn more about <a href="%2$s" target="_blank">getting started</a>.' ),
__( 'Watch our <a href="%1$s" target="_blank">guided tour videos</a> to learn more about WooCommerce, and visit WooCommerce.com to learn more about <a href="%2$s" target="_blank">getting started</a>.', 'woocommerce' ),
$videos_url,
$docs_url
);

View File

@ -115,7 +115,7 @@ class WC_Admin_Status {
}
// Bulk actions
if ( isset( $_GET['action'] ) && isset( $_GET['log'] ) ) {
if ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['log'] ) ) {
self::log_table_bulk_actions();
}
@ -315,9 +315,9 @@ class WC_Admin_Status {
wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
}
$log_ids = array_map( 'absint', (array) $_GET['log'] );
$log_ids = array_map( 'absint', (array) $_REQUEST['log'] );
if ( 'delete' === $_GET['action'] || 'delete' === $_GET['action2'] ) {
if ( 'delete' === $_REQUEST['action'] || 'delete' === $_REQUEST['action2'] ) {
WC_Log_Handler_DB::delete( $log_ids );
wp_safe_redirect( esc_url_raw( admin_url( 'admin.php?page=wc-status&tab=logs' ) ) );
exit();

View File

@ -135,9 +135,23 @@ class WC_Helper_Compat {
if ( is_plugin_active( 'woothemes-updater/woothemes-updater.php' ) ) {
deactivate_plugins( 'woothemes-updater/woothemes-updater.php' );
// Notify the user when the plugin is deactivated.
add_action( 'pre_current_active_plugins', array( __CLASS__, 'plugin_deactivation_notice' ) );
}
}
/**
* Display admin notice directing the user where to go.
*/
public static function plugin_deactivation_notice() {
?>
<div id="message" class="error is-dismissible">
<p><?php printf( __( 'The WooCommerce Helper plugin is no longer needed. <a href="%s">Manage subscriptions</a> from the extensions tab instead.', 'woocommerce' ), esc_url( admin_url( 'admin.php?page=wc-addons&section=helper' ) ) ); ?></p>
</div>
<?php
}
/**
* Register menu item.
*/

View File

@ -321,11 +321,9 @@ class WC_Helper {
/**
* Get available subscriptions filters.
*
* @param array Optional subscriptions array to generate counts.
*
* @return array An array of filter keys and labels.
*/
public static function get_filters( $subscriptions = null ) {
public static function get_filters() {
$filters = array(
'all' => __( 'All', 'woocommerce' ),
'active' => __( 'Active', 'woocommerce' ),

View File

@ -55,7 +55,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<td>
<input type="hidden" name="update_existing" value="0" />
<input type="checkbox" id="woocommerce-importer-update-existing" name="update_existing" value="1" />
<label for="woocommerce-importer-update-existing"><?php esc_html_e( 'If a product being imported matches an existing product by ID or SKU, update the existing product rather than creating a new product or skipping the row.', 'woocommerce' ); ?></label>
<label for="woocommerce-importer-update-existing"><?php esc_html_e( 'Existing products that match by ID or SKU will be updated. Products that do not exist will be skipped.', 'woocommerce' ); ?></label>
</td>
</tr>
<tr class="woocommerce-importer-advanced hidden">

View File

@ -13,7 +13,6 @@ if ( ! defined( 'ABSPATH' ) ) {
}
if ( class_exists( 'WC_Admin_List_Table_Coupons', false ) ) {
new WC_Admin_List_Table_Coupons();
return;
}
@ -233,5 +232,3 @@ class WC_Admin_List_Table_Coupons extends WC_Admin_List_Table {
return $query_vars;
}
}
new WC_Admin_List_Table_Coupons();

View File

@ -13,7 +13,6 @@ if ( ! defined( 'ABSPATH' ) ) {
}
if ( class_exists( 'WC_Admin_List_Table_Orders', false ) ) {
new WC_Admin_List_Table_Orders();
return;
}
@ -84,6 +83,7 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
return array(
'shipping_address',
'billing_address',
'wc_actions',
);
}
@ -114,15 +114,12 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
$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['billing_address'] = __( 'Billing', 'woocommerce' );
$show_columns['shipping_address'] = __( 'Ship to', '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' );
}
$show_columns['wc_actions'] = __( 'Actions', 'woocommerce' );
wp_enqueue_script( 'wc-orders' );
@ -140,9 +137,9 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
unset( $actions['edit'] );
}
$actions['mark_processing'] = __( 'Mark processing', 'woocommerce' );
$actions['mark_on-hold'] = __( 'Mark on-hold', 'woocommerce' );
$actions['mark_completed'] = __( 'Mark complete', 'woocommerce' );
$actions['mark_processing'] = __( 'Change status to processing', 'woocommerce' );
$actions['mark_on-hold'] = __( 'Change status to on-hold', 'woocommerce' );
$actions['mark_completed'] = __( 'Change status to completed', 'woocommerce' );
return $actions;
}
@ -227,7 +224,7 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
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' ) ) );
$show_date = $this->object->get_date_created()->date_i18n( apply_filters( 'woocommerce_admin_order_date_format', __( 'M j, Y', 'woocommerce' ) ) );
}
printf(
'<time datetime="%1$s" title="%2$s">%3$s</time>',
@ -250,9 +247,9 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
}
/**
* Render columm: order_actions.
* Render columm: wc_actions.
*/
protected function render_order_actions_column() {
protected function render_wc_actions_column() {
echo '<p>';
do_action( 'woocommerce_admin_order_actions_start', $this->object );
@ -261,25 +258,23 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
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',
'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',
'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'] ) );
}
echo wc_render_action_buttons( $actions ); // WPCS: XSS ok.
do_action( 'woocommerce_admin_order_actions_end', $this->object );
@ -292,6 +287,11 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
protected function render_billing_address_column() {
if ( $address = $this->object->get_formatted_billing_address() ) {
echo esc_html( preg_replace( '#<br\s*/?>#i', ', ', $address ) );
if ( $this->object->get_payment_method() ) {
/* translators: %s: payment method */
echo '<span class="description">' . sprintf( __( 'via %s', 'woocommerce' ), esc_html( $this->object->get_payment_method_title() ) ) . '</span>';
}
} else {
echo '&ndash;';
}
@ -303,6 +303,10 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
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>';
if ( $this->object->get_shipping_method() ) {
/* translators: %s: shipping method */
echo '<span class="description">' . sprintf( __( 'via %s', 'woocommerce' ), esc_html( $this->object->get_shipping_method() ) ) . '</span>';
}
} else {
echo '&ndash;';
}
@ -320,6 +324,7 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
<div class="wc-backbone-modal-content">
<section class="wc-backbone-modal-main" role="main">
<header class="wc-backbone-modal-header">
<mark class="order-status status-{{ data.status }}"><span>{{ data.status_name }}</span></mark>
<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>
@ -328,8 +333,6 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
<article>
<?php do_action( 'woocommerce_admin_order_preview_start' ); ?>
{{{ data.item_html }}}
<div class="wc-order-preview-addresses">
<div class="wc-order-preview-address">
<h2><?php esc_html_e( 'Billing details', 'woocommerce' ); ?></h2>
@ -347,7 +350,7 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
<# if ( data.payment_via ) { #>
<strong><?php esc_html_e( 'Payment via', 'woocommerce' ); ?></strong>
{{ data.payment_via }}
{{{ data.payment_via }}}
<# } #>
</div>
<# if ( data.needs_shipping ) { #>
@ -371,10 +374,15 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
</div>
<# } #>
</div>
{{{ data.item_html }}}
<?php do_action( 'woocommerce_admin_order_preview_end' ); ?>
</article>
<footer>
<div class="inner">
{{{ data.actions_html }}}
<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>
@ -386,6 +394,191 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
<?php
}
/**
* Get items to display in the preview as HTML.
*
* @param WC_Order $order Order object.
* @return string
*/
public static function get_order_preview_item_html( $order ) {
$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',
) );
$line_items = apply_filters( 'woocommerce_admin_order_preview_line_items', $order->get_items(), $order );
$columns = apply_filters( 'woocommerce_admin_order_preview_line_item_columns', array(
'product' => __( 'Product', 'woocommerce' ),
'quantity' => __( 'Quantity', 'woocommerce' ),
'tax' => __( 'Tax', 'woocommerce' ),
'total' => __( 'Total', 'woocommerce' ),
), $order );
if ( ! wc_tax_enabled() ) {
unset( $columns['tax'] );
}
$html = '
<div class="wc-order-preview-table-wrapper">
<table cellspacing="0" class="wc-order-preview-table">
<thead>
<tr>';
foreach ( $columns as $column => $label ) {
$html .= '<th class="wc-order-preview-table__column--' . esc_attr( $column ) . '">' . esc_html( $label ) . '</th>';
}
$html .= '
</tr>
</thead>
<tbody>';
foreach ( $line_items as $item_id => $item ) {
$product_object = is_callable( array( $item, 'get_product' ) ) ? $item->get_product() : null;
$html .= '<tr class="wc-order-preview-table__item wc-order-preview-table__item--' . esc_attr( $item_id ) . '">';
foreach ( $columns as $column => $label ) {
$html .= '<td class="wc-order-preview-table__column--' . esc_attr( $column ) . '">';
switch ( $column ) {
case 'product':
$html .= wp_kses_post( $item->get_name() );
if ( $product_object ) {
$html .= '<div class="wc-order-item-sku">' . esc_html( $product_object->get_sku() ) . '</div>';
}
if ( $meta_data = $item->get_formatted_meta_data( '' ) ) {
$html .= '<table cellspacing="0" class="wc-order-item-meta">';
foreach ( $meta_data as $meta_id => $meta ) {
if ( in_array( $meta->key, $hidden_order_itemmeta ) ) {
continue;
}
$html .= '<tr><th>' . wp_kses_post( $meta->display_key ) . ':</th><td>' . wp_kses_post( force_balance_tags( $meta->display_value ) ) . '</td></tr>';
}
$html .= '</table>';
}
break;
case 'quantity':
$html .= esc_html( $item->get_quantity() );
break;
case 'tax':
$html .= wc_price( $item->get_total_tax(), array( 'currency' => $order->get_currency() ) );
break;
case 'total':
$html .= wc_price( $item->get_total(), array( 'currency' => $order->get_currency() ) );
break;
default :
$html .= apply_filters( 'woocommerce_admin_order_preview_line_item_column_' . sanitize_key( $column ), '', $item, $item_id, $order );
break;
}
$html .= '</td>';
}
$html .= '</tr>';
}
$html .= '
</tbody>
</table>
</div>';
return $html;
}
/**
* Get actions to display in the preview as HTML.
*
* @param WC_Order $order Order object.
* @return string
*/
public static function get_order_preview_actions_html( $order ) {
$actions = array();
$status_actions = array();
if ( $order->has_status( array( 'pending' ) ) ) {
$status_actions['on-hold'] = array(
'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=on-hold&order_id=' . $order->get_id() ), 'woocommerce-mark-order-status' ),
'name' => __( 'On-hold', 'woocommerce' ),
'action' => 'on-hold',
);
}
if ( $order->has_status( array( 'pending', 'on-hold' ) ) ) {
$status_actions['processing'] = array(
'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=processing&order_id=' . $order->get_id() ), 'woocommerce-mark-order-status' ),
'name' => __( 'Processing', 'woocommerce' ),
'action' => 'processing',
);
}
if ( $order->has_status( array( 'pending', 'on-hold', 'processing' ) ) ) {
$status_actions['complete'] = array(
'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce_mark_order_status&status=completed&order_id=' . $order->get_id() ), 'woocommerce-mark-order-status' ),
'name' => __( 'Completed', 'woocommerce' ),
'action' => 'complete',
);
}
if ( $status_actions ) {
$actions['status'] = array(
'group' => __( 'Change status: ', 'woocommerce' ),
'actions' => $status_actions,
);
}
return wc_render_action_buttons( apply_filters( 'woocommerce_admin_order_preview_actions', $actions, $order ) );
}
/**
* Get order details to send to the ajax endpoint for previews.
*
* @param WC_Order $order Order object.
* @return array
*/
public static function order_preview_get_order_details( $order ) {
if ( ! $order ) {
return array();
}
$payment_via = $order->get_payment_method_title();
$payment_method = $order->get_payment_method();
$payment_gateways = WC()->payment_gateways() ? WC()->payment_gateways->payment_gateways() : array();
if ( $transaction_id = $order->get_transaction_id() ) {
if ( isset( $payment_gateways[ $payment_method ] ) && ( $url = $payment_gateways[ $payment_method ]->get_transaction_url( $order ) ) ) {
$payment_via .= ' (<a href="' . esc_url( $url ) . '" target="_blank">' . esc_html( $transaction_id ) . '</a>)';
} else {
$payment_via .= ' (' . esc_html( $transaction_id ) . ')';
}
}
return apply_filters( 'woocommerce_admin_order_preview_get_order_details', array(
'data' => $order->get_data(),
'order_number' => $order->get_order_number(),
'item_html' => WC_Admin_List_Table_Orders::get_order_preview_item_html( $order ),
'actions_html' => WC_Admin_List_Table_Orders::get_order_preview_actions_html( $order ),
'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' => $payment_via,
'shipping_via' => $order->get_shipping_method(),
'status' => $order->get_status(),
'status_name' => wc_get_order_status_name( $order->get_status() ),
), $order );
}
/**
* Handle bulk actions.
*
@ -610,5 +803,3 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
}
}
}
new WC_Admin_List_Table_Orders();

View File

@ -13,7 +13,6 @@ if ( ! defined( 'ABSPATH' ) ) {
}
if ( class_exists( 'WC_Admin_List_Table_Products', false ) ) {
new WC_Admin_List_Table_Products();
return;
}
@ -233,7 +232,7 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
$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.
echo apply_filters( 'woocommerce_admin_product_term_list', implode( ', ', $termlist ), 'product_cat', $this->object->get_id(), $termlist, $terms ); // WPCS: XSS ok.
}
}
@ -249,7 +248,7 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
$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.
echo apply_filters( 'woocommerce_admin_product_term_list', implode( ', ', $termlist ), 'product_tag', $this->object->get_id(), $termlist, $terms ); // WPCS: XSS ok.
}
}
@ -271,7 +270,9 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
* Render columm: is_in_stock.
*/
protected function render_is_in_stock_column() {
if ( $this->object->is_in_stock() ) {
if ( $this->object->is_on_backorder() ) {
$stock_html = '<mark class="onbackorder">' . __( 'On backorder', 'woocommerce' ) . '</mark>';
} elseif ( $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>';
@ -299,22 +300,27 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
* 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
$categories_count = (int) wp_count_terms( 'product_cat' );
$terms = get_terms( 'product_type' );
$output = '<select name="product_type" id="dropdown_product_type">';
$output .= '<option value="">' . __( 'Filter by product type', 'woocommerce' ) . '</option>';
if ( $categories_count <= apply_filters( 'woocommerce_product_category_filter_threshold', 100 ) ) {
wc_product_dropdown_categories( array(
'option_select_text' => __( 'Filter by category', 'woocommerce' ),
) );
} else {
$current_category_slug = isset( $_GET['product_cat'] ) ? wc_clean( wp_unslash( $_GET['product_cat'] ) ) : false; // WPCS: input var ok, CSRF ok.
$current_category = $current_category_slug ? get_term_by( 'slug', $current_category_slug, 'product_cat' ) : false;
?>
<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
}
$current_product_type = isset( $_REQUEST['product_type'] ) ? wc_clean( wp_unslash( $_REQUEST['product_type'] ) ) : false; // WPCS: input var ok, sanitization ok.
$terms = get_terms( 'product_type' );
$output = '<select name="product_type" id="dropdown_product_type"><option value="">' . __( 'Filter by product type', 'woocommerce' ) . '</option>';
foreach ( $terms as $term ) {
$output .= '<option value="' . sanitize_title( $term->name ) . '" ';
@ -362,6 +368,16 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
$output .= '</select>';
$current_stock_status = isset( $_REQUEST['stock_status'] ) ? wc_clean( wp_unslash( $_REQUEST['stock_status'] ) ): false; // WPCS: input var ok, sanitization ok.
$stock_statuses = wc_get_product_stock_status_options();
$output .= '<select name="stock_status"><option value="">' . esc_html__( 'Filter by stock status', 'woocommerce' ) . '</option>';
foreach ( $stock_statuses as $status => $label ) {
$output .= '<option ' . selected( $status, $current_stock_status, false ) . ' value="' . esc_attr( $status ) . '">' . esc_html( $label ) . '</option>';
}
$output .= '</select>';
echo apply_filters( 'woocommerce_product_filters', $output ); // WPCS: XSS ok.
}
@ -372,6 +388,7 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
* @return array
*/
protected function query_filters( $query_vars ) {
if ( isset( $query_vars['orderby'] ) ) {
if ( 'price' === $vars['orderby'] ) {
// @codingStandardsIgnoreStart
@ -414,6 +431,17 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
);
}
if ( ! empty( $_GET['stock_status'] ) ) {
if ( ! isset( $query_vars['meta_query'] ) ) {
$query_vars['meta_query'] = array();
}
$query_vars['meta_query'][] = array(
'key' => '_stock_status',
'value' => wc_clean( wp_unslash( $_GET['stock_status'] ) ),
);
}
return $query_vars;
}
@ -478,5 +506,3 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
return $views;
}
}
new WC_Admin_List_Table_Products();

View File

@ -188,9 +188,9 @@ class WC_Meta_Box_Order_Data {
if ( $transaction_id = $order->get_transaction_id() ) {
if ( isset( $payment_gateways[ $payment_method ] ) && ( $url = $payment_gateways[ $payment_method ]->get_transaction_url( $order ) ) ) {
$payment_method_string = ' (<a href="' . esc_url( $url ) . '" target="_blank">' . esc_html( $transaction_id ) . '</a>)';
$payment_method_string .= ' (<a href="' . esc_url( $url ) . '" target="_blank">' . esc_html( $transaction_id ) . '</a>)';
} else {
$payment_method_string = ' (' . esc_html( $transaction_id ) . ')';
$payment_method_string .= ' (' . esc_html( $transaction_id ) . ')';
}
}

View File

@ -284,12 +284,18 @@ class WC_Meta_Box_Product_Data {
$attribute_key = sanitize_title( $attribute->get_name() );
if ( ! is_null( $index ) ) {
$value = isset( $_POST[ $key_prefix . $attribute_key ][ $index ] ) ? stripslashes( $_POST[ $key_prefix . $attribute_key ][ $index ] ) : '';
$value = isset( $_POST[ $key_prefix . $attribute_key ][ $index ] ) ? wp_unslash( $_POST[ $key_prefix . $attribute_key ][ $index ] ) : '';
} else {
$value = isset( $_POST[ $key_prefix . $attribute_key ] ) ? stripslashes( $_POST[ $key_prefix . $attribute_key ] ) : '';
$value = isset( $_POST[ $key_prefix . $attribute_key ] ) ? wp_unslash( $_POST[ $key_prefix . $attribute_key ] ) : '';
}
if ( $attribute->is_taxonomy() ) {
// Don't use wc_clean as it destroys sanitized characters.
$value = sanitize_title( $value );
} else {
$value = html_entity_decode( wc_clean( $value ), ENT_QUOTES, get_bloginfo( 'charset' ) ); // WPCS: sanitization ok.
}
$value = $attribute->is_taxonomy() ? sanitize_title( $value ) : wc_clean( $value ); // Don't use wc_clean as it destroys sanitized characters in terms.
$attributes[ $attribute_key ] = $value;
}
}

View File

@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
<div class="wc-metabox closed">
<h3 class="fixed">
<button type="button" data-permission_id="<?php echo esc_attr( $download->get_id() ); ?>" rel="<?php echo esc_attr( $download->get_product_id() ) . ',' . esc_attr( $download->get_download_id() ); ?>" class="revoke_access button"><?php _e( 'Revoke access', 'woocommerce' ); ?></button>
<button type="button" data-permission_id="<?php echo esc_attr( $download->get_id() ); ?>" rel="<?php echo esc_attr( $download->get_product_id() ) . ',' . esc_attr( $download->get_download_id() ); ?>" class="revoke_access button"><?php esc_html_e( 'Revoke access', 'woocommerce' ); ?></button>
<div class="handlediv" aria-label="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div>
<strong><?php
printf(
@ -16,19 +16,19 @@ if ( ! defined( 'ABSPATH' ) ) {
esc_html( wc_get_filename_from_url( $product->get_file_download_path( $download->get_download_id() ) ) )
);
printf( _n( 'Downloaded %s time', 'Downloaded %s times', $download->get_download_count(), 'woocommerce' ), esc_html( $download->get_download_count() ) )
?></strong>
?></strong>
</h3>
<table cellpadding="0" cellspacing="0" class="wc-metabox-content">
<tbody>
<tr>
<td>
<label><?php esc_html_e( 'Downloads remaining', 'woocommerce' ); ?></label>
<input type="hidden" name="permission_id[<?php echo $loop; ?>]" value="<?php echo esc_attr( $download->get_id() ); ?>" />
<input type="number" step="1" min="0" class="short" name="downloads_remaining[<?php echo $loop; ?>]" value="<?php echo esc_attr( $download->get_downloads_remaining() ); ?>" placeholder="<?php esc_attr_e( 'Unlimited', 'woocommerce' ); ?>" />
<input type="hidden" name="permission_id[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( $download->get_id() ); ?>" />
<input type="number" step="1" min="0" class="short" name="downloads_remaining[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( $download->get_downloads_remaining() ); ?>" placeholder="<?php esc_attr_e( 'Unlimited', 'woocommerce' ); ?>" />
</td>
<td>
<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 esc_attr( $loop ); ?>]" value="<?php echo ! is_null( $download->get_access_expires() ) ? esc_attr( date_i18n( 'Y-m-d', $download->get_access_expires()->getTimestamp() ) ) : ''; ?>" maxlength="10" placeholder="<?php esc_attr_e( 'Never', 'woocommerce' ); ?>" pattern="<?php echo esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ); ?>" />
</td>
<td>
<label><?php esc_html_e( 'Customer download link', 'woocommerce' ); ?></label>

View File

@ -10,7 +10,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<tr class="fee <?php echo ( ! empty( $class ) ) ? $class : ''; ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>">
<tr class="fee <?php echo ( ! empty( $class ) ) ? esc_attr( $class ) : ''; ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>">
<td class="thumb"><div></div></td>
<td class="name">
@ -22,7 +22,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<input type="hidden" class="order_item_id" name="order_item_id[]" value="<?php echo esc_attr( $item_id ); ?>" />
<input type="hidden" name="order_item_tax_class[<?php echo absint( $item_id ); ?>]" value="<?php echo esc_attr( $item->get_tax_class() ); ?>" />
</div>
<?php do_action( 'woocommerce_after_order_fee_item_name', $item_id, $item, null ) ?>
<?php do_action( 'woocommerce_after_order_fee_item_name', $item_id, $item, null ); ?>
</td>
<?php do_action( 'woocommerce_admin_order_item_values', null, $item, absint( $item_id ) ); ?>
@ -41,10 +41,10 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
</div>
<div class="edit" style="display: none;">
<input type="text" name="line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" />
<input type="text" name="line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" />
</div>
<div class="refund" style="display: none;">
<input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_total wc_input_price" />
<input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_total wc_input_price" />
</div>
</td>
@ -65,10 +65,10 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
</div>
<div class="edit" style="display: none;">
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" />
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" />
</div>
<div class="refund" style="display: none;">
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
</div>
</td>

View File

@ -18,8 +18,9 @@ $hidden_order_itemmeta = apply_filters( 'woocommerce_hidden_order_itemmeta', arr
?><div class="view">
<?php if ( $meta_data = $item->get_formatted_meta_data( '' ) ) : ?>
<table cellspacing="0" class="display_meta">
<?php foreach ( $meta_data as $meta_id => $meta ) :
if ( in_array( $meta->key, $hidden_order_itemmeta ) ) {
<?php
foreach ( $meta_data as $meta_id => $meta ) :
if ( in_array( $meta->key, $hidden_order_itemmeta, true ) ) {
continue;
}
?>
@ -35,8 +36,9 @@ $hidden_order_itemmeta = apply_filters( 'woocommerce_hidden_order_itemmeta', arr
<table class="meta" cellspacing="0">
<tbody class="meta_items">
<?php if ( $meta_data = $item->get_formatted_meta_data( '' ) ) : ?>
<?php foreach ( $meta_data as $meta_id => $meta ) :
if ( in_array( $meta->key, $hidden_order_itemmeta ) ) {
<?php
foreach ( $meta_data as $meta_id => $meta ) :
if ( in_array( $meta->key, $hidden_order_itemmeta, true ) ) {
continue;
}
?>
@ -52,7 +54,7 @@ $hidden_order_itemmeta = apply_filters( 'woocommerce_hidden_order_itemmeta', arr
</tbody>
<tfoot>
<tr>
<td colspan="4"><button class="add_order_item_meta button"><?php _e( 'Add&nbsp;meta', 'woocommerce' ); ?></button></td>
<td colspan="4"><button class="add_order_item_meta button"><?php esc_html_e( 'Add&nbsp;meta', 'woocommerce' ); ?></button></td>
</tr>
</tfoot>
</table>

View File

@ -11,8 +11,9 @@ if ( ! defined( 'ABSPATH' ) ) {
$product = $item->get_product();
$product_link = $product ? admin_url( 'post.php?post=' . $item->get_product_id() . '&action=edit' ) : '';
$thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnail', $product->get_image( 'thumbnail', array( 'title' => '' ), false ), $item_id, $item ) : '';
$row_class = apply_filters( 'woocommerce_admin_html_order_item_class', ! empty( $class ) ? $class : '', $item, $order );
?>
<tr class="item <?php echo apply_filters( 'woocommerce_admin_html_order_item_class', ( ! empty( $class ) ? $class : '' ), $item, $order ); ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>">
<tr class="item <?php echo esc_attr( $row_class ); ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>">
<td class="thumb">
<?php echo '<div class="wc-order-item-thumbnail">' . wp_kses_post( $thumbnail ) . '</div>'; ?>
</td>
@ -21,11 +22,11 @@ $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnai
echo $product_link ? '<a href="' . esc_url( $product_link ) . '" class="wc-order-item-name">' . esc_html( $item->get_name() ) . '</a>' : '<div class="wc-order-item-name">' . esc_html( $item->get_name() ) . '</div>';
if ( $product && $product->get_sku() ) {
echo '<div class="wc-order-item-sku"><strong>' . __( 'SKU:', 'woocommerce' ) . '</strong> ' . esc_html( $product->get_sku() ) . '</div>';
echo '<div class="wc-order-item-sku"><strong>' . esc_html__( 'SKU:', 'woocommerce' ) . '</strong> ' . esc_html( $product->get_sku() ) . '</div>';
}
if ( $item->get_variation_id() ) {
echo '<div class="wc-order-item-variation"><strong>' . __( 'Variation ID:', 'woocommerce' ) . '</strong> ';
echo '<div class="wc-order-item-variation"><strong>' . esc_html__( 'Variation ID:', 'woocommerce' ) . '</strong> ';
if ( 'product_variation' === get_post_type( $item->get_variation_id() ) ) {
echo esc_html( $item->get_variation_id() );
} else {
@ -38,9 +39,9 @@ $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnai
<input type="hidden" class="order_item_id" name="order_item_id[]" value="<?php echo esc_attr( $item_id ); ?>" />
<input type="hidden" name="order_item_tax_class[<?php echo absint( $item_id ); ?>]" value="<?php echo esc_attr( $item->get_tax_class() ); ?>" />
<?php do_action( 'woocommerce_before_order_itemmeta', $item_id, $item, $product ) ?>
<?php do_action( 'woocommerce_before_order_itemmeta', $item_id, $item, $product ); ?>
<?php include( 'html-order-item-meta.php' ); ?>
<?php do_action( 'woocommerce_after_order_itemmeta', $item_id, $item, $product ) ?>
<?php do_action( 'woocommerce_after_order_itemmeta', $item_id, $item, $product ); ?>
</td>
<?php do_action( 'woocommerce_admin_order_item_values', $product, $item, absint( $item_id ) ); ?>
@ -67,10 +68,10 @@ $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnai
?>
</div>
<div class="edit" style="display: none;">
<input type="number" step="<?php echo apply_filters( 'woocommerce_quantity_input_step', '1', $product ); ?>" min="0" autocomplete="off" name="order_item_qty[<?php echo absint( $item_id ); ?>]" placeholder="0" value="<?php echo esc_attr( $item->get_quantity() ); ?>" data-qty="<?php echo esc_attr( $item->get_quantity() ); ?>" size="4" class="quantity" />
<input type="number" step="<?php echo esc_attr( apply_filters( 'woocommerce_quantity_input_step', '1', $product ) ); ?>" min="0" autocomplete="off" name="order_item_qty[<?php echo absint( $item_id ); ?>]" placeholder="0" value="<?php echo esc_attr( $item->get_quantity() ); ?>" data-qty="<?php echo esc_attr( $item->get_quantity() ); ?>" size="4" class="quantity" />
</div>
<div class="refund" style="display: none;">
<input type="number" step="<?php echo apply_filters( 'woocommerce_quantity_input_step', '1', $product ); ?>" min="0" max="<?php echo $item->get_quantity(); ?>" autocomplete="off" name="refund_order_item_qty[<?php echo absint( $item_id ); ?>]" placeholder="0" size="4" class="refund_order_item_qty" />
<input type="number" step="<?php echo esc_attr( apply_filters( 'woocommerce_quantity_input_step', '1', $product ) ); ?>" min="0" max="<?php echo absint( $item->get_quantity() ); ?>" autocomplete="off" name="refund_order_item_qty[<?php echo absint( $item_id ); ?>]" placeholder="0" size="4" class="refund_order_item_qty" />
</div>
</td>
<td class="line_cost" width="1%" data-sort-value="<?php echo esc_attr( $item->get_total() ); ?>">
@ -91,16 +92,16 @@ $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnai
<div class="split-input">
<div class="input">
<label><?php esc_attr_e( 'Pre-discount:', 'woocommerce' ); ?></label>
<input type="text" name="line_subtotal[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_subtotal() ) ); ?>" class="line_subtotal wc_input_price" data-subtotal="<?php echo esc_attr( wc_format_localized_price( $item->get_subtotal() ) ); ?>" />
<input type="text" name="line_subtotal[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_subtotal() ) ); ?>" class="line_subtotal wc_input_price" data-subtotal="<?php echo esc_attr( wc_format_localized_price( $item->get_subtotal() ) ); ?>" />
</div>
<div class="input">
<label><?php esc_attr_e( 'Total:', 'woocommerce' ); ?></label>
<input type="text" name="line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" data-tip="<?php esc_attr_e( 'After pre-tax discounts.', 'woocommerce' ); ?>" data-total="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" />
<input type="text" name="line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" data-tip="<?php esc_attr_e( 'After pre-tax discounts.', 'woocommerce' ); ?>" data-total="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" />
</div>
</div>
</div>
<div class="refund" style="display: none;">
<input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_total wc_input_price" />
<input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_total wc_input_price" />
</div>
</td>
@ -114,7 +115,7 @@ $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnai
<td class="line_tax" width="1%">
<div class="view">
<?php
if ( '' != $tax_item_total ) {
if ( '' !== $tax_item_total ) {
echo wc_price( wc_round_tax_total( $tax_item_total ), array( 'currency' => $order->get_currency() ) );
} else {
echo '&ndash;';
@ -137,16 +138,16 @@ $thumbnail = $product ? apply_filters( 'woocommerce_admin_order_item_thumbnai
<div class="split-input">
<div class="input">
<label><?php esc_attr_e( 'Pre-discount:', 'woocommerce' ); ?></label>
<input type="text" name="line_subtotal_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $tax_item_subtotal ) ); ?>" class="line_subtotal_tax wc_input_price" data-subtotal_tax="<?php echo esc_attr( wc_format_localized_price( $tax_item_subtotal ) ); ?>" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
<input type="text" name="line_subtotal_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $tax_item_subtotal ) ); ?>" class="line_subtotal_tax wc_input_price" data-subtotal_tax="<?php echo esc_attr( wc_format_localized_price( $tax_item_subtotal ) ); ?>" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
</div>
<div class="input">
<label><?php esc_attr_e( 'Total:', 'woocommerce' ); ?></label>
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $tax_item_total ) ); ?>" class="line_tax wc_input_price" data-total_tax="<?php echo esc_attr( wc_format_localized_price( $tax_item_total ) ); ?>" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $tax_item_total ) ); ?>" class="line_tax wc_input_price" data-total_tax="<?php echo esc_attr( wc_format_localized_price( $tax_item_total ) ); ?>" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
</div>
</div>
</div>
<div class="refund" style="display: none;">
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
</div>
</td>
<?php

View File

@ -26,23 +26,24 @@ if ( wc_tax_enabled() ) {
<table cellpadding="0" cellspacing="0" class="woocommerce_order_items">
<thead>
<tr>
<th class="item sortable" colspan="2" data-sort="string-ins"><?php _e( 'Item', 'woocommerce' ); ?></th>
<th class="item sortable" colspan="2" data-sort="string-ins"><?php esc_html_e( 'Item', 'woocommerce' ); ?></th>
<?php do_action( 'woocommerce_admin_order_item_headers', $order ); ?>
<th class="item_cost sortable" data-sort="float"><?php _e( 'Cost', 'woocommerce' ); ?></th>
<th class="quantity sortable" data-sort="int"><?php _e( 'Qty', 'woocommerce' ); ?></th>
<th class="line_cost sortable" data-sort="float"><?php _e( 'Total', 'woocommerce' ); ?></th>
<th class="item_cost sortable" data-sort="float"><?php esc_html_e( 'Cost', 'woocommerce' ); ?></th>
<th class="quantity sortable" data-sort="int"><?php esc_html_e( 'Qty', 'woocommerce' ); ?></th>
<th class="line_cost sortable" data-sort="float"><?php esc_html_e( 'Total', 'woocommerce' ); ?></th>
<?php
if ( ! empty( $order_taxes ) ) :
foreach ( $order_taxes as $tax_id => $tax_item ) :
$tax_class = wc_get_tax_class_by_tax_id( $tax_item['rate_id'] );
$tax_class_name = isset( $classes_options[ $tax_class ] ) ? $classes_options[ $tax_class ] : __( 'Tax', 'woocommerce' );
$column_label = ! empty( $tax_item['label'] ) ? $tax_item['label'] : __( 'Tax', 'woocommerce' );
/* translators: %1$s: tax item name %2$s: tax class name */
$column_tip = sprintf( esc_html__( '%1$s (%2$s)', 'woocommerce' ), $tax_item['name'], $tax_class_name );
?>
<th class="line_tax tips" data-tip="<?php echo esc_attr( $column_tip ); ?>">
<?php echo esc_attr( $column_label ); ?>
<input type="hidden" class="order-tax-id" name="order_taxes[<?php echo $tax_id; ?>]" value="<?php echo esc_attr( $tax_item['rate_id'] ); ?>">
<a class="delete-order-tax" href="#" data-rate_id="<?php echo $tax_id; ?>"></a>
<input type="hidden" class="order-tax-id" name="order_taxes[<?php echo esc_attr( $tax_id ); ?>]" value="<?php echo esc_attr( $tax_item['rate_id'] ); ?>">
<a class="delete-order-tax" href="#" data-rate_id="<?php echo esc_attr( $tax_id ); ?>"></a>
</th>
<?php
endforeach;
@ -94,11 +95,11 @@ if ( wc_tax_enabled() ) {
</div>
<div class="wc-order-data-row wc-order-item-bulk-edit" style="display:none;">
<?php if ( $order->is_editable() ) : ?>
<button type="button" class="button bulk-delete-items"><?php _e( 'Delete selected row(s)', 'woocommerce' ); ?></button>
<button type="button" class="button bulk-delete-items"><?php esc_html_e( 'Delete selected row(s)', 'woocommerce' ); ?></button>
<?php endif; ?>
<button type="button" class="button bulk-decrease-stock"><?php _e( 'Reduce stock', 'woocommerce' ); ?></button>
<button type="button" class="button bulk-increase-stock"><?php _e( 'Increase stock', 'woocommerce' ); ?></button>
<button type="button" class="button bulk-decrease-stock"><?php esc_html_e( 'Reduce stock', 'woocommerce' ); ?></button>
<button type="button" class="button bulk-increase-stock"><?php esc_html_e( 'Increase stock', 'woocommerce' ); ?></button>
<?php do_action( 'woocommerce_admin_order_item_bulk_actions', $order ); ?>
</div>
<div class="wc-order-data-row wc-order-totals-items wc-order-items-editable">
@ -108,7 +109,7 @@ if ( wc_tax_enabled() ) {
?>
<div class="wc-used-coupons">
<ul class="wc_coupon_list"><?php
echo '<li><strong>' . __( 'Coupon(s)', 'woocommerce' ) . '</strong></li>';
echo '<li><strong>' . esc_html__( 'Coupon(s)', 'woocommerce' ) . '</strong></li>';
foreach ( $coupons as $item_id => $item ) {
$post_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_title = %s AND post_type = 'shop_coupon' AND post_status = 'publish' LIMIT 1;", $item->get_code() ) );
@ -126,7 +127,7 @@ if ( wc_tax_enabled() ) {
<table class="wc-order-totals">
<?php if ( 0 < $order->get_total_discount() ) : ?>
<tr>
<td class="label"><?php _e( 'Discount:', 'woocommerce' ); ?></td>
<td class="label"><?php esc_html_e( 'Discount:', 'woocommerce' ); ?></td>
<td width="1%"></td>
<td class="total">
<?php echo wc_price( $order->get_total_discount(), array( 'currency' => $order->get_currency() ) ); ?>
@ -138,10 +139,12 @@ if ( wc_tax_enabled() ) {
<?php if ( $order->get_shipping_methods() ) : ?>
<tr>
<td class="label"><?php _e( 'Shipping:', 'woocommerce' ); ?></td>
<td class="label"><?php esc_html_e( 'Shipping:', 'woocommerce' ); ?></td>
<td width="1%"></td>
<td class="total"><?php
if ( ( $refunded = $order->get_total_shipping_refunded() ) > 0 ) {
<td class="total">
<?php
$refunded = $order->get_total_shipping_refunded();
if ( $refunded > 0 ) {
echo '<del>' . strip_tags( wc_price( $order->get_shipping_total(), array( 'currency' => $order->get_currency() ) ) ) . '</del> <ins>' . wc_price( $order->get_shipping_total() - $refunded, array( 'currency' => $order->get_currency() ) ) . '</ins>';
} else {
echo wc_price( $order->get_shipping_total(), array( 'currency' => $order->get_currency() ) );
@ -155,15 +158,18 @@ if ( wc_tax_enabled() ) {
<?php if ( wc_tax_enabled() ) : ?>
<?php foreach ( $order->get_tax_totals() as $code => $tax ) : ?>
<tr>
<td class="label"><?php echo $tax->label; ?>:</td>
<td class="label"><?php echo esc_html( $tax->label ); ?>:</td>
<td width="1%"></td>
<td class="total"><?php
if ( ( $refunded = $order->get_total_tax_refunded_by_rate_id( $tax->rate_id ) ) > 0 ) {
<td class="total">
<?php
$refunded = $order->get_total_tax_refunded_by_rate_id( $tax->rate_id );
if ( $refunded > 0 ) {
echo '<del>' . strip_tags( $tax->formatted_amount ) . '</del> <ins>' . wc_price( WC_Tax::round( $tax->amount, wc_get_price_decimals() ) - WC_Tax::round( $refunded, wc_get_price_decimals() ), array( 'currency' => $order->get_currency() ) ) . '</ins>';
} else {
echo $tax->formatted_amount;
}
?></td>
?>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
@ -171,7 +177,7 @@ if ( wc_tax_enabled() ) {
<?php do_action( 'woocommerce_admin_order_totals_after_tax', $order->get_id() ); ?>
<tr>
<td class="label"><?php _e( 'Total', 'woocommerce' ); ?>:</td>
<td class="label"><?php esc_html_e( 'Total', 'woocommerce' ); ?>:</td>
<td width="1%"></td>
<td class="total">
<?php echo $order->get_formatted_order_total(); ?>
@ -182,7 +188,7 @@ if ( wc_tax_enabled() ) {
<?php if ( $order->get_total_refunded() ) : ?>
<tr>
<td class="label refunded-total"><?php _e( 'Refunded', 'woocommerce' ); ?>:</td>
<td class="label refunded-total"><?php esc_html_e( 'Refunded', 'woocommerce' ); ?>:</td>
<td width="1%"></td>
<td class="total refunded-total">-<?php echo wc_price( $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); ?></td>
</tr>
@ -196,63 +202,63 @@ if ( wc_tax_enabled() ) {
<div class="wc-order-data-row wc-order-bulk-actions wc-order-data-row-toggle">
<p class="add-items">
<?php if ( $order->is_editable() ) : ?>
<button type="button" class="button add-line-item"><?php _e( 'Add item(s)', 'woocommerce' ); ?></button>
<button type="button" class="button add-coupon"><?php _e( 'Apply coupon', 'woocommerce' ); ?></button>
<button type="button" class="button add-line-item"><?php esc_html_e( 'Add item(s)', 'woocommerce' ); ?></button>
<button type="button" class="button add-coupon"><?php esc_html_e( 'Apply coupon', 'woocommerce' ); ?></button>
<?php else : ?>
<span class="description"><?php echo wc_help_tip( __( 'To edit this order change the status back to "Pending"', 'woocommerce' ) ); ?> <?php _e( 'This order is no longer editable.', 'woocommerce' ); ?></span>
<span class="description"><?php echo wc_help_tip( __( 'To edit this order change the status back to "Pending"', 'woocommerce' ) ); ?> <?php esc_html_e( 'This order is no longer editable.', 'woocommerce' ); ?></span>
<?php endif; ?>
<?php if ( 0 < $order->get_total() - $order->get_total_refunded() || 0 < absint( $order->get_item_count() - $order->get_item_count_refunded() ) ) : ?>
<button type="button" class="button refund-items"><?php _e( 'Refund', 'woocommerce' ); ?></button>
<button type="button" class="button refund-items"><?php esc_html_e( 'Refund', 'woocommerce' ); ?></button>
<?php endif; ?>
<?php
// allow adding custom buttons
do_action( 'woocommerce_order_item_add_action_buttons', $order );
?>
<?php if ( $order->is_editable() ) : ?>
<button type="button" class="button button-primary calculate-action"><?php _e( 'Recalculate', 'woocommerce' ); ?></button>
<button type="button" class="button button-primary calculate-action"><?php esc_html_e( 'Recalculate', 'woocommerce' ); ?></button>
<?php endif; ?>
</p>
</div>
<div class="wc-order-data-row wc-order-add-item wc-order-data-row-toggle" style="display:none;">
<button type="button" class="button add-order-item"><?php _e( 'Add product(s)', 'woocommerce' ); ?></button>
<button type="button" class="button add-order-fee"><?php _e( 'Add fee', 'woocommerce' ); ?></button>
<button type="button" class="button add-order-shipping"><?php _e( 'Add shipping', 'woocommerce' ); ?></button>
<button type="button" class="button add-order-item"><?php esc_html_e( 'Add product(s)', 'woocommerce' ); ?></button>
<button type="button" class="button add-order-fee"><?php esc_html_e( 'Add fee', 'woocommerce' ); ?></button>
<button type="button" class="button add-order-shipping"><?php esc_html_e( 'Add shipping', 'woocommerce' ); ?></button>
<?php if ( wc_tax_enabled() ) : ?>
<button type="button" class="button add-order-tax"><?php _e( 'Add tax', 'woocommerce' ); ?></button>
<button type="button" class="button add-order-tax"><?php esc_html_e( 'Add tax', 'woocommerce' ); ?></button>
<?php endif; ?>
<?php
// allow adding custom buttons
do_action( 'woocommerce_order_item_add_line_buttons', $order );
?>
<button type="button" class="button cancel-action"><?php _e( 'Cancel', 'woocommerce' ); ?></button>
<button type="button" class="button button-primary save-action"><?php _e( 'Save', 'woocommerce' ); ?></button>
<button type="button" class="button cancel-action"><?php esc_html_e( 'Cancel', 'woocommerce' ); ?></button>
<button type="button" class="button button-primary save-action"><?php esc_html_e( 'Save', 'woocommerce' ); ?></button>
</div>
<?php if ( 0 < $order->get_total() - $order->get_total_refunded() || 0 < absint( $order->get_item_count() - $order->get_item_count_refunded() ) ) : ?>
<div class="wc-order-data-row wc-order-refund-items wc-order-data-row-toggle" style="display: none;">
<table class="wc-order-totals">
<?php if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) : ?>
<tr>
<td class="label"><label for="restock_refunded_items"><?php _e( 'Restock refunded items', 'woocommerce' ); ?>:</label></td>
<td class="label"><label for="restock_refunded_items"><?php esc_html_e( 'Restock refunded items', 'woocommerce' ); ?>:</label></td>
<td class="total"><input type="checkbox" id="restock_refunded_items" name="restock_refunded_items" checked="checked" /></td>
</tr>
<?php endif; ?>
<tr>
<td class="label"><?php _e( 'Amount already refunded', 'woocommerce' ); ?>:</td>
<td class="label"><?php esc_html_e( 'Amount already refunded', 'woocommerce' ); ?>:</td>
<td class="total">-<?php echo wc_price( $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); ?></td>
</tr>
<tr>
<td class="label"><?php _e( 'Total available to refund', 'woocommerce' ); ?>:</td>
<td class="label"><?php esc_html_e( 'Total available to refund', 'woocommerce' ); ?>:</td>
<td class="total"><?php echo wc_price( $order->get_total() - $order->get_total_refunded(), array( 'currency' => $order->get_currency() ) ); ?></td>
</tr>
<tr>
<td class="label"><label for="refund_amount"><?php _e( 'Refund amount', 'woocommerce' ); ?>:</label></td>
<td class="label"><label for="refund_amount"><?php esc_html_e( 'Refund amount', 'woocommerce' ); ?>:</label></td>
<td class="total">
<input type="text" id="refund_amount" name="refund_amount" class="wc_input_price" />
<div class="clear"></div>
</td>
</tr>
<tr>
<td class="label"><label for="refund_reason"><?php echo wc_help_tip( __( 'Note: the refund reason will be visible by the customer.', 'woocommerce' ) ); ?> <?php _e( 'Reason for refund (optional):', 'woocommerce' ); ?></label></td>
<td class="label"><label for="refund_reason"><?php echo wc_help_tip( __( 'Note: the refund reason will be visible by the customer.', 'woocommerce' ) ); ?> <?php esc_html_e( 'Reason for refund (optional):', 'woocommerce' ); ?></label></td>
<td class="total">
<input type="text" id="refund_reason" name="refund_reason" />
<div class="clear"></div>
@ -266,9 +272,11 @@ if ( wc_tax_enabled() ) {
$gateway_supports_refunds = false !== $payment_gateway && $payment_gateway->supports( 'refunds' );
$gateway_name = false !== $payment_gateway ? ( ! empty( $payment_gateway->method_title ) ? $payment_gateway->method_title : $payment_gateway->get_title() ) : __( 'Payment gateway', 'woocommerce' );
?>
<button type="button" class="button <?php echo $gateway_supports_refunds ? 'button-primary do-api-refund' : 'tips disabled'; ?>" <?php echo $gateway_supports_refunds ? '' : 'data-tip="' . esc_attr__( 'The payment gateway used to place this order does not support automatic refunds.', 'woocommerce' ) . '"'; ?>><?php printf( __( 'Refund %1$s via %2$s', 'woocommerce' ), $refund_amount, $gateway_name ); ?></button>
<button type="button" class="button button-primary do-manual-refund tips" data-tip="<?php esc_attr_e( 'You will need to manually issue a refund through your payment gateway after using this.', 'woocommerce' ); ?>"><?php printf( __( 'Refund %s manually', 'woocommerce' ), $refund_amount ); ?></button>
<button type="button" class="button cancel-action"><?php _e( 'Cancel', 'woocommerce' ); ?></button>
<?php /* translators: refund amount, gateway name */ ?>
<button type="button" class="button <?php echo $gateway_supports_refunds ? 'button-primary do-api-refund' : 'tips disabled'; ?>" <?php echo $gateway_supports_refunds ? '' : 'data-tip="' . esc_attr__( 'The payment gateway used to place this order does not support automatic refunds.', 'woocommerce' ) . '"'; ?>><?php printf( esc_html__( 'Refund %1$s via %2$s', 'woocommerce' ), $refund_amount, $gateway_name ); ?></button>
<?php /* translators: refund amount */ ?>
<button type="button" class="button button-primary do-manual-refund tips" data-tip="<?php esc_attr_e( 'You will need to manually issue a refund through your payment gateway after using this.', 'woocommerce' ); ?>"><?php printf( esc_html__( 'Refund %s manually', 'woocommerce' ), $refund_amount ); ?></button>
<button type="button" class="button cancel-action"><?php esc_html_e( 'Cancel', 'woocommerce' ); ?></button>
<input type="hidden" id="refunded_amount" name="refunded_amount" value="<?php echo esc_attr( $order->get_total_refunded() ); ?>" />
<div class="clear"></div>
</div>
@ -280,7 +288,7 @@ if ( wc_tax_enabled() ) {
<div class="wc-backbone-modal-content">
<section class="wc-backbone-modal-main" role="main">
<header class="wc-backbone-modal-header">
<h1><?php _e( 'Add products', 'woocommerce' ); ?></h1>
<h1><?php esc_html_e( 'Add products', 'woocommerce' ); ?></h1>
<button class="modal-close modal-close-link dashicons dashicons-no-alt">
<span class="screen-reader-text">Close modal panel</span>
</button>
@ -292,7 +300,7 @@ if ( wc_tax_enabled() ) {
</article>
<footer>
<div class="inner">
<button id="btn-ok" class="button button-primary button-large"><?php _e( 'Add', 'woocommerce' ); ?></button>
<button id="btn-ok" class="button button-primary button-large"><?php esc_html_e( 'Add', 'woocommerce' ); ?></button>
</div>
</footer>
</section>
@ -306,7 +314,7 @@ if ( wc_tax_enabled() ) {
<div class="wc-backbone-modal-content">
<section class="wc-backbone-modal-main" role="main">
<header class="wc-backbone-modal-header">
<h1><?php _e( 'Add tax', 'woocommerce' ); ?></h1>
<h1><?php esc_html_e( 'Add tax', 'woocommerce' ); ?></h1>
<button class="modal-close modal-close-link dashicons dashicons-no-alt">
<span class="screen-reader-text">Close modal panel</span>
</button>
@ -317,10 +325,10 @@ if ( wc_tax_enabled() ) {
<thead>
<tr>
<th>&nbsp;</th>
<th><?php _e( 'Rate name', 'woocommerce' ); ?></th>
<th><?php _e( 'Tax class', 'woocommerce' ); ?></th>
<th><?php _e( 'Rate code', 'woocommerce' ); ?></th>
<th><?php _e( 'Rate %', 'woocommerce' ); ?></th>
<th><?php esc_html_e( 'Rate name', 'woocommerce' ); ?></th>
<th><?php esc_html_e( 'Tax class', 'woocommerce' ); ?></th>
<th><?php esc_html_e( 'Rate code', 'woocommerce' ); ?></th>
<th><?php esc_html_e( 'Rate %', 'woocommerce' ); ?></th>
</tr>
</thead>
<?php
@ -341,7 +349,7 @@ if ( wc_tax_enabled() ) {
</table>
<?php if ( absint( $wpdb->get_var( "SELECT COUNT(tax_rate_id) FROM {$wpdb->prefix}woocommerce_tax_rates;" ) ) > 100 ) : ?>
<p>
<label for="manual_tax_rate_id"><?php _e( 'Or, enter tax rate ID:', 'woocommerce' ); ?></label><br/>
<label for="manual_tax_rate_id"><?php esc_html_e( 'Or, enter tax rate ID:', 'woocommerce' ); ?></label><br/>
<input type="number" name="manual_tax_rate_id" id="manual_tax_rate_id" step="1" placeholder="<?php esc_attr_e( 'Optional', 'woocommerce' ); ?>" />
</p>
<?php endif; ?>
@ -349,7 +357,7 @@ if ( wc_tax_enabled() ) {
</article>
<footer>
<div class="inner">
<button id="btn-ok" class="button button-primary button-large"><?php _e( 'Add', 'woocommerce' ); ?></button>
<button id="btn-ok" class="button button-primary button-large"><?php esc_html_e( 'Add', 'woocommerce' ); ?></button>
</div>
</footer>
</section>

View File

@ -8,7 +8,7 @@ if ( ! defined( 'ABSPATH' ) ) {
*/
$who_refunded = new WP_User( $refund->get_refunded_by() );
?>
<tr class="refund <?php echo ( ! empty( $class ) ) ? $class : ''; ?>" data-order_refund_id="<?php echo $refund->get_id(); ?>">
<tr class="refund <?php echo ( ! empty( $class ) ) ? esc_attr( $class ) : ''; ?>" data-order_refund_id="<?php echo esc_attr( $refund->get_id() ); ?>">
<td class="thumb"><div></div></td>
<td class="name">
@ -16,11 +16,12 @@ $who_refunded = new WP_User( $refund->get_refunded_by() );
if ( $who_refunded->exists() ) {
printf(
/* translators: 1: refund id 2: refund date 3: username */
__( 'Refund #%1$s - %2$s by %3$s', 'woocommerce' ),
esc_html__( 'Refund #%1$s - %2$s by %3$s', 'woocommerce' ),
$refund->get_id(),
wc_format_datetime( $refund->get_date_created(), get_option( 'date_format' ) . ', ' . get_option( 'time_format' ) ),
sprintf(
'<abbr class="refund_by" title="%1$s">%2$s</abbr>',
/* translators: 1: ID who refunded */
sprintf( esc_attr__( 'ID: %d', 'woocommerce' ), absint( $who_refunded->ID ) ),
esc_html( $who_refunded->display_name )
)
@ -28,7 +29,7 @@ $who_refunded = new WP_User( $refund->get_refunded_by() );
} else {
printf(
/* translators: 1: refund id 2: refund date */
__( 'Refund #%1$s - %2$s', 'woocommerce' ),
esc_html__( 'Refund #%1$s - %2$s', 'woocommerce' ),
$refund->get_id(),
wc_format_datetime( $refund->get_date_created(), get_option( 'date_format' ) . ', ' . get_option( 'time_format' ) )
);

View File

@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<tr class="shipping <?php echo ( ! empty( $class ) ) ? $class : ''; ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>">
<tr class="shipping <?php echo ( ! empty( $class ) ) ? esc_attr( $class ) : ''; ?>" data-order_item_id="<?php echo esc_attr( $item_id ); ?>">
<td class="thumb"><div></div></td>
<td class="name">
@ -21,7 +21,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<input type="text" class="shipping_method_name" placeholder="<?php esc_attr_e( 'Shipping name', 'woocommerce' ); ?>" name="shipping_method_title[<?php echo esc_attr( $item_id ); ?>]" value="<?php echo esc_attr( $item->get_name() ); ?>" />
<select class="shipping_method" name="shipping_method[<?php echo esc_attr( $item_id ); ?>]">
<optgroup label="<?php esc_attr_e( 'Shipping method', 'woocommerce' ); ?>">
<option value=""><?php _e( 'N/A', 'woocommerce' ); ?></option>
<option value=""><?php esc_html_e( 'N/A', 'woocommerce' ); ?></option>
<?php
$found_method = false;
@ -36,18 +36,18 @@ if ( ! defined( 'ABSPATH' ) ) {
}
if ( ! $found_method && $item->get_method_id() ) {
echo '<option value="' . esc_attr( $item->get_method_id() ) . '" selected="selected">' . __( 'Other', 'woocommerce' ) . '</option>';
echo '<option value="' . esc_attr( $item->get_method_id() ) . '" selected="selected">' . esc_html__( 'Other', 'woocommerce' ) . '</option>';
} else {
echo '<option value="other">' . __( 'Other', 'woocommerce' ) . '</option>';
echo '<option value="other">' . esc_html__( 'Other', 'woocommerce' ) . '</option>';
}
?>
</optgroup>
</select>
</div>
<?php do_action( 'woocommerce_before_order_itemmeta', $item_id, $item, null ) ?>
<?php do_action( 'woocommerce_before_order_itemmeta', $item_id, $item, null ); ?>
<?php include( 'html-order-item-meta.php' ); ?>
<?php do_action( 'woocommerce_after_order_itemmeta', $item_id, $item, null ) ?>
<?php do_action( 'woocommerce_after_order_itemmeta', $item_id, $item, null ); ?>
</td>
<?php do_action( 'woocommerce_admin_order_item_values', null, $item, absint( $item_id ) ); ?>
@ -59,17 +59,17 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="view">
<?php
echo wc_price( $item->get_total(), array( 'currency' => $order->get_currency() ) );
if ( $refunded = $order->get_total_refunded_for_item( $item_id, 'shipping' ) ) {
$refunded = $order->get_total_refunded_for_item( $item_id, 'shipping' );
if ( $refunded ) {
echo '<small class="refunded">-' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>';
}
?>
</div>
<div class="edit" style="display: none;">
<input type="text" name="shipping_cost[<?php echo esc_attr( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" />
<input type="text" name="shipping_cost[<?php echo esc_attr( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo esc_attr( wc_format_localized_price( $item->get_total() ) ); ?>" class="line_total wc_input_price" />
</div>
<div class="refund" style="display: none;">
<input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_total wc_input_price" />
<input type="text" name="refund_line_total[<?php echo absint( $item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_total wc_input_price" />
</div>
</td>
@ -83,17 +83,17 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="view">
<?php
echo ( '' !== $tax_item_total ) ? wc_price( wc_round_tax_total( $tax_item_total ), array( 'currency' => $order->get_currency() ) ) : '&ndash;';
if ( $refunded = $order->get_tax_refunded_for_item( $item_id, $tax_item_id, 'shipping' ) ) {
$refunded = $order->get_tax_refunded_for_item( $item_id, $tax_item_id, 'shipping' );
if ( $refunded ) {
echo '<small class="refunded">-' . wc_price( $refunded, array( 'currency' => $order->get_currency() ) ) . '</small>';
}
?>
</div>
<div class="edit" style="display: none;">
<input type="text" name="shipping_taxes[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" />
<input type="text" name="shipping_taxes[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" />
</div>
<div class="refund" style="display: none;">
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo esc_attr( wc_format_localized_price( 0 ) ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
</div>
</td>
<?php

View File

@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
<div data-taxonomy="<?php echo esc_attr( $attribute->get_taxonomy() ); ?>" class="woocommerce_attribute wc-metabox closed <?php echo esc_attr( implode( ' ', $metabox_class ) ); ?>" rel="<?php echo esc_attr( $attribute->get_position() ); ?>">
<h3>
<a href="#" class="remove_row delete"><?php _e( 'Remove', 'woocommerce' ); ?></a>
<a href="#" class="remove_row delete"><?php esc_html_e( 'Remove', 'woocommerce' ); ?></a>
<div class="handlediv" title="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div>
<strong class="attribute_name"><?php echo esc_html( wc_attribute_label( $attribute->get_name() ) ); ?></strong>
</h3>
@ -14,24 +14,26 @@ if ( ! defined( 'ABSPATH' ) ) {
<tbody>
<tr>
<td class="attribute_name">
<label><?php _e( 'Name', 'woocommerce' ); ?>:</label>
<label><?php esc_html_e( 'Name', 'woocommerce' ); ?>:</label>
<?php if ( $attribute->is_taxonomy() ) : ?>
<strong><?php echo esc_html( wc_attribute_label( $attribute->get_name() ) ); ?></strong>
<input type="hidden" name="attribute_names[<?php echo $i; ?>]" value="<?php echo esc_attr( $attribute->get_name() ); ?>" />
<input type="hidden" name="attribute_names[<?php echo esc_attr( $i ); ?>]" value="<?php echo esc_attr( $attribute->get_name() ); ?>" />
<?php else : ?>
<input type="text" class="attribute_name" name="attribute_names[<?php echo $i; ?>]" value="<?php echo esc_attr( $attribute->get_name() ); ?>" />
<input type="text" class="attribute_name" name="attribute_names[<?php echo esc_attr( $i ); ?>]" value="<?php echo esc_attr( $attribute->get_name() ); ?>" />
<?php endif; ?>
<input type="hidden" name="attribute_position[<?php echo $i; ?>]" class="attribute_position" value="<?php echo esc_attr( $attribute->get_position() ); ?>" />
<input type="hidden" name="attribute_position[<?php echo esc_attr( $i ); ?>]" class="attribute_position" value="<?php echo esc_attr( $attribute->get_position() ); ?>" />
</td>
<td rowspan="3">
<label><?php _e( 'Value(s)', 'woocommerce' ); ?>:</label>
<label><?php esc_html_e( 'Value(s)', 'woocommerce' ); ?>:</label>
<?php if ( $attribute->is_taxonomy() && ( $attribute_taxonomy = $attribute->get_taxonomy_object() ) ) : ?>
<?php
if ( $attribute->is_taxonomy() && $attribute_taxonomy = $attribute->get_taxonomy_object() ) :
?>
<?php if ( 'select' === $attribute_taxonomy->attribute_type ) : ?>
<select multiple="multiple" data-placeholder="<?php esc_attr_e( 'Select terms', 'woocommerce' ); ?>" class="multiselect attribute_values wc-enhanced-select" name="attribute_values[<?php echo $i; ?>][]">
<select multiple="multiple" data-placeholder="<?php esc_attr_e( 'Select terms', 'woocommerce' ); ?>" class="multiselect attribute_values wc-enhanced-select" name="attribute_values[<?php echo esc_attr( $i ); ?>][]">
<?php
$args = array(
'orderby' => 'name',
@ -42,18 +44,18 @@ if ( ! defined( 'ABSPATH' ) ) {
foreach ( $all_terms as $term ) {
$options = $attribute->get_options();
$options = ! empty( $options ) ? $options : array();
echo '<option value="' . esc_attr( $term->term_id ) . '" ' . selected( in_array( $term->term_id, $options ), true, false ) . '>' . esc_attr( apply_filters( 'woocommerce_product_attribute_term_name', $term->name, $term ) ) . '</option>';
echo '<option value="' . esc_attr( $term->term_id ) . '" ' . selected( in_array( $term->term_id, $options, true ), true, false ) . '>' . esc_attr( apply_filters( 'woocommerce_product_attribute_term_name', $term->name, $term ) ) . '</option>';
}
}
?>
</select>
<button class="button plus select_all_attributes"><?php _e( 'Select all', 'woocommerce' ); ?></button>
<button class="button minus select_no_attributes"><?php _e( 'Select none', 'woocommerce' ); ?></button>
<button class="button fr plus add_new_attribute"><?php _e( 'Add new', 'woocommerce' ); ?></button>
<button class="button plus select_all_attributes"><?php esc_html_e( 'Select all', 'woocommerce' ); ?></button>
<button class="button minus select_no_attributes"><?php esc_html_e( 'Select none', 'woocommerce' ); ?></button>
<button class="button fr plus add_new_attribute"><?php esc_html_e( 'Add new', 'woocommerce' ); ?></button>
<?php elseif ( 'text' == $attribute_taxonomy->attribute_type ) : ?>
<?php elseif ( 'text' === $attribute_taxonomy->attribute_type ) : ?>
<input type="text" name="attribute_values[<?php echo $i; ?>]" value="<?php
<input type="text" name="attribute_values[<?php echo esc_attr( $i ); ?>]" value="<?php
// Text attributes should list terms pipe separated
echo esc_attr( wc_implode_text_attributes( wp_list_pluck( $attribute->get_terms(), 'name' ) ) );
@ -70,21 +72,21 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php do_action( 'woocommerce_product_option_terms', $attribute_taxonomy, $i ); ?>
<?php else : ?>
<textarea name="attribute_values[<?php echo $i; ?>]" cols="5" rows="5" placeholder="<?php printf( esc_attr__( 'Enter some text, or some attributes by "%s" separating values.', 'woocommerce' ), WC_DELIMITER ); ?>"><?php echo esc_textarea( wc_implode_text_attributes( $attribute->get_options() ) ); ?></textarea>
<?php /* translators: %s: WC_DELIMITER */ ?>
<textarea name="attribute_values[<?php echo esc_attr( $i ); ?>]" cols="5" rows="5" placeholder="<?php printf( esc_attr__( 'Enter some text, or some attributes by "%s" separating values.', 'woocommerce' ), WC_DELIMITER ); ?>"><?php echo esc_textarea( wc_implode_text_attributes( $attribute->get_options() ) ); ?></textarea>
<?php endif; ?>
</td>
</tr>
<tr>
<td>
<label><input type="checkbox" class="checkbox" <?php checked( $attribute->get_visible(), true ); ?> name="attribute_visibility[<?php echo $i; ?>]" value="1" /> <?php _e( 'Visible on the product page', 'woocommerce' ); ?></label>
<label><input type="checkbox" class="checkbox" <?php checked( $attribute->get_visible(), true ); ?> name="attribute_visibility[<?php echo esc_attr( $i ); ?>]" value="1" /> <?php esc_html_e( 'Visible on the product page', 'woocommerce' ); ?></label>
</td>
</tr>
<tr>
<td>
<div class="enable_variation show_if_variable">
<label><input type="checkbox" class="checkbox" <?php checked( $attribute->get_variation(), true ); ?> name="attribute_variation[<?php echo $i; ?>]" value="1" /> <?php _e( 'Used for variations', 'woocommerce' ); ?></label>
<label><input type="checkbox" class="checkbox" <?php checked( $attribute->get_variation(), true ); ?> name="attribute_variation[<?php echo esc_attr( $i ); ?>]" value="1" /> <?php esc_html_e( 'Used for variations', 'woocommerce' ); ?></label>
</div>
</td>
</tr>

View File

@ -6,10 +6,10 @@ if ( ! defined( 'ABSPATH' ) ) {
<div id="product_attributes" class="panel wc-metaboxes-wrapper hidden">
<div class="toolbar toolbar-top">
<span class="expand-close">
<a href="#" class="expand_all"><?php _e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php _e( 'Close', 'woocommerce' ); ?></a>
<a href="#" class="expand_all"><?php esc_html_e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php esc_html_e( 'Close', 'woocommerce' ); ?></a>
</span>
<select name="attribute_taxonomy" class="attribute_taxonomy">
<option value=""><?php _e( 'Custom product attribute', 'woocommerce' ); ?></option>
<option value=""><?php esc_html_e( 'Custom product attribute', 'woocommerce' ); ?></option>
<?php
global $wc_product_attributes;
@ -25,7 +25,7 @@ if ( ! defined( 'ABSPATH' ) ) {
}
?>
</select>
<button type="button" class="button add_attribute"><?php _e( 'Add', 'woocommerce' ); ?></button>
<button type="button" class="button add_attribute"><?php esc_html_e( 'Add', 'woocommerce' ); ?></button>
</div>
<div class="product_attributes wc-metaboxes">
<?php
@ -48,9 +48,9 @@ if ( ! defined( 'ABSPATH' ) ) {
</div>
<div class="toolbar">
<span class="expand-close">
<a href="#" class="expand_all"><?php _e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php _e( 'Close', 'woocommerce' ); ?></a>
<a href="#" class="expand_all"><?php esc_html_e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php esc_html_e( 'Close', 'woocommerce' ); ?></a>
</span>
<button type="button" class="button save_attributes button-primary"><?php _e( 'Save attributes', 'woocommerce' ); ?></button>
<button type="button" class="button save_attributes button-primary"><?php esc_html_e( 'Save attributes', 'woocommerce' ); ?></button>
</div>
<?php do_action( 'woocommerce_product_options_attributes' ); ?>
</div>

View File

@ -46,10 +46,10 @@ if ( ! defined( 'ABSPATH' ) ) {
$sale_price_dates_to = $product_object->get_date_on_sale_to( 'edit' ) && ( $date = $product_object->get_date_on_sale_to( 'edit' )->getOffsetTimestamp() ) ? date_i18n( 'Y-m-d', $date ) : '';
echo '<p class="form-field sale_price_dates_fields">
<label for="_sale_price_dates_from">' . __( 'Sale price dates', 'woocommerce' ) . '</label>
<input type="text" class="short" name="_sale_price_dates_from" id="_sale_price_dates_from" value="' . esc_attr( $sale_price_dates_from ) . '" placeholder="' . _x( 'From&hellip;', 'placeholder', 'woocommerce' ) . ' YYYY-MM-DD" maxlength="10" pattern="' . 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" name="_sale_price_dates_to" id="_sale_price_dates_to" value="' . esc_attr( $sale_price_dates_to ) . '" placeholder="' . _x( 'To&hellip;', 'placeholder', 'woocommerce' ) . ' YYYY-MM-DD" maxlength="10" pattern="' . 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])' ) ) . '" />
<a href="#" class="description cancel_sale_schedule">' . __( 'Cancel', 'woocommerce' ) . '</a>' . wc_help_tip( __( 'The sale will end at the beginning of the set date.', 'woocommerce' ) ) . '
<label for="_sale_price_dates_from">' . esc_html__( 'Sale price dates', 'woocommerce' ) . '</label>
<input type="text" class="short" name="_sale_price_dates_from" id="_sale_price_dates_from" value="' . esc_attr( $sale_price_dates_from ) . '" placeholder="' . esc_html( _x( 'From&hellip;', 'placeholder', 'woocommerce' ) ) . ' YYYY-MM-DD" maxlength="10" pattern="' . 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" name="_sale_price_dates_to" id="_sale_price_dates_to" value="' . esc_attr( $sale_price_dates_to ) . '" placeholder="' . esc_html( _x( 'To&hellip;', 'placeholder', 'woocommerce' ) ) . ' YYYY-MM-DD" maxlength="10" pattern="' . 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])' ) ) . '" />
<a href="#" class="description cancel_sale_schedule">' . esc_html__( 'Cancel', 'woocommerce' ) . '</a>' . wc_help_tip( __( 'The sale will end at the beginning of the set date.', 'woocommerce' ) ) . '
</p>';
do_action( 'woocommerce_product_options_pricing' );
@ -58,19 +58,20 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="options_group show_if_downloadable hidden">
<div class="form-field downloadable_files">
<label><?php _e( 'Downloadable files', 'woocommerce' ); ?></label>
<label><?php esc_html_e( 'Downloadable files', 'woocommerce' ); ?></label>
<table class="widefat">
<thead>
<tr>
<th class="sort">&nbsp;</th>
<th><?php _e( 'Name', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the name of the download shown to the customer.', 'woocommerce' ) ); ?></th>
<th colspan="2"><?php _e( 'File URL', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the URL or absolute path to the file which customers will get access to. URLs entered here should already be encoded.', 'woocommerce' ) ); ?></th>
<th><?php esc_html_e( 'Name', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the name of the download shown to the customer.', 'woocommerce' ) ); ?></th>
<th colspan="2"><?php esc_html_e( 'File URL', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the URL or absolute path to the file which customers will get access to. URLs entered here should already be encoded.', 'woocommerce' ) ); ?></th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
<?php
if ( $downloadable_files = $product_object->get_downloads( 'edit' ) ) {
$downloadable_files = $product_object->get_downloads( 'edit' );
if ( $downloadable_files ) {
foreach ( $downloadable_files as $key => $file ) {
include( 'html-product-download.php' );
}
@ -89,7 +90,7 @@ if ( ! defined( 'ABSPATH' ) ) {
ob_start();
include( 'html-product-download.php' );
echo esc_attr( ob_get_clean() );
?>"><?php _e( 'Add File', 'woocommerce' ); ?></a>
?>"><?php esc_html_e( 'Add File', 'woocommerce' ); ?></a>
</th>
</tr>
</tfoot>

View File

@ -11,7 +11,7 @@ if ( ! defined( 'ABSPATH' ) ) {
woocommerce_wp_text_input( array(
'id' => '_sku',
'value' => $product_object->get_sku( 'edit' ),
'label' => '<abbr title="' . __( 'Stock Keeping Unit', 'woocommerce' ) . '">' . __( 'SKU', 'woocommerce' ) . '</abbr>',
'label' => '<abbr title="' . esc_attr__( 'Stock Keeping Unit', 'woocommerce' ) . '">' . esc_html__( 'SKU', 'woocommerce' ) . '</abbr>',
'desc_tip' => true,
'description' => __( 'SKU refers to a Stock-keeping unit, a unique identifier for each distinct product and service that can be purchased.', 'woocommerce' ),
) );
@ -65,7 +65,7 @@ if ( ! defined( 'ABSPATH' ) ) {
woocommerce_wp_select( array(
'id' => '_stock_status',
'value' => $product_object->get_stock_status( 'edit' ),
'wrapper_class' => 'hide_if_variable hide_if_external',
'wrapper_class' => 'stock_status_field hide_if_variable hide_if_external',
'label' => __( 'Stock status', 'woocommerce' ),
'options' => wc_get_product_stock_status_options(),
'desc_tip' => true,

View File

@ -7,7 +7,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="options_group show_if_grouped">
<p class="form-field">
<label for="grouped_products"><?php _e( 'Grouped products', 'woocommerce' ); ?></label>
<label for="grouped_products"><?php esc_html_e( 'Grouped products', 'woocommerce' ); ?></label>
<select class="wc-product-search" multiple="multiple" style="width: 50%;" id="grouped_products" name="grouped_products[]" data-sortable="true" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products" data-exclude="<?php echo intval( $post->ID ); ?>">
<?php
$product_ids = $product_object->get_children( 'edit' );
@ -25,7 +25,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="options_group">
<p class="form-field">
<label for="upsell_ids"><?php _e( 'Upsells', 'woocommerce' ); ?></label>
<label for="upsell_ids"><?php esc_html_e( 'Upsells', 'woocommerce' ); ?></label>
<select class="wc-product-search" multiple="multiple" style="width: 50%;" id="upsell_ids" name="upsell_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations" data-exclude="<?php echo intval( $post->ID ); ?>">
<?php
$product_ids = $product_object->get_upsell_ids( 'edit' );
@ -41,7 +41,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</p>
<p class="form-field hide_if_grouped hide_if_external">
<label for="crosssell_ids"><?php _e( 'Cross-sells', 'woocommerce' ); ?></label>
<label for="crosssell_ids"><?php esc_html_e( 'Cross-sells', 'woocommerce' ); ?></label>
<select class="wc-product-search" multiple="multiple" style="width: 50%;" id="crosssell_ids" name="crosssell_ids[]" data-placeholder="<?php esc_attr_e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations" data-exclude="<?php echo intval( $post->ID ); ?>">
<?php
$product_ids = $product_object->get_cross_sell_ids( 'edit' );

View File

@ -32,8 +32,8 @@ if ( ! defined( 'ABSPATH' ) ) {
<ul class="product_data_tabs wc-tabs">
<?php foreach ( self::get_product_data_tabs() as $key => $tab ) : ?>
<li class="<?php echo $key; ?>_options <?php echo $key; ?>_tab <?php echo esc_attr( isset( $tab['class'] ) ? implode( ' ' , (array) $tab['class'] ) : '' ); ?>">
<a href="#<?php echo $tab['target']; ?>"><span><?php echo esc_html( $tab['label'] ); ?></span></a>
<li class="<?php echo esc_attr( $key ); ?>_options <?php echo esc_attr( $key ); ?>_tab <?php echo esc_attr( isset( $tab['class'] ) ? implode( ' ' , (array) $tab['class'] ) : '' ); ?>">
<a href="#<?php echo esc_attr( $tab['target'] ); ?>"><span><?php echo esc_html( $tab['label'] ); ?></span></a>
</li>
<?php endforeach; ?>
<?php do_action( 'woocommerce_product_write_panel_tabs' ); ?>

View File

@ -21,6 +21,7 @@ if ( ! defined( 'ABSPATH' ) ) {
if ( wc_product_dimensions_enabled() ) {
?><p class="form-field dimensions_field">
<?php /* translators: WooCommerce dimension unit*/ ?>
<label for="product_length"><?php printf( __( 'Dimensions (%s)', 'woocommerce' ), get_option( 'woocommerce_dimension_unit' ) ); ?></label>
<span class="wrap">
<input id="product_length" placeholder="<?php esc_attr_e( 'Length', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="_length" value="<?php echo esc_attr( wc_format_localized_decimal( $product_object->get_length( 'edit' ) ) ); ?>" />
@ -47,7 +48,7 @@ if ( ! defined( 'ABSPATH' ) ) {
'class' => 'select short',
);
?><p class="form-field dimensions_field">
<label for="product_shipping_class"><?php _e( 'Shipping class', 'woocommerce' ); ?></label>
<label for="product_shipping_class"><?php esc_html_e( 'Shipping class', 'woocommerce' ); ?></label>
<?php wp_dropdown_categories( $args ); ?>
<?php echo wc_help_tip( __( 'Shipping classes are used by certain shipping methods to group similar products.', 'woocommerce' ) ); ?>
</p><?php

View File

@ -1,4 +1,10 @@
<?php
/**
* Product data variations
*
* @package WooCommerce\Admin\Metaboxes\Views
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
@ -9,33 +15,34 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( ! count( $variation_attributes ) ) : ?>
<div id="message" class="inline notice woocommerce-message">
<p><?php _e( 'Before you can add a variation you need to add some variation attributes on the <strong>Attributes</strong> tab.', 'woocommerce' ); ?></p>
<p><a class="button-primary" href="<?php echo esc_url( apply_filters( 'woocommerce_docs_url', 'https://docs.woocommerce.com/document/variable-product/', 'product-variations' ) ); ?>" target="_blank"><?php _e( 'Learn more', 'woocommerce' ); ?></a></p>
<p><?php echo wp_kses_post( __( 'Before you can add a variation you need to add some variation attributes on the <strong>Attributes</strong> tab.', 'woocommerce' ) ); ?></p>
<p><a class="button-primary" href="<?php echo esc_url( apply_filters( 'woocommerce_docs_url', 'https://docs.woocommerce.com/document/variable-product/', 'product-variations' ) ); ?>" target="_blank"><?php esc_html_e( 'Learn more', 'woocommerce' ); ?></a></p>
</div>
<?php else : ?>
<div class="toolbar toolbar-variations-defaults">
<div class="variations-defaults">
<strong><?php _e( 'Default Form Values', 'woocommerce' ); ?>: <?php echo wc_help_tip( __( 'These are the attributes that will be pre-selected on the frontend.', 'woocommerce' ) ); ?></strong>
<strong><?php esc_html_e( 'Default Form Values', 'woocommerce' ); ?>: <?php echo wc_help_tip( __( 'These are the attributes that will be pre-selected on the frontend.', 'woocommerce' ) ); ?></strong>
<?php
foreach ( $variation_attributes as $attribute ) {
$selected_value = isset( $default_attributes[ sanitize_title( $attribute->get_name() ) ] ) ? $default_attributes[ sanitize_title( $attribute->get_name() ) ] : '';
?>
<select name="default_attribute_<?php echo sanitize_title( $attribute->get_name() ); ?>" data-current="<?php echo esc_attr( $selected_value ); ?>">
<option value=""><?php printf( esc_html__( 'No default %s&hellip;', 'woocommerce' ), wc_attribute_label( $attribute->get_name() ) ); ?></option>
<?php if ( $attribute->is_taxonomy() ) : ?>
<?php foreach ( $attribute->get_terms() as $option ) : ?>
<option <?php selected( $selected_value, $option->slug ); ?> value="<?php echo esc_attr( $option->slug ); ?>"><?php echo esc_html( apply_filters( 'woocommerce_variation_option_name', $option->name ) ); ?></option>
<?php endforeach; ?>
<?php else : ?>
<?php foreach ( $attribute->get_options() as $option ) : ?>
<option <?php selected( $selected_value, $option ); ?> value="<?php echo esc_attr( $option ); ?>"><?php echo esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ); ?></option>
<?php endforeach; ?>
<?php endif; ?>
</select>
<?php
}
foreach ( $variation_attributes as $attribute ) {
$selected_value = isset( $default_attributes[ sanitize_title( $attribute->get_name() ) ] ) ? $default_attributes[ sanitize_title( $attribute->get_name() ) ] : '';
?>
<select name="default_attribute_<?php echo esc_attr( sanitize_title( $attribute->get_name() ) ); ?>" data-current="<?php echo esc_attr( $selected_value ); ?>">
<?php /* translators: WooCommerce attribute label */ ?>
<option value=""><?php esc_html( sprintf( __( 'No default %s&hellip;', 'woocommerce' ), wc_attribute_label( $attribute->get_name() ) ) ); ?></option>
<?php if ( $attribute->is_taxonomy() ) : ?>
<?php foreach ( $attribute->get_terms() as $option ) : ?>
<option <?php selected( $selected_value, $option->slug ); ?> value="<?php echo esc_attr( $option->slug ); ?>"><?php echo esc_html( apply_filters( 'woocommerce_variation_option_name', $option->name ) ); ?></option>
<?php endforeach; ?>
<?php else : ?>
<?php foreach ( $attribute->get_options() as $option ) : ?>
<option <?php selected( $selected_value, $option ); ?> value="<?php echo esc_attr( $option ); ?>"><?php echo esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ); ?></option>
<?php endforeach; ?>
<?php endif; ?>
</select>
<?php
}
?>
</div>
<div class="clear"></div>
@ -43,59 +50,61 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="toolbar toolbar-top">
<select id="field_to_edit" class="variation_actions">
<option data-global="true" value="add_variation"><?php _e( 'Add variation', 'woocommerce' ); ?></option>
<option data-global="true" value="link_all_variations"><?php _e( 'Create variations from all attributes', 'woocommerce' ); ?></option>
<option value="delete_all"><?php _e( 'Delete all variations', 'woocommerce' ); ?></option>
<option data-global="true" value="add_variation"><?php esc_html_e( 'Add variation', 'woocommerce' ); ?></option>
<option data-global="true" value="link_all_variations"><?php esc_html_e( 'Create variations from all attributes', 'woocommerce' ); ?></option>
<option value="delete_all"><?php esc_html_e( 'Delete all variations', 'woocommerce' ); ?></option>
<optgroup label="<?php esc_attr_e( 'Status', 'woocommerce' ); ?>">
<option value="toggle_enabled"><?php _e( 'Toggle &quot;Enabled&quot;', 'woocommerce' ); ?></option>
<option value="toggle_downloadable"><?php _e( 'Toggle &quot;Downloadable&quot;', 'woocommerce' ); ?></option>
<option value="toggle_virtual"><?php _e( 'Toggle &quot;Virtual&quot;', 'woocommerce' ); ?></option>
<option value="toggle_enabled"><?php esc_html_e( 'Toggle &quot;Enabled&quot;', 'woocommerce' ); ?></option>
<option value="toggle_downloadable"><?php esc_html_e( 'Toggle &quot;Downloadable&quot;', 'woocommerce' ); ?></option>
<option value="toggle_virtual"><?php esc_html_e( 'Toggle &quot;Virtual&quot;', 'woocommerce' ); ?></option>
</optgroup>
<optgroup label="<?php esc_attr_e( 'Pricing', 'woocommerce' ); ?>">
<option value="variable_regular_price"><?php _e( 'Set regular prices', 'woocommerce' ); ?></option>
<option value="variable_regular_price_increase"><?php _e( 'Increase regular prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
<option value="variable_regular_price_decrease"><?php _e( 'Decrease regular prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
<option value="variable_sale_price"><?php _e( 'Set sale prices', 'woocommerce' ); ?></option>
<option value="variable_sale_price_increase"><?php _e( 'Increase sale prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
<option value="variable_sale_price_decrease"><?php _e( 'Decrease sale prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
<option value="variable_sale_schedule"><?php _e( 'Set scheduled sale dates', 'woocommerce' ); ?></option>
<option value="variable_regular_price"><?php esc_html_e( 'Set regular prices', 'woocommerce' ); ?></option>
<option value="variable_regular_price_increase"><?php esc_html_e( 'Increase regular prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
<option value="variable_regular_price_decrease"><?php esc_html_e( 'Decrease regular prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
<option value="variable_sale_price"><?php esc_html_e( 'Set sale prices', 'woocommerce' ); ?></option>
<option value="variable_sale_price_increase"><?php esc_html_e( 'Increase sale prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
<option value="variable_sale_price_decrease"><?php esc_html_e( 'Decrease sale prices (fixed amount or percentage)', 'woocommerce' ); ?></option>
<option value="variable_sale_schedule"><?php esc_html_e( 'Set scheduled sale dates', 'woocommerce' ); ?></option>
</optgroup>
<optgroup label="<?php esc_attr_e( 'Inventory', 'woocommerce' ); ?>">
<option value="toggle_manage_stock"><?php _e( 'Toggle &quot;Manage stock&quot;', 'woocommerce' ); ?></option>
<option value="variable_stock"><?php _e( 'Stock', 'woocommerce' ); ?></option>
<option value="variable_stock_status_instock"><?php _e( 'Set Status - In stock', 'woocommerce' ); ?></option>
<option value="variable_stock_status_outofstock"><?php _e( 'Set Status - Out of stock', 'woocommerce' ); ?></option>
<option value="toggle_manage_stock"><?php esc_html_e( 'Toggle &quot;Manage stock&quot;', 'woocommerce' ); ?></option>
<option value="variable_stock"><?php esc_html_e( 'Stock', 'woocommerce' ); ?></option>
<option value="variable_stock_status_instock"><?php esc_html_e( 'Set Status - In stock', 'woocommerce' ); ?></option>
<option value="variable_stock_status_outofstock"><?php esc_html_e( 'Set Status - Out of stock', 'woocommerce' ); ?></option>
<option value="variable_stock_status_onbackorder"><?php esc_html_e( 'Set Status - On backorder', 'woocommerce' ); ?></option>
</optgroup>
<optgroup label="<?php esc_attr_e( 'Shipping', 'woocommerce' ); ?>">
<option value="variable_length"><?php _e( 'Length', 'woocommerce' ); ?></option>
<option value="variable_width"><?php _e( 'Width', 'woocommerce' ); ?></option>
<option value="variable_height"><?php _e( 'Height', 'woocommerce' ); ?></option>
<option value="variable_weight"><?php _e( 'Weight', 'woocommerce' ); ?></option>
<option value="variable_length"><?php esc_html_e( 'Length', 'woocommerce' ); ?></option>
<option value="variable_width"><?php esc_html_e( 'Width', 'woocommerce' ); ?></option>
<option value="variable_height"><?php esc_html_e( 'Height', 'woocommerce' ); ?></option>
<option value="variable_weight"><?php esc_html_e( 'Weight', 'woocommerce' ); ?></option>
</optgroup>
<optgroup label="<?php esc_attr_e( 'Downloadable products', 'woocommerce' ); ?>">
<option value="variable_download_limit"><?php _e( 'Download limit', 'woocommerce' ); ?></option>
<option value="variable_download_expiry"><?php _e( 'Download expiry', 'woocommerce' ); ?></option>
<option value="variable_download_limit"><?php esc_html_e( 'Download limit', 'woocommerce' ); ?></option>
<option value="variable_download_expiry"><?php esc_html_e( 'Download expiry', 'woocommerce' ); ?></option>
</optgroup>
<?php do_action( 'woocommerce_variable_product_bulk_edit_actions' ); ?>
</select>
<a class="button bulk_edit do_variation_action"><?php _e( 'Go', 'woocommerce' ); ?></a>
<a class="button bulk_edit do_variation_action"><?php esc_html_e( 'Go', 'woocommerce' ); ?></a>
<div class="variations-pagenav">
<span class="displaying-num"><?php printf( _n( '%s item', '%s items', $variations_count, 'woocommerce' ), $variations_count ); ?></span>
<?php /* translators: variations count */ ?>
<span class="displaying-num"><?php echo esc_html( sprintf( _n( '%s item', '%s items', $variations_count, 'woocommerce' ), $variations_count ) ); ?></span>
<span class="expand-close">
(<a href="#" class="expand_all"><?php _e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php _e( 'Close', 'woocommerce' ); ?></a>)
(<a href="#" class="expand_all"><?php esc_html_e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php esc_html_e( 'Close', 'woocommerce' ); ?></a>)
</span>
<span class="pagination-links">
<a class="first-page disabled" title="<?php esc_attr_e( 'Go to the first page', 'woocommerce' ); ?>" href="#">&laquo;</a>
<a class="prev-page disabled" title="<?php esc_attr_e( 'Go to the previous page', 'woocommerce' ); ?>" href="#">&lsaquo;</a>
<span class="paging-select">
<label for="current-page-selector-1" class="screen-reader-text"><?php _e( 'Select Page', 'woocommerce' ); ?></label>
<label for="current-page-selector-1" class="screen-reader-text"><?php esc_html_e( 'Select Page', 'woocommerce' ); ?></label>
<select class="page-selector" id="current-page-selector-1" title="<?php esc_attr_e( 'Current page', 'woocommerce' ); ?>">
<?php for ( $i = 1; $i <= $variations_total_pages; $i++ ) : ?>
<option value="<?php echo $i; ?>"><?php echo $i; ?></option>
<option value="<?php echo $i; // WPCS: XSS ok. ?>"><?php echo $i; // WPCS: XSS ok. ?></option>
<?php endfor; ?>
</select>
<?php _ex( 'of', 'number of pages', 'woocommerce' ); ?> <span class="total-pages"><?php echo $variations_total_pages; ?></span>
<?php echo esc_html_x( 'of', 'number of pages', 'woocommerce' ); ?> <span class="total-pages"><?php echo esc_html( $variations_total_pages ); ?></span>
</span>
<a class="next-page" title="<?php esc_attr_e( 'Go to the next page', 'woocommerce' ); ?>" href="#">&rsaquo;</a>
<a class="last-page" title="<?php esc_attr_e( 'Go to the last page', 'woocommerce' ); ?>" href="#">&raquo;</a>
@ -104,32 +113,35 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="clear"></div>
</div>
<div class="woocommerce_variations wc-metaboxes" data-attributes="<?php
// esc_attr does not double encode - htmlspecialchars does
echo htmlspecialchars( json_encode( wc_list_pluck( $variation_attributes, 'get_data' ) ) );
?>" data-total="<?php echo $variations_count; ?>" data-total_pages="<?php echo $variations_total_pages; ?>" data-page="1" data-edited="false">
<?php
// esc_attr does not double encode - htmlspecialchars does.
$attributes_data = htmlspecialchars( wp_json_encode( wc_list_pluck( $variation_attributes, 'get_data' ) ) );
?>
<div class="woocommerce_variations wc-metaboxes" data-attributes="<?php echo $attributes_data; // WPCS: XSS ok. ?>" data-total="<?php echo esc_attr( $variations_count ); ?>" data-total_pages="<?php echo esc_attr( $variations_total_pages ); ?>" data-page="1" data-edited="false">
</div>
<div class="toolbar">
<button type="button" class="button-primary save-variation-changes" disabled="disabled"><?php _e( 'Save changes', 'woocommerce' ); ?></button>
<button type="button" class="button cancel-variation-changes" disabled="disabled"><?php _e( 'Cancel', 'woocommerce' ); ?></button>
<button type="button" class="button-primary save-variation-changes" disabled="disabled"><?php esc_html_e( 'Save changes', 'woocommerce' ); ?></button>
<button type="button" class="button cancel-variation-changes" disabled="disabled"><?php esc_html_e( 'Cancel', 'woocommerce' ); ?></button>
<div class="variations-pagenav">
<span class="displaying-num"><?php printf( _n( '%s item', '%s items', $variations_count, 'woocommerce' ), $variations_count ); ?></span>
<?php /* translators: variations count*/ ?>
<span class="displaying-num"><?php echo esc_html( sprintf( _n( '%s item', '%s items', $variations_count, 'woocommerce' ), $variations_count ) ); ?></span>
<span class="expand-close">
(<a href="#" class="expand_all"><?php _e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php _e( 'Close', 'woocommerce' ); ?></a>)
(<a href="#" class="expand_all"><?php esc_html_e( 'Expand', 'woocommerce' ); ?></a> / <a href="#" class="close_all"><?php esc_html_e( 'Close', 'woocommerce' ); ?></a>)
</span>
<span class="pagination-links">
<a class="first-page disabled" title="<?php esc_attr_e( 'Go to the first page', 'woocommerce' ); ?>" href="#">&laquo;</a>
<a class="prev-page disabled" title="<?php esc_attr_e( 'Go to the previous page', 'woocommerce' ); ?>" href="#">&lsaquo;</a>
<span class="paging-select">
<label for="current-page-selector-1" class="screen-reader-text"><?php _e( 'Select Page', 'woocommerce' ); ?></label>
<label for="current-page-selector-1" class="screen-reader-text"><?php esc_html_e( 'Select Page', 'woocommerce' ); ?></label>
<select class="page-selector" id="current-page-selector-1" title="<?php esc_attr_e( 'Current page', 'woocommerce' ); ?>">
<?php for ( $i = 1; $i <= $variations_total_pages; $i++ ) : ?>
<option value="<?php echo $i; ?>"><?php echo $i; ?></option>
<option value="<?php echo $i; // WPCS: XSS ok. ?>"><?php echo $i; // WPCS: XSS ok. ?></option>
<?php endfor; ?>
</select>
<?php _ex( 'of', 'number of pages', 'woocommerce' ); ?> <span class="total-pages"><?php echo $variations_total_pages; ?></span>
<?php echo esc_html_x( 'of', 'number of pages', 'woocommerce' ); ?> <span class="total-pages"><?php echo esc_html( $variations_total_pages ); ?></span>
</span>
<a class="next-page" title="<?php esc_attr_e( 'Go to the next page', 'woocommerce' ); ?>" href="#">&rsaquo;</a>
<a class="last-page" title="<?php esc_attr_e( 'Go to the last page', 'woocommerce' ); ?>" href="#">&raquo;</a>

View File

@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<input type="text" class="input_text" placeholder="<?php esc_attr_e( 'File name', 'woocommerce' ); ?>" name="_wc_file_names[]" value="<?php echo esc_attr( $file['name'] ); ?>" />
<input type="hidden" name="_wc_file_hashes[]" value="<?php echo esc_attr( $key ); ?>" />
</td>
<td class="file_url"><input type="text" class="input_text" placeholder="<?php esc_attr_e( "http://", 'woocommerce' ); ?>" name="_wc_file_urls[]" value="<?php echo esc_attr( $file['file'] ); ?>" /></td>
<td class="file_url_choose" width="1%"><a href="#" class="button upload_file_button" data-choose="<?php esc_attr_e( 'Choose file', 'woocommerce' ); ?>" data-update="<?php esc_attr_e( 'Insert file URL', 'woocommerce' ); ?>"><?php echo str_replace( ' ', '&nbsp;', __( 'Choose file', 'woocommerce' ) ); ?></a></td>
<td width="1%"><a href="#" class="delete"><?php _e( 'Delete', 'woocommerce' ); ?></a></td>
<td class="file_url"><input type="text" class="input_text" placeholder="<?php esc_attr_e( 'http://', 'woocommerce' ); ?>" name="_wc_file_urls[]" value="<?php echo esc_attr( $file['file'] ); ?>" /></td>
<td class="file_url_choose" width="1%"><a href="#" class="button upload_file_button" data-choose="<?php esc_attr_e( 'Choose file', 'woocommerce' ); ?>" data-update="<?php esc_attr_e( 'Insert file URL', 'woocommerce' ); ?>"><?php echo esc_html__( 'Choose file', 'woocommerce' ); ?></a></td>
<td width="1%"><a href="#" class="delete"><?php esc_html_e( 'Delete', 'woocommerce' ); ?></a></td>
</tr>

View File

@ -5,10 +5,10 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
<tr>
<td class="file_name">
<input type="text" class="input_text" placeholder="<?php esc_attr_e( 'File name', 'woocommerce' ); ?>" name="_wc_variation_file_names[<?php echo $variation_id; ?>][]" value="<?php echo esc_attr( $file['name'] ); ?>" />
<input type="hidden" name="_wc_variation_file_hashes[<?php echo $variation_id; ?>][]" value="<?php echo esc_attr( $key ); ?>" />
<input type="text" class="input_text" placeholder="<?php esc_attr_e( 'File name', 'woocommerce' ); ?>" name="_wc_variation_file_names[<?php echo esc_attr( $variation_id ); ?>][]" value="<?php echo esc_attr( $file['name'] ); ?>" />
<input type="hidden" name="_wc_variation_file_hashes[<?php echo esc_attr( $variation_id ); ?>][]" value="<?php echo esc_attr( $key ); ?>" />
</td>
<td class="file_url"><input type="text" class="input_text" placeholder="<?php esc_attr_e( "http://", 'woocommerce' ); ?>" name="_wc_variation_file_urls[<?php echo $variation_id; ?>][]" value="<?php echo esc_attr( $file['file'] ); ?>" /></td>
<td class="file_url_choose" width="1%"><a href="#" class="button upload_file_button" data-choose="<?php esc_attr_e( 'Choose file', 'woocommerce' ); ?>" data-update="<?php esc_attr_e( 'Insert file URL', 'woocommerce' ); ?>"><?php echo str_replace( ' ', '&nbsp;', __( 'Choose file', 'woocommerce' ) ); ?></a></td>
<td width="1%"><a href="#" class="delete"><?php _e( 'Delete', 'woocommerce' ); ?></a></td>
<td class="file_url"><input type="text" class="input_text" placeholder="<?php esc_attr_e( 'http://', 'woocommerce' ); ?>" name="_wc_variation_file_urls[<?php echo esc_attr( $variation_id ); ?>][]" value="<?php echo esc_attr( $file['file'] ); ?>" /></td>
<td class="file_url_choose" width="1%"><a href="#" class="button upload_file_button" data-choose="<?php esc_attr_e( 'Choose file', 'woocommerce' ); ?>" data-update="<?php esc_attr_e( 'Insert file URL', 'woocommerce' ); ?>"><?php esc_html_e( 'Choose file', 'woocommerce' ); ?></a></td>
<td width="1%"><a href="#" class="delete"><?php esc_html_e( 'Delete', 'woocommerce' ); ?></a></td>
</tr>

View File

@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
<div class="woocommerce_variation wc-metabox closed">
<h3>
<a href="#" class="remove_variation delete" rel="<?php echo esc_attr( $variation_id ); ?>"><?php _e( 'Remove', 'woocommerce' ); ?></a>
<a href="#" class="remove_variation delete" rel="<?php echo esc_attr( $variation_id ); ?>"><?php esc_html_e( 'Remove', 'woocommerce' ); ?></a>
<div class="handlediv" aria-label="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div>
<div class="tips sort" data-tip="<?php esc_attr_e( 'Drag and drop, or click to set admin variation order', 'woocommerce' ); ?>"></div>
<strong>#<?php echo esc_html( $variation_id ); ?> </strong>
@ -44,14 +44,14 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php
}
?>
<input type="hidden" name="variable_post_id[<?php echo $loop; ?>]" value="<?php echo esc_attr( $variation_id ); ?>" />
<input type="hidden" class="variation_menu_order" name="variation_menu_order[<?php echo $loop; ?>]" value="<?php echo esc_attr( $variation_object->get_menu_order( 'edit' ) ); ?>" />
<input type="hidden" name="variable_post_id[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( $variation_id ); ?>" />
<input type="hidden" class="variation_menu_order" name="variation_menu_order[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( $variation_object->get_menu_order( 'edit' ) ); ?>" />
</h3>
<div class="woocommerce_variable_attributes wc-metabox-content" style="display: none;">
<div class="data">
<p class="form-row form-row-first upload_image">
<a href="#" class="upload_image_button tips <?php echo $variation_object->get_image_id( 'edit' ) ? 'remove' : ''; ?>" data-tip="<?php echo $variation_object->get_image_id( 'edit' ) ? esc_attr__( 'Remove this image', 'woocommerce' ) : esc_attr__( 'Upload an image', 'woocommerce' ); ?>" rel="<?php echo esc_attr( $variation_id ); ?>">
<img src="<?php echo $variation_object->get_image_id( 'edit' ) ? esc_url( wp_get_attachment_thumb_url( $variation_object->get_image_id( 'edit' ) ) ) : esc_url( wc_placeholder_img_src() ); ?>" /><input type="hidden" name="upload_image_id[<?php echo $loop; ?>]" class="upload_image_id" value="<?php echo esc_attr( $variation_object->get_image_id( 'edit' ) ); ?>" />
<img src="<?php echo $variation_object->get_image_id( 'edit' ) ? esc_url( wp_get_attachment_thumb_url( $variation_object->get_image_id( 'edit' ) ) ) : esc_url( wc_placeholder_img_src() ); ?>" /><input type="hidden" name="upload_image_id[<?php echo esc_attr( $loop ); ?>]" class="upload_image_id" value="<?php echo esc_attr( $variation_object->get_image_id( 'edit' ) ); ?>" />
</a>
</p>
<?php
@ -70,22 +70,22 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
<p class="form-row form-row-full options">
<label>
<?php _e( 'Enabled', 'woocommerce' ); ?>:
<input type="checkbox" class="checkbox" name="variable_enabled[<?php echo $loop; ?>]" <?php checked( in_array( $variation_object->get_status( 'edit' ), array( 'publish', false ) ), true ); ?> />
<?php esc_html_e( 'Enabled', 'woocommerce' ); ?>:
<input type="checkbox" class="checkbox" name="variable_enabled[<?php echo $loop; ?>]" <?php checked( in_array( $variation_object->get_status( 'edit' ), array( 'publish', false ), true ), true ); ?> />
</label>
<label class="tips" data-tip="<?php _e( 'Enable this option if access is given to a downloadable file upon purchase of a product', 'woocommerce' ); ?>">
<?php _e( 'Downloadable', 'woocommerce' ); ?>:
<input type="checkbox" class="checkbox variable_is_downloadable" name="variable_is_downloadable[<?php echo $loop; ?>]" <?php checked( $variation_object->get_downloadable( 'edit' ), true ); ?> />
<label class="tips" data-tip="<?php esc_html_e( 'Enable this option if access is given to a downloadable file upon purchase of a product', 'woocommerce' ); ?>">
<?php esc_html_e( 'Downloadable', 'woocommerce' ); ?>:
<input type="checkbox" class="checkbox variable_is_downloadable" name="variable_is_downloadable[<?php echo esc_attr( $loop ); ?>]" <?php checked( $variation_object->get_downloadable( 'edit' ), true ); ?> />
</label>
<label class="tips" data-tip="<?php _e( 'Enable this option if a product is not shipped or there is no shipping cost', 'woocommerce' ); ?>">
<?php _e( 'Virtual', 'woocommerce' ); ?>:
<input type="checkbox" class="checkbox variable_is_virtual" name="variable_is_virtual[<?php echo $loop; ?>]" <?php checked( $variation_object->get_virtual( 'edit' ), true ); ?> />
<label class="tips" data-tip="<?php esc_html_e( 'Enable this option if a product is not shipped or there is no shipping cost', 'woocommerce' ); ?>">
<?php esc_html_e( 'Virtual', 'woocommerce' ); ?>:
<input type="checkbox" class="checkbox variable_is_virtual" name="variable_is_virtual[<?php echo esc_attr( $loop ); ?>]" <?php checked( $variation_object->get_virtual( 'edit' ), true ); ?> />
</label>
<?php if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) : ?>
<label class="tips" data-tip="<?php _e( 'Enable this option to enable stock management at variation level', 'woocommerce' ); ?>">
<?php _e( 'Manage stock?', 'woocommerce' ); ?>
<input type="checkbox" class="checkbox variable_manage_stock" name="variable_manage_stock[<?php echo $loop; ?>]" <?php checked( $variation_object->get_manage_stock( 'edit' ), true ); ?> />
<label class="tips" data-tip="<?php esc_html_e( 'Enable this option to enable stock management at variation level', 'woocommerce' ); ?>">
<?php esc_html_e( 'Manage stock?', 'woocommerce' ); ?>
<input type="checkbox" class="checkbox variable_manage_stock" name="variable_manage_stock[<?php echo esc_attr( $loop ); ?>]" <?php checked( $variation_object->get_manage_stock( 'edit' ), true ); ?> />
</label>
<?php endif; ?>
@ -94,8 +94,8 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="variable_pricing">
<?php
/* translators: %s: currency symbol */
$label = sprintf(
/* translators: %s: currency symbol */
__( 'Regular price (%s)', 'woocommerce' ),
get_woocommerce_currency_symbol()
);
@ -109,9 +109,9 @@ if ( ! defined( 'ABSPATH' ) ) {
'wrapper_class' => 'form-row form-row-first',
'placeholder' => __( 'Variation price (required)', 'woocommerce' ),
) );
/* translators: %s: currency symbol */
$label = sprintf(
/* translators: %s: currency symbol */
__( 'Sale price (%s)', 'woocommerce' ),
get_woocommerce_currency_symbol()
);
@ -121,7 +121,7 @@ if ( ! defined( 'ABSPATH' ) ) {
'name' => "variable_sale_price[{$loop}]",
'value' => wc_format_localized_price( $variation_object->get_sale_price( 'edit' ) ),
'data_type' => 'price',
'label' => $label . ' <a href="#" class="sale_schedule">' . __( 'Schedule', 'woocommerce' ) . '</a><a href="#" class="cancel_sale_schedule hidden">' . __( 'Cancel schedule', 'woocommerce' ) . '</a>',
'label' => $label . ' <a href="#" class="sale_schedule">' . esc_html__( 'Schedule', 'woocommerce' ) . '</a><a href="#" class="cancel_sale_schedule hidden">' . esc_html__( 'Cancel schedule', 'woocommerce' ) . '</a>',
'wrapper_class' => 'form-row form-row-last',
) );
@ -135,7 +135,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</p>
<p class="form-row form-row-last">
<label>' . __( 'Sale end date', 'woocommerce' ) . '</label>
<input type="text" class="sale_price_dates_to" name="variable_sale_price_dates_to[' . $loop . ']" value="' . esc_attr( $sale_price_dates_to ) . '" placeholder="' . _x( 'To&hellip;', 'placeholder', 'woocommerce' ) . ' YYYY-MM-DD" maxlength="10" pattern="' . 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="sale_price_dates_to" name="variable_sale_price_dates_to[' . esc_attr( $loop ) . ']" value="' . esc_attr( $sale_price_dates_to ) . '" placeholder="' . esc_html_x( 'To&hellip;', 'placeholder', 'woocommerce' ) . ' YYYY-MM-DD" maxlength="10" pattern="' . 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])' ) ) . '" />
</p>
</div>';
@ -170,7 +170,7 @@ if ( ! defined( 'ABSPATH' ) ) {
'wrapper_class' => 'form-row form-row-first',
) );
echo '<input type="hidden" name="variable_original_stock[' . $loop . ']" value="' . esc_attr( wc_stock_amount( $variation_object->get_stock_quantity( 'edit' ) ) ) . '" />';
echo '<input type="hidden" name="variable_original_stock[' . esc_attr( $loop ) . ']" value="' . esc_attr( wc_stock_amount( $variation_object->get_stock_quantity( 'edit' ) ) ) . '" />';
woocommerce_wp_select( array(
'id' => "variable_backorders{$loop}",
@ -211,8 +211,8 @@ if ( ! defined( 'ABSPATH' ) ) {
) );
if ( wc_product_weight_enabled() ) {
/* translators: %s: weight unit */
$label = sprintf(
/* translators: %s: weight unit */
__( 'Weight (%s)', 'woocommerce' ),
esc_html( get_option( 'woocommerce_weight_unit' ) )
);
@ -238,17 +238,17 @@ if ( ! defined( 'ABSPATH' ) ) {
?><p class="form-field form-row dimensions_field hide_if_variation_virtual form-row-last">
<label for="product_length"><?php
/* translators: %s: dimension unit */
printf(
__( 'Dimensions (L&times;W&times;H) (%s)', 'woocommerce' ),
/* translators: %s: dimension unit */
esc_html__( 'Dimensions (L&times;W&times;H) (%s)', 'woocommerce' ),
get_option( 'woocommerce_dimension_unit' )
);
?></label>
<?php echo wc_help_tip( __( 'Length x width x height in decimal form', 'woocommerce' ) ); ?>
<span class="wrap">
<input id="product_length" placeholder="<?php echo $parent_length ? esc_attr( $parent_length ) : esc_attr__( 'Length', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="variable_length[<?php echo $loop; ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_length( 'edit' ) ) ); ?>" />
<input placeholder="<?php echo $parent_width ? esc_attr( $parent_width ) : esc_attr__( 'Width', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="variable_width[<?php echo $loop; ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_width( 'edit' ) ) ); ?>" />
<input placeholder="<?php echo $parent_height ? esc_attr( $parent_height ) : esc_attr__( 'Height', 'woocommerce' ); ?>" class="input-text wc_input_decimal last" size="6" type="text" name="variable_height[<?php echo $loop; ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_height( 'edit' ) ) ); ?>" />
<input id="product_length" placeholder="<?php echo $parent_length ? esc_attr( $parent_length ) : esc_attr__( 'Length', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="variable_length[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_length( 'edit' ) ) ); ?>" />
<input placeholder="<?php echo $parent_width ? esc_attr( $parent_width ) : esc_attr__( 'Width', 'woocommerce' ); ?>" class="input-text wc_input_decimal" size="6" type="text" name="variable_width[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_width( 'edit' ) ) ); ?>" />
<input placeholder="<?php echo $parent_height ? esc_attr( $parent_height ) : esc_attr__( 'Height', 'woocommerce' ); ?>" class="input-text wc_input_decimal last" size="6" type="text" name="variable_height[<?php echo esc_attr( $loop ); ?>]" value="<?php echo esc_attr( wc_format_localized_decimal( $variation_object->get_height( 'edit' ) ) ); ?>" />
</span>
</p><?php
}
@ -267,7 +267,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</div>
<div>
<p class="form-row hide_if_variation_virtual form-row-full"><label><?php _e( 'Shipping class', 'woocommerce' ); ?></label> <?php
<p class="form-row hide_if_variation_virtual form-row-full"><label><?php esc_html_e( 'Shipping class', 'woocommerce' ); ?></label> <?php
wp_dropdown_categories( array(
'taxonomy' => 'product_shipping_class',
'hide_empty' => 0,
@ -319,12 +319,12 @@ if ( ! defined( 'ABSPATH' ) ) {
</div>
<div class="show_if_variation_downloadable" style="display: none;">
<div class="form-row form-row-full downloadable_files">
<label><?php _e( 'Downloadable files', 'woocommerce' ); ?></label>
<label><?php esc_html_e( 'Downloadable files', 'woocommerce' ); ?></label>
<table class="widefat">
<thead>
<div>
<th><?php _e( 'Name', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the name of the download shown to the customer.', 'woocommerce' ) ); ?></th>
<th colspan="2"><?php _e( 'File URL', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the URL or absolute path to the file which customers will get access to. URLs entered here should already be encoded.', 'woocommerce' ) ); ?></th>
<th><?php esc_html_e( 'Name', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the name of the download shown to the customer.', 'woocommerce' ) ); ?></th>
<th colspan="2"><?php esc_html_e( 'File URL', 'woocommerce' ); ?> <?php echo wc_help_tip( __( 'This is the URL or absolute path to the file which customers will get access to. URLs entered here should already be encoded.', 'woocommerce' ) ); ?></th>
<th>&nbsp;</th>
</div>
</thead>
@ -349,7 +349,7 @@ if ( ! defined( 'ABSPATH' ) ) {
ob_start();
include( 'html-product-variation-download.php' );
echo esc_attr( ob_get_clean() );
?>"><?php _e( 'Add file', 'woocommerce' ); ?></a>
?>"><?php esc_html_e( 'Add file', 'woocommerce' ); ?></a>
</th>
</div>
</tfoot>

View File

@ -658,8 +658,12 @@ class WC_Admin_Report {
return;
}
if ( ! isset( $_GET['wc_reports_nonce'] ) || ! wp_verify_nonce( $_GET['wc_reports_nonce'], 'custom_range' ) ) {
wp_safe_redirect( remove_query_arg( array( 'start_date', 'end_date', 'range', 'wc_reports_nonce' ) ) );
if ( ! isset( $_GET['wc_reports_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_GET['wc_reports_nonce'] ), 'custom_range' ) ) { // WPCS: input var ok, CSRF ok.
wp_die(
/* translators: %1$s: open link, %2$s: close link */
sprintf( esc_html__( 'This report link has expired. %1$sClick here to view the filtered report%2$s.', 'woocommerce' ), '<a href="' . esc_url( wp_nonce_url( esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'custom_range', 'wc_reports_nonce' ) ) . '">', '</a>' ), // @codingStandardsIgnoreLine.
esc_attr__( 'Confirm navigation', 'woocommerce' )
);
exit;
}
}

View File

@ -138,7 +138,7 @@ class WC_Report_Customer_List extends WP_List_Table {
break;
case 'user_actions' :
case 'wc_actions' :
ob_start();
?><p>
<?php
@ -210,7 +210,7 @@ class WC_Report_Customer_List extends WP_List_Table {
'orders' => __( 'Orders', 'woocommerce' ),
'spent' => __( 'Money spent', 'woocommerce' ),
'last_order' => __( 'Last order', 'woocommerce' ),
'user_actions' => __( 'Actions', 'woocommerce' ),
'wc_actions' => __( 'Actions', 'woocommerce' ),
);
return $columns;

View File

@ -108,7 +108,9 @@ class WC_Report_Stock extends WP_List_Table {
break;
case 'stock_status' :
if ( $product->is_in_stock() ) {
if ( $product->is_on_backorder() ) {
$stock_html = '<mark class="onbackorder">' . __( 'On backorder', 'woocommerce' ) . '</mark>';
} elseif ( $product->is_in_stock() ) {
$stock_html = '<mark class="instock">' . __( 'In stock', 'woocommerce' ) . '</mark>';
} else {
$stock_html = '<mark class="outofstock">' . __( 'Out of stock', 'woocommerce' ) . '</mark>';

View File

@ -12,14 +12,14 @@ if ( ! defined( 'ABSPATH' ) ) {
<fieldset class="inline-edit-col-left">
<div id="woocommerce-fields" class="inline-edit-col">
<h4><?php _e( 'Product data', 'woocommerce' ); ?></h4>
<h4><?php esc_html_e( 'Product data', 'woocommerce' ); ?></h4>
<?php do_action( 'woocommerce_product_quick_edit_start' ); ?>
<?php if ( wc_product_sku_enabled() ) : ?>
<label>
<span class="title"><?php _e( 'SKU', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'SKU', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<input type="text" name="_sku" class="text sku" value="">
</span>
@ -30,14 +30,14 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="price_fields">
<label>
<span class="title"><?php _e( 'Price', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'Price', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<input type="text" name="_regular_price" class="text wc_input_price regular_price" placeholder="<?php esc_attr_e( 'Regular price', 'woocommerce' ); ?>" value="">
</span>
</label>
<br class="clear" />
<label>
<span class="title"><?php _e( 'Sale', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'Sale', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<input type="text" name="_sale_price" class="text wc_input_price sale_price" placeholder="<?php esc_attr_e( 'Sale price', 'woocommerce' ); ?>" value="">
</span>
@ -47,7 +47,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( wc_tax_enabled() ) : ?>
<label class="alignleft">
<span class="title"><?php _e( 'Tax status', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'Tax status', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="tax_status" name="_tax_status">
<?php
@ -57,7 +57,7 @@ if ( ! defined( 'ABSPATH' ) ) {
'none' => _x( 'None', 'Tax status', 'woocommerce' ),
);
foreach ( $options as $key => $value ) {
echo '<option value="' . esc_attr( $key ) . '">' . $value . '</option>';
echo '<option value="' . esc_attr( $key ) . '">' . esc_html( $value ) . '</option>';
}
?>
</select>
@ -65,7 +65,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</label>
<br class="clear" />
<label class="alignleft">
<span class="title"><?php _e( 'Tax class', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'Tax class', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="tax_class" name="_tax_class">
<?php
@ -96,7 +96,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( wc_product_weight_enabled() ) : ?>
<label>
<span class="title"><?php _e( 'Weight', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'Weight', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<input type="text" name="_weight" class="text weight" placeholder="<?php echo wc_format_localized_decimal( 0 ); ?>" value="">
</span>
@ -107,7 +107,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( wc_product_dimensions_enabled() ) : ?>
<div class="inline-edit-group dimensions">
<div>
<span class="title"><?php _e( 'L/W/H', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'L/W/H', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<input type="text" name="_length" class="text wc_input_decimal length" placeholder="<?php esc_attr_e( 'Length', 'woocommerce' ); ?>" value="">
<input type="text" name="_width" class="text wc_input_decimal width" placeholder="<?php esc_attr_e( 'Width', 'woocommerce' ); ?>" value="">
@ -120,51 +120,61 @@ if ( ! defined( 'ABSPATH' ) ) {
</div>
<?php endif; ?>
<label class="alignleft">
<span class="title"><?php _e( 'Shipping class', 'woocommerce' ); ?></span>
<div class="inline-edit-group">
<span class="title"><?php esc_html_e( 'Shipping class', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="shipping_class" name="_shipping_class">
<option value="_no_shipping_class"><?php _e( 'No shipping class', 'woocommerce' ); ?></option>
<option value="_no_shipping_class"><?php esc_html_e( 'No shipping class', 'woocommerce' ); ?></option>
<?php
foreach ( $shipping_class as $key => $value ) {
echo '<option value="' . esc_attr( $value->slug ) . '">' . $value->name . '</option>';
echo '<option value="' . esc_attr( $value->slug ) . '">' . esc_html( $value->name ) . '</option>';
}
?>
</select>
</span>
</label>
<br class="clear" />
</div>
<label class="alignleft">
<span class="title"><?php _e( 'Visibility', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="visibility" name="_visibility">
<?php
$options = apply_filters( 'woocommerce_product_visibility_options', array(
'visible' => __( 'Catalog &amp; search', 'woocommerce' ),
'catalog' => __( 'Catalog', 'woocommerce' ),
'search' => __( 'Search', 'woocommerce' ),
'hidden' => __( 'Hidden', 'woocommerce' ),
) );
foreach ( $options as $key => $value ) {
echo '<option value="' . esc_attr( $key ) . '">' . $value . '</option>';
}
?>
</select>
</span>
</label>
<label class="alignleft featured">
<input type="checkbox" name="_featured" value="1">
<span class="checkbox-title"><?php _e( 'Featured', 'woocommerce' ); ?></span>
</label>
<br class="clear" />
<label class="alignleft">
<span class="title"><?php _e( 'In stock?', 'woocommerce' ); ?></span>
<div class="inline-edit-group">
<label class="alignleft">
<span class="title"><?php esc_html_e( 'Visibility', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="visibility" name="_visibility">
<?php
$options = apply_filters( 'woocommerce_product_visibility_options', array(
'visible' => __( 'Catalog &amp; search', 'woocommerce' ),
'catalog' => __( 'Catalog', 'woocommerce' ),
'search' => __( 'Search', 'woocommerce' ),
'hidden' => __( 'Hidden', 'woocommerce' ),
) );
foreach ( $options as $key => $value ) {
echo '<option value="' . esc_attr( $key ) . '">' . esc_html( $value ) . '</option>';
}
?>
</select>
</span>
</label>
<label class="alignleft featured">
<input type="checkbox" name="_featured" value="1">
<span class="checkbox-title"><?php esc_html_e( 'Featured', 'woocommerce' ); ?></span>
</label>
</div>
<?php if ( get_option( 'woocommerce_manage_stock' ) == 'yes' ) : ?>
<div class="inline-edit-group">
<label class="manage_stock">
<input type="checkbox" name="_manage_stock" value="1">
<span class="checkbox-title"><?php esc_html_e( 'Manage stock?', 'woocommerce' ); ?></span>
</label>
</div>
<?php endif; ?>
<label class="stock_status_field">
<span class="title"><?php esc_html_e( 'In stock?', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="stock_status" name="_stock_status">
<?php
foreach ( wc_get_product_stock_status_options() as $key => $value ) {
echo '<option value="' . esc_attr( $key ) . '">' . $value . '</option>';
echo '<option value="' . esc_attr( $key ) . '">' . esc_html( $value ) . '</option>';
}
?>
</select>
@ -172,30 +182,23 @@ if ( ! defined( 'ABSPATH' ) ) {
</label>
<div class="stock_fields">
<?php if ( get_option( 'woocommerce_manage_stock' ) == 'yes' ) : ?>
<label class="alignleft manage_stock">
<input type="checkbox" name="_manage_stock" value="1">
<span class="checkbox-title"><?php _e( 'Manage stock?', 'woocommerce' ); ?></span>
</label>
<br class="clear" />
<label class="stock_qty_field">
<span class="title"><?php _e( 'Stock qty', 'woocommerce' ); ?></span>
<span class="title"><?php esc_html_e( 'Stock qty', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<input type="number" name="_stock" class="text stock" step="any" value="">
</span>
</label>
<?php endif; ?>
</div>
<label class="alignleft">
<span class="title"><?php _e( 'Backorders?', 'woocommerce' ); ?></span>
<label class="alignleft backorder_field">
<span class="title"><?php esc_html_e( 'Backorders?', 'woocommerce' ); ?></span>
<span class="input-text-wrap">
<select class="backorders" name="_backorders">
<?php
foreach ( wc_get_product_backorder_options() as $key => $value ) {
echo '<option value="' . esc_attr( $key ) . '">' . $value . '</option>';
echo '<option value="' . esc_attr( $key ) . '">' . esc_html( $value ) . '</option>';
}
?>
</select>

View File

@ -309,3 +309,24 @@ function wc_save_order_items( $order_id, $items ) {
// Inform other plugins that the items have been saved
do_action( 'woocommerce_saved_order_items', $order_id, $items );
}
/**
* Get HTML for some action buttons. Used in list tables.
*
* @since 3.3.0
* @param array $actions Actions to output.
* @return string
*/
function wc_render_action_buttons( $actions ) {
$actions_html = '';
foreach ( $actions as $action ) {
if ( isset( $action['group'] ) ) {
$actions_html .= '<div class="wc-action-button-group"><label>' . $action['group'] . '</label> <span class="wc-action-button-group__items">' . wc_render_action_buttons( $action['actions'] ) . '</span></div>';
} elseif ( isset( $action['action'], $action['url'], $action['name'] ) ) {
$actions_html .= sprintf( '<a class="button wc-action-button wc-action-button-%s %s" href="%s" title="%s">%s</a>', esc_attr( $action['action'] ), esc_attr( $action['action'] ), esc_url( $action['url'] ), esc_attr( $action['name'] ), esc_attr( $action['name'] ) );
}
}
return $actions_html;
}

View File

@ -507,7 +507,7 @@ class WC_REST_Coupons_Controller extends WC_REST_Legacy_Coupons_Controller {
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
),

View File

@ -354,7 +354,7 @@ class WC_REST_Customers_Controller extends WC_REST_Customers_V1_Controller {
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
),

View File

@ -401,7 +401,7 @@ class WC_REST_Order_Refunds_Controller extends WC_REST_Orders_Controller {
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
),
@ -422,12 +422,12 @@ class WC_REST_Order_Refunds_Controller extends WC_REST_Orders_Controller {
),
'name' => array(
'description' => __( 'Product name.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'product_id' => array(
'description' => __( 'Product ID.', 'woocommerce' ),
'type' => 'integer',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'variation_id' => array(
@ -513,7 +513,7 @@ class WC_REST_Order_Refunds_Controller extends WC_REST_Orders_Controller {
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
),

View File

@ -597,8 +597,9 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
protected function maybe_set_item_meta_data( $item, $posted ) {
if ( ! empty( $posted['meta_data'] ) && is_array( $posted['meta_data'] ) ) {
foreach ( $posted['meta_data'] as $meta ) {
if ( isset( $meta['key'], $meta['value'] ) ) {
$item->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' );
if ( isset( $meta['key'] ) ) {
$value = isset( $meta['value'] ) ? $meta['value'] : null;
$item->update_meta_data( $meta['key'], $value, isset( $meta['id'] ) ? $meta['id'] : '' );
}
}
}
@ -1118,7 +1119,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
),
@ -1139,12 +1140,12 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
),
'name' => array(
'description' => __( 'Product name.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'product_id' => array(
'description' => __( 'Product ID.', 'woocommerce' ),
'type' => 'integer',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'variation_id' => array(
@ -1230,7 +1231,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
),
@ -1321,7 +1322,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
),
@ -1345,12 +1346,12 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
),
'method_title' => array(
'description' => __( 'Shipping method name.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'method_id' => array(
'description' => __( 'Shipping method ID.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'total' => array(
@ -1407,7 +1408,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
),
@ -1431,7 +1432,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
),
'name' => array(
'description' => __( 'Fee name.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'tax_class' => array(
@ -1505,7 +1506,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
),
@ -1529,7 +1530,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
),
'code' => array(
'description' => __( 'Coupon code.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'discount' => array(
@ -1563,7 +1564,7 @@ class WC_REST_Orders_Controller extends WC_REST_Legacy_Orders_Controller {
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
),

View File

@ -185,7 +185,7 @@ class WC_REST_Product_Categories_Controller extends WC_REST_Product_Categories_V
'format' => 'uri',
'context' => array( 'view', 'edit' ),
),
'name' => array(
'title' => array(
'description' => __( 'Image name.', 'woocommerce' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),

View File

@ -945,7 +945,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Products_Controller
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
),

View File

@ -1991,7 +1991,7 @@ class WC_REST_Products_Controller extends WC_REST_Legacy_Products_Controller {
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
),

View File

@ -378,7 +378,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller {
),
'name' => array(
'description' => __( 'Product name.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
@ -390,7 +390,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller {
),
'product_id' => array(
'description' => __( 'Product ID.', 'woocommerce' ),
'type' => 'integer',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'variation_id' => array(
@ -486,7 +486,7 @@ class WC_REST_Order_Refunds_V1_Controller extends WC_REST_Orders_V1_Controller {
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),

View File

@ -1211,7 +1211,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
),
'name' => array(
'description' => __( 'Product name.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
@ -1223,7 +1223,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
),
'product_id' => array(
'description' => __( 'Product ID.', 'woocommerce' ),
'type' => 'integer',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'variation_id' => array(
@ -1319,7 +1319,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
),
'value' => array(
'description' => __( 'Meta value.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
'readonly' => true,
),
@ -1397,12 +1397,12 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
),
'method_title' => array(
'description' => __( 'Shipping method name.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'method_id' => array(
'description' => __( 'Shipping method ID.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'total' => array(
@ -1457,7 +1457,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
),
'name' => array(
'description' => __( 'Fee name.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'tax_class' => array(
@ -1528,7 +1528,7 @@ class WC_REST_Orders_V1_Controller extends WC_REST_Posts_Controller {
),
'code' => array(
'description' => __( 'Coupon code.', 'woocommerce' ),
'type' => 'string',
'type' => 'mixed',
'context' => array( 'view', 'edit' ),
),
'discount' => array(

View File

@ -240,7 +240,7 @@ class WC_REST_Product_Categories_V1_Controller extends WC_REST_Terms_Controller
'format' => 'uri',
'context' => array( 'view', 'edit' ),
),
'name' => array(
'title' => array(
'description' => __( 'Image name.', 'woocommerce' ),
'type' => 'string',
'context' => array( 'view', 'edit' ),

View File

@ -378,7 +378,7 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller {
),
'date_min' => array(
/* translators: %s: date format */
'description' => sprintf( __( 'Return sales for a specific start date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-AA' ),
'description' => sprintf( __( 'Return sales for a specific start date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ),
'type' => 'string',
'format' => 'date',
'validate_callback' => 'wc_rest_validate_reports_request_arg',
@ -386,7 +386,7 @@ class WC_REST_Report_Sales_V1_Controller extends WC_REST_Controller {
),
'date_max' => array(
/* translators: %s: date format */
'description' => sprintf( __( 'Return sales for a specific end date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-AA' ),
'description' => sprintf( __( 'Return sales for a specific end date, the date need to be in the %s format.', 'woocommerce' ), 'YYYY-MM-DD' ),
'type' => 'string',
'format' => 'date',
'validate_callback' => 'wc_rest_validate_reports_request_arg',

View File

@ -388,7 +388,7 @@ class WC_AJAX {
}
/**
* AJAX add to cart.
* AJAX remove from cart.
*/
public static function remove_from_cart() {
ob_start();
@ -483,83 +483,12 @@ class WC_AJAX {
wp_die( -1 );
}
if ( $order = wc_get_order( absint( $_GET['order_id'] ) ) ) {
$order = wc_get_order( absint( $_GET['order_id'] ) ); // WPCS: sanitization ok.
ob_start();
if ( $order ) {
include_once( 'admin/list-tables/class-wc-admin-list-table-orders.php' );
$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( apply_filters( 'woocommerce_ajax_get_order_details', 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(),
), $order ) );
wp_send_json_success( WC_Admin_List_Table_Orders::order_preview_get_order_details( $order ) );
}
exit;
}
@ -1735,9 +1664,6 @@ class WC_AJAX {
wp_send_json_success( $response_data );
} catch ( Exception $e ) {
if ( $refund && is_a( $refund, 'WC_Order_Refund' ) ) {
wp_delete_post( $refund->get_id(), true );
}
wp_send_json_error( array( 'error' => $e->getMessage() ) );
}
}
@ -2039,6 +1965,17 @@ class WC_AJAX {
self::variation_bulk_set( $variations, 'stock_status', 'outofstock' );
}
/**
* Bulk action - Set Stock Status as On Backorder.
* @access private
* @used-by bulk_edit_variations
* @param array $variations
* @param array $data
*/
private static function variation_bulk_action_variable_stock_status_onbackorder( $variations, $data ) {
self::variation_bulk_set( $variations, 'stock_status', 'onbackorder' );
}
/**
* Bulk action - Set Stock.
* @access private

View File

@ -71,11 +71,14 @@ final class WC_Cart_Session {
$this->cart->set_coupon_discount_tax_totals( WC()->session->get( 'coupon_discount_tax_totals', array() ) );
$this->cart->set_removed_cart_contents( WC()->session->get( 'removed_cart_contents', array() ) );
if ( is_null( $cart ) && ( $saved_cart = get_user_meta( get_current_user_id(), '_woocommerce_persistent_cart_' . get_current_blog_id(), true ) ) ) {
if ( is_null( $cart ) && ( $saved_cart = get_user_meta( get_current_user_id(), '_woocommerce_persistent_cart_' . get_current_blog_id(), true ) ) ) { // @codingStandardsIgnoreLine
$cart = $saved_cart['cart'];
$update_cart_session = true;
} elseif ( is_null( $cart ) ) {
$cart = array();
} elseif ( is_array( $cart ) && ( $saved_cart = get_user_meta( get_current_user_id(), '_woocommerce_persistent_cart_' . get_current_blog_id(), true ) ) ) { // @codingStandardsIgnoreLine
$cart = array_merge( $saved_cart['cart'], $cart );
$update_cart_session = true;
}
if ( is_array( $cart ) ) {
@ -97,7 +100,9 @@ final class WC_Cart_Session {
} else {
// Put session data into array. Run through filter so other plugins can load their own session data.
$session_data = array_merge( $values, array( 'data' => $product ) );
$session_data = array_merge( $values, array(
'data' => $product,
) );
$cart_contents[ $key ] = apply_filters( 'woocommerce_get_cart_item_from_session', $session_data, $values, $key );
// Add to cart right away so the product is visible in woocommerce_get_cart_item_from_session hook.
@ -180,7 +185,9 @@ final class WC_Cart_Session {
*/
public function persistent_cart_update() {
if ( get_current_user_id() ) {
update_user_meta( get_current_user_id(), '_woocommerce_persistent_cart_' . get_current_blog_id(), array( 'cart' => $this->get_cart_for_session() ) );
update_user_meta( get_current_user_id(), '_woocommerce_persistent_cart_' . get_current_blog_id(), array(
'cart' => $this->get_cart_for_session(),
) );
}
}

View File

@ -227,7 +227,7 @@ final class WC_Cart_Totals {
$item->taxable = 'taxable' === $cart_item['data']->get_tax_status();
$item->price_includes_tax = wc_prices_include_tax();
$item->quantity = $cart_item['quantity'];
$item->price = wc_add_number_precision_deep( $cart_item['data']->get_price() ) * $cart_item['quantity'];
$item->price = wc_add_number_precision_deep( $cart_item['data']->get_price() * $cart_item['quantity'] );
$item->product = $cart_item['data'];
$item->tax_rates = $this->get_item_tax_rates( $item );
$this->items[ $cart_item_key ] = $item;
@ -423,7 +423,7 @@ final class WC_Cart_Totals {
* @return object
*/
protected function remove_item_base_taxes( $item ) {
if ( $item->price_includes_tax ) {
if ( $item->price_includes_tax && $item->taxable ) {
$base_tax_rates = WC_Tax::get_base_tax_rates( $item->product->get_tax_class( 'unfiltered' ) );
// Work out a new base price without the shop's base tax.
@ -449,7 +449,7 @@ final class WC_Cart_Totals {
* @return object
*/
protected function adjust_non_base_location_price( $item ) {
if ( $item->price_includes_tax ) {
if ( $item->price_includes_tax && $item->taxable ) {
$base_tax_rates = WC_Tax::get_base_tax_rates( $item->product->get_tax_class( 'unfiltered' ) );
if ( $item->tax_rates !== $base_tax_rates ) {

View File

@ -981,6 +981,23 @@ class WC_Cart extends WC_Legacy_Cart {
return array_unique( $found_tax_classes );
}
/**
* Get all tax classes for shipping based on the items in the cart.
*
* @return array
*/
public function get_cart_item_tax_classes_for_shipping() {
$found_tax_classes = array();
foreach ( WC()->cart->get_cart() as $item ) {
if ( $item['data'] && ( $item['data']->is_shipping_taxable() ) ) {
$found_tax_classes[] = $item['data']->get_tax_class();
}
}
return array_unique( $found_tax_classes );
}
/**
* Determines the value that the customer spent and the subtotal
* displayed, used for things like coupon validation.
@ -1085,7 +1102,7 @@ class WC_Cart extends WC_Legacy_Cart {
}
// Load cart item data - may be added by other plugins.
$cart_item_data = (array) apply_filters( 'woocommerce_add_cart_item_data', $cart_item_data, $product_id, $variation_id );
$cart_item_data = (array) apply_filters( 'woocommerce_add_cart_item_data', $cart_item_data, $product_id, $variation_id, $quantity );
// Generate a ID based on product ID, variation ID, variation data, and other cart item data.
$cart_id = $this->generate_cart_id( $product_id, $variation_id, $variation, $cart_item_data );

View File

@ -469,7 +469,7 @@ class WC_Checkout {
* @param WC_Cart $cart
*/
public function create_order_tax_lines( &$order, $cart ) {
foreach ( array_keys( $cart->get_cart_contents_taxes() + $cart->get_shipping_taxes() ) as $tax_rate_id ) {
foreach ( array_keys( $cart->get_cart_contents_taxes() + $cart->get_shipping_taxes() + $cart->get_fee_taxes() ) as $tax_rate_id ) {
if ( $tax_rate_id && apply_filters( 'woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated' ) !== $tax_rate_id ) {
$item = new WC_Order_Item_Tax();
$item->set_props( array(

View File

@ -218,7 +218,10 @@ class WC_Comments {
$stats = get_transient( 'wc_count_comments' );
if ( ! $stats ) {
$stats = array();
$stats = array(
'total_comments' => 0,
'all' => 0,
);
$count = $wpdb->get_results( "
SELECT comment_approved, COUNT(*) AS num_comments
@ -227,7 +230,6 @@ class WC_Comments {
GROUP BY comment_approved
", ARRAY_A );
$total = 0;
$approved = array(
'0' => 'moderated',
'1' => 'approved',
@ -238,16 +240,17 @@ class WC_Comments {
foreach ( (array) $count as $row ) {
// Don't count post-trashed toward totals.
if ( 'post-trashed' !== $row['comment_approved'] && 'trash' !== $row['comment_approved'] ) {
$total += $row['num_comments'];
if ( ! in_array( $row['comment_approved'], array( 'post-trashed', 'trash', 'spam' ), true ) ) {
$stats['all'] += $row['num_comments'];
$stats['total_comments'] += $row['num_comments'];
} elseif ( ! in_array( $row['comment_approved'], array( 'post-trashed', 'trash' ), true ) ) {
$stats['total_comments'] += $row['num_comments'];
}
if ( isset( $approved[ $row['comment_approved'] ] ) ) {
$stats[ $approved[ $row['comment_approved'] ] ] = $row['num_comments'];
}
}
$stats['total_comments'] = $total;
$stats['all'] = $total;
foreach ( $approved as $key ) {
if ( empty( $stats[ $key ] ) ) {
$stats[ $key ] = 0;

View File

@ -1,12 +1,18 @@
<?php
/**
* Deprecated action hooks
*
* @package WooCommerce\Abstracts
* @since 3.0.0
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Handles deprecation notices and triggering of legacy action hooks.
*
* @since 3.0.0
*/
class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
@ -16,7 +22,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
* @var array
*/
protected $deprecated_hooks = array(
'woocommerce_new_order_item' => array(
'woocommerce_new_order_item' => array(
'woocommerce_order_add_shipping',
'woocommerce_order_add_coupon',
'woocommerce_order_add_tax',
@ -25,21 +31,45 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
'woocommerce_add_order_item_meta',
'woocommerce_add_order_fee_meta',
),
'woocommerce_update_order_item' => array(
'woocommerce_update_order_item' => array(
'woocommerce_order_edit_product',
'woocommerce_order_update_coupon',
'woocommerce_order_update_shipping',
'woocommerce_order_update_fee',
'woocommerce_order_update_tax',
),
'woocommerce_new_payment_token' => 'woocommerce_payment_token_created',
'woocommerce_new_product_variation' => 'woocommerce_create_product_variation',
'woocommerce_order_details_after_order_table_items' => 'woocommerce_order_items_table'
'woocommerce_new_payment_token' => 'woocommerce_payment_token_created',
'woocommerce_new_product_variation' => 'woocommerce_create_product_variation',
'woocommerce_order_details_after_order_table_items' => 'woocommerce_order_items_table',
);
/**
* Array of versions on each hook has been deprecated.
*
* @var array
*/
protected $deprecated_version = array(
'woocommerce_order_add_shipping' => '3.0.0',
'woocommerce_order_add_coupon' => '3.0.0',
'woocommerce_order_add_tax' => '3.0.0',
'woocommerce_order_add_fee' => '3.0.0',
'woocommerce_add_shipping_order_item' => '3.0.0',
'woocommerce_add_order_item_meta' => '3.0.0',
'woocommerce_add_order_fee_meta' => '3.0.0',
'woocommerce_order_edit_product' => '3.0.0',
'woocommerce_order_update_coupon' => '3.0.0',
'woocommerce_order_update_shipping' => '3.0.0',
'woocommerce_order_update_fee' => '3.0.0',
'woocommerce_order_update_tax' => '3.0.0',
'woocommerce_payment_token_created' => '3.0.0',
'woocommerce_create_product_variation' => '3.0.0',
'woocommerce_order_items_table' => '3.0.0',
);
/**
* Hook into the new hook so we can handle deprecated hooks once fired.
* @param string $hook_name
*
* @param string $hook_name Hook name.
*/
public function hook_in( $hook_name ) {
add_action( $hook_name, array( $this, 'maybe_handle_deprecated_hook' ), -1000, 8 );
@ -48,10 +78,10 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
/**
* If the old hook is in-use, trigger it.
*
* @param string $new_hook
* @param string $old_hook
* @param array $new_callback_args
* @param mixed $return_value
* @param string $new_hook New hook name.
* @param string $old_hook Old hook name.
* @param array $new_callback_args New callback args.
* @param mixed $return_value Returned value.
* @return mixed
*/
public function handle_deprecated_hook( $new_hook, $old_hook, $new_callback_args, $return_value ) {
@ -65,14 +95,14 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
/**
* Fire off a legacy hook with it's args.
*
* @param string $old_hook
* @param array $new_callback_args
* @param string $old_hook Old hook name.
* @param array $new_callback_args New callback args.
* @return mixed
*/
protected function trigger_hook( $old_hook, $new_callback_args ) {
switch ( $old_hook ) {
case 'woocommerce_order_add_shipping' :
case 'woocommerce_order_add_fee' :
case 'woocommerce_order_add_shipping':
case 'woocommerce_order_add_fee':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -80,7 +110,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $order_id, $item_id, $item );
}
break;
case 'woocommerce_order_add_coupon' :
case 'woocommerce_order_add_coupon':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -88,7 +118,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $order_id, $item_id, $item->get_code(), $item->get_discount(), $item->get_discount_tax() );
}
break;
case 'woocommerce_order_add_tax' :
case 'woocommerce_order_add_tax':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -96,7 +126,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $order_id, $item_id, $item->get_rate_id(), $item->get_tax_total(), $item->get_shipping_tax_total() );
}
break;
case 'woocommerce_add_shipping_order_item' :
case 'woocommerce_add_shipping_order_item':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -104,7 +134,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $order_id, $item_id, $item->legacy_package_key );
}
break;
case 'woocommerce_add_order_item_meta' :
case 'woocommerce_add_order_item_meta':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -112,7 +142,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $item_id, $item->legacy_values, $item->legacy_cart_item_key );
}
break;
case 'woocommerce_add_order_fee_meta' :
case 'woocommerce_add_order_fee_meta':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -120,7 +150,7 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $order_id, $item_id, $item->legacy_fee, $item->legacy_fee_key );
}
break;
case 'woocommerce_order_edit_product' :
case 'woocommerce_order_edit_product':
$item_id = $new_callback_args[0];
$item = $new_callback_args[1];
$order_id = $new_callback_args[2];
@ -128,15 +158,15 @@ class WC_Deprecated_Action_Hooks extends WC_Deprecated_Hooks {
do_action( $old_hook, $order_id, $item_id, $item, $item->get_product() );
}
break;
case 'woocommerce_order_update_coupon' :
case 'woocommerce_order_update_shipping' :
case 'woocommerce_order_update_fee' :
case 'woocommerce_order_update_tax' :
case 'woocommerce_order_update_coupon':
case 'woocommerce_order_update_shipping':
case 'woocommerce_order_update_fee':
case 'woocommerce_order_update_tax':
if ( ! is_a( $item, 'WC_Order_Item_Product' ) ) {
do_action( $old_hook, $order_id, $item_id, $item );
}
break;
default :
default:
do_action_ref_array( $old_hook, $new_callback_args );
break;
}

View File

@ -1,12 +1,18 @@
<?php
/**
* Deprecated filter hooks
*
* @package WooCommerce\Abstracts
* @since 3.0.0
* @version 3.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Handles deprecation notices and triggering of legacy filter hooks.
*
* @since 3.0.0
* Handles deprecation notices and triggering of legacy filter hooks
*/
class WC_Deprecated_Filter_Hooks extends WC_Deprecated_Hooks {
@ -54,9 +60,53 @@ class WC_Deprecated_Filter_Hooks extends WC_Deprecated_Hooks {
'woocommerce_credit_card_type_labels' => 'wocommerce_credit_card_type_labels',
);
/**
* Array of versions on each hook has been deprecated.
*
* @var array
*/
protected $deprecated_version = array(
'woocommerce_email_order_schema_markup' => '3.0.0',
'add_to_cart_fragments' => '3.0.0',
'add_to_cart_redirect' => '3.0.0',
'woocommerce_product_width' => '3.0.0',
'woocommerce_product_height' => '3.0.0',
'woocommerce_product_length' => '3.0.0',
'woocommerce_product_weight' => '3.0.0',
'woocommerce_get_sku' => '3.0.0',
'woocommerce_get_price' => '3.0.0',
'woocommerce_get_regular_price' => '3.0.0',
'woocommerce_get_sale_price' => '3.0.0',
'woocommerce_product_tax_class' => '3.0.0',
'woocommerce_get_stock_quantity' => '3.0.0',
'woocommerce_get_product_attributes' => '3.0.0',
'woocommerce_product_gallery_attachment_ids' => '3.0.0',
'woocommerce_product_review_count' => '3.0.0',
'woocommerce_product_files' => '3.0.0',
'woocommerce_get_currency' => '3.0.0',
'woocommerce_order_amount_discount_total' => '3.0.0',
'woocommerce_order_amount_discount_tax' => '3.0.0',
'woocommerce_order_amount_shipping_total' => '3.0.0',
'woocommerce_order_amount_shipping_tax' => '3.0.0',
'woocommerce_order_amount_cart_tax' => '3.0.0',
'woocommerce_order_amount_total' => '3.0.0',
'woocommerce_order_amount_total_tax' => '3.0.0',
'woocommerce_order_amount_total_discount' => '3.0.0',
'woocommerce_order_amount_subtotal' => '3.0.0',
'woocommerce_order_tax_totals' => '3.0.0',
'woocommerce_refund_amount' => '3.0.0',
'woocommerce_refund_reason' => '3.0.0',
'default_checkout_country' => '3.0.0',
'default_checkout_state' => '3.0.0',
'default_checkout_postcode' => '3.0.0',
'woocommerce_debug_posting' => '3.0.0',
'wocommerce_credit_card_type_labels' => '3.0.0',
);
/**
* Hook into the new hook so we can handle deprecated hooks once fired.
* @param string $hook_name
*
* @param string $hook_name Hook name.
*/
public function hook_in( $hook_name ) {
add_filter( $hook_name, array( $this, 'maybe_handle_deprecated_hook' ), -1000, 8 );
@ -65,10 +115,10 @@ class WC_Deprecated_Filter_Hooks extends WC_Deprecated_Hooks {
/**
* If the old hook is in-use, trigger it.
*
* @param string $new_hook
* @param string $old_hook
* @param array $new_callback_args
* @param mixed $return_value
* @param string $new_hook New hook name.
* @param string $old_hook Old hook name.
* @param array $new_callback_args New callback args.
* @param mixed $return_value Returned value.
* @return mixed
*/
public function handle_deprecated_hook( $new_hook, $old_hook, $new_callback_args, $return_value ) {
@ -82,8 +132,8 @@ class WC_Deprecated_Filter_Hooks extends WC_Deprecated_Hooks {
/**
* Fire off a legacy hook with it's args.
*
* @param string $old_hook
* @param array $new_callback_args
* @param string $old_hook Old hook name.
* @param array $new_callback_args New callback args.
* @return mixed
*/
protected function trigger_hook( $old_hook, $new_callback_args ) {

View File

@ -887,7 +887,7 @@ class WC_Form_Handler {
// Don't use wc_clean as it destroys sanitized characters.
$value = sanitize_title( wp_unslash( $_REQUEST[ $taxonomy ] ) );
} else {
$value = wc_clean( wp_unslash( $_REQUEST[ $taxonomy ] ) ); // WPCS: sanitization ok.
$value = html_entity_decode( wc_clean( wp_unslash( $_REQUEST[ $taxonomy ] ) ), ENT_QUOTES, get_bloginfo( 'charset' ) ); // WPCS: sanitization ok.
}
// Allow if valid or show error.
@ -974,7 +974,7 @@ class WC_Form_Handler {
$redirect = wc_get_page_permalink( 'myaccount' );
}
wp_redirect( wp_validate_redirect( apply_filters( 'woocommerce_login_redirect', $redirect, $user ), wc_get_page_permalink( 'myaccount' ) ) );
wp_redirect( wp_validate_redirect( apply_filters( 'woocommerce_login_redirect', remove_query_arg( 'wc_error', $redirect ), $user ), wc_get_page_permalink( 'myaccount' ) ) );
exit;
}
} catch ( Exception $e ) {

View File

@ -220,7 +220,7 @@ class WC_Frontend_Scripts {
'selectWoo' => array(
'src' => self::get_asset_url( 'assets/js/selectWoo/selectWoo.full' . $suffix . '.js' ),
'deps' => array( 'jquery' ),
'version' => '1.0.1',
'version' => '1.0.2',
),
'wc-address-i18n' => array(
'src' => self::get_asset_url( 'assets/js/frontend/address-i18n' . $suffix . '.js' ),

View File

@ -21,11 +21,21 @@ if ( ! defined( 'ABSPATH' ) ) {
*/
class WC_Geolocation {
/** URL to the geolocation database we're using */
const GEOLITE_DB = 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz';
/**
* GeoLite IPv4 DB.
*/
const GEOLITE_DB = 'http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz';
/**
* GeoLite IPv6 DB.
*/
const GEOLITE_IPV6_DB = 'http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz';
/** @var array API endpoints for looking up user IP address */
/**
* API endpoints for looking up user IP address.
*
* @var array
*/
private static $ip_lookup_apis = array(
'icanhazip' => 'http://icanhazip.com',
'ipify' => 'http://api.ipify.org/',
@ -35,7 +45,11 @@ class WC_Geolocation {
'ip.appspot' => 'http://ip.appspot.com',
);
/** @var array API endpoints for geolocating an IP address */
/**
* API endpoints for geolocating an IP address
*
* @var array
*/
private static $geoip_apis = array(
'freegeoip' => 'https://freegeoip.net/json/%s',
'ipinfo.io' => 'https://ipinfo.io/%s/json',
@ -46,7 +60,7 @@ class WC_Geolocation {
* Hook in tabs.
*/
public static function init() {
// Only download the database from MaxMind if the geolocation function is enabled, or a plugin specifically requests it
// Only download the database from MaxMind if the geolocation function is enabled, or a plugin specifically requests it.
if ( 'geolocation' === get_option( 'woocommerce_default_customer_address' ) || apply_filters( 'woocommerce_geolocation_update_database_periodically', false ) ) {
add_action( 'woocommerce_geoip_updater', array( __CLASS__, 'update_database' ) );
}
@ -55,8 +69,9 @@ class WC_Geolocation {
/**
* Maybe trigger a DB update for the first time.
* @param string $new_value
* @param string $old_value
*
* @param string $new_value New value.
* @param string $old_value Old value.
* @return string
*/
public static function maybe_update_database( $new_value, $old_value ) {
@ -66,46 +81,20 @@ class WC_Geolocation {
return $new_value;
}
/**
* Check if is a valid IP address.
*
* @since 3.0.6
* @param string $ip_address IP address.
* @return string|bool The valid IP address, otherwise false.
*/
private static function is_ip_address( $ip_address ) {
// WP 4.7+ only.
if ( function_exists( 'rest_is_ip_address' ) ) {
return rest_is_ip_address( $ip_address );
}
// Support for WordPress 4.4 to 4.6.
if ( ! class_exists( 'Requests_IPv6', false ) ) {
include_once( dirname( __FILE__ ) . '/vendor/class-requests-ipv6.php' );
}
$ipv4_pattern = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/';
if ( ! preg_match( $ipv4_pattern, $ip_address ) && ! Requests_IPv6::check_ipv6( $ip_address ) ) {
return false;
}
return $ip_address;
}
/**
* Get current user IP Address.
*
* @return string
*/
public static function get_ip_address() {
if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) {
return $_SERVER['HTTP_X_REAL_IP'];
} elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
if ( isset( $_SERVER['HTTP_X_REAL_IP'] ) ) { // WPCS: input var ok, CSRF ok.
return sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_REAL_IP'] ) ); // WPCS: input var ok, CSRF ok.
} elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) { // WPCS: input var ok, CSRF ok.
// Proxy servers can send through this header like this: X-Forwarded-For: client1, proxy1, proxy2
// Make sure we always only send through the first IP in the list which should always be the client IP.
return (string) self::is_ip_address( trim( current( explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) );
} elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
return $_SERVER['REMOTE_ADDR'];
return (string) rest_is_ip_address( trim( current( explode( ',', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) ) ) ) ); // WPCS: input var ok, CSRF ok.
} elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) { // @codingStandardsIgnoreLine
return sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ); // @codingStandardsIgnoreLine
}
return '';
}
@ -114,6 +103,7 @@ class WC_Geolocation {
* Get user IP Address using an external service.
* This is used mainly as a fallback for users on localhost where
* get_ip_address() will be a local IP and non-geolocatable.
*
* @return string
*/
public static function get_external_ip_address() {
@ -148,8 +138,9 @@ class WC_Geolocation {
/**
* Geolocate an IP address.
* @param string $ip_address
* @param bool $fallback If true, fallbacks to alternative IP detection (can be slower).
*
* @param string $ip_address IP Address.
* @param bool $fallback If true, fallbacks to alternative IP detection (can be slower).
* @param bool $api_fallback If true, uses geolocation APIs if the database file doesn't exist (can be slower).
* @return array
*/
@ -158,19 +149,19 @@ class WC_Geolocation {
$country_code = apply_filters( 'woocommerce_geolocate_ip', false, $ip_address, $fallback, $api_fallback );
if ( false === $country_code ) {
// If GEOIP is enabled in CloudFlare, we can use that (Settings -> CloudFlare Settings -> Settings Overview)
if ( ! empty( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ) {
$country_code = sanitize_text_field( strtoupper( $_SERVER['HTTP_CF_IPCOUNTRY'] ) );
// WP.com VIP has a variable available.
} elseif ( ! empty( $_SERVER['GEOIP_COUNTRY_CODE'] ) ) {
$country_code = sanitize_text_field( strtoupper( $_SERVER['GEOIP_COUNTRY_CODE'] ) );
// VIP Go has a variable available also.
} elseif ( ! empty( $_SERVER['HTTP_X_COUNTRY_CODE'] ) ) {
$country_code = sanitize_text_field( strtoupper( $_SERVER['HTTP_X_COUNTRY_CODE'] ) );
// If GEOIP is enabled in CloudFlare, we can use that (Settings -> CloudFlare Settings -> Settings Overview).
if ( ! empty( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ) { // WPCS: input var ok, CSRF ok.
$country_code = strtoupper( sanitize_text_field( wp_unslash( $_SERVER['HTTP_CF_IPCOUNTRY'] ) ) ); // WPCS: input var ok, CSRF ok.
} elseif ( ! empty( $_SERVER['GEOIP_COUNTRY_CODE'] ) ) { // WPCS: input var ok, CSRF ok.
// WP.com VIP has a variable available.
$country_code = strtoupper( sanitize_text_field( wp_unslash( $_SERVER['GEOIP_COUNTRY_CODE'] ) ) ); // WPCS: input var ok, CSRF ok.
} elseif ( ! empty( $_SERVER['HTTP_X_COUNTRY_CODE'] ) ) { // WPCS: input var ok, CSRF ok.
// VIP Go has a variable available also.
$country_code = strtoupper( sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_COUNTRY_CODE'] ) ) ); // WPCS: input var ok, CSRF ok.
} else {
$ip_address = $ip_address ? $ip_address : self::get_ip_address();
if ( self::is_IPv6( $ip_address ) ) {
if ( self::is_ipv6( $ip_address ) ) {
$database = self::get_local_database_path( 'v6' );
} else {
$database = self::get_local_database_path();
@ -185,7 +176,7 @@ class WC_Geolocation {
}
if ( ! $country_code && $fallback ) {
// May be a local environment - find external IP
// May be a local environment - find external IP.
return self::geolocate_ip( self::get_external_ip_address(), false, $api_fallback );
}
}
@ -199,11 +190,12 @@ class WC_Geolocation {
/**
* Path to our local db.
* @param string $version
*
* @param string $version Version.
* @return string
*/
public static function get_local_database_path( $version = 'v4' ) {
$version = ( 'v4' == $version ) ? '' : 'v6';
$version = 'v4' === $version ? '' : 'v6';
$upload_dir = wp_upload_dir();
return apply_filters( 'woocommerce_geolocation_local_database_path', $upload_dir['basedir'] . '/GeoIP' . $version . '.dat', $version );
@ -220,7 +212,7 @@ class WC_Geolocation {
return;
}
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once ABSPATH . 'wp-admin/includes/file.php';
$tmp_databases = array(
'v4' => download_url( self::GEOLITE_DB ),
@ -229,20 +221,20 @@ class WC_Geolocation {
foreach ( $tmp_databases as $tmp_database_version => $tmp_database_path ) {
if ( ! is_wp_error( $tmp_database_path ) ) {
$gzhandle = @gzopen( $tmp_database_path, 'r' );
$handle = @fopen( self::get_local_database_path( $tmp_database_version ), 'w' );
$gzhandle = @gzopen( $tmp_database_path, 'r' ); // @codingStandardsIgnoreLine
$handle = @fopen( self::get_local_database_path( $tmp_database_version ), 'w' ); // @codingStandardsIgnoreLine
if ( $gzhandle && $handle ) {
while ( $string = gzread( $gzhandle, 4096 ) ) {
fwrite( $handle, $string, strlen( $string ) );
while ( $string = gzread( $gzhandle, 4096 ) ) { // @codingStandardsIgnoreLine
fwrite( $handle, $string, strlen( $string ) ); // @codingStandardsIgnoreLine
}
gzclose( $gzhandle );
$s_array = fstat( $handle );
fclose( $handle );
fclose( $handle ); // @codingStandardsIgnoreLine
if ( ! isset( $s_array['size'] ) || 0 === $s_array['size'] ) {
$logger->notice( 'Empty database file, deleting local copy.', array( 'source' => 'geolocation' ) );
// Delete empty DB, we do not want to keep empty files around.
@unlink( self::get_local_database_path( $tmp_database_version ) );
@unlink( self::get_local_database_path( $tmp_database_version ) ); // @codingStandardsIgnoreLine
// Reschedule download of DB.
wp_clear_scheduled_hook( 'woocommerce_geoip_updater' );
wp_schedule_event( strtotime( 'first tuesday of next month' ), 'monthly', 'woocommerce_geoip_updater' );
@ -250,7 +242,7 @@ class WC_Geolocation {
} else {
$logger->notice( 'Unable to open database file', array( 'source' => 'geolocation' ) );
}
@unlink( $tmp_database_path );
@unlink( $tmp_database_path ); // @codingStandardsIgnoreLine
} else {
$logger->notice(
'Unable to download GeoIP Database: ' . $tmp_database_path->get_error_message(),
@ -262,17 +254,18 @@ class WC_Geolocation {
/**
* Use MAXMIND GeoLite database to geolocation the user.
* @param string $ip_address
*
* @param string $ip_address IP address.
* @return string
*/
private static function geolocate_via_db( $ip_address ) {
if ( ! class_exists( 'WC_Geo_IP', false ) ) {
include_once( WC_ABSPATH . 'includes/class-wc-geo-ip.php' );
include_once WC_ABSPATH . 'includes/class-wc-geo-ip.php';
}
$gi = new WC_Geo_IP();
if ( self::is_IPv6( $ip_address ) ) {
if ( self::is_ipv6( $ip_address ) ) {
$database = self::get_local_database_path( 'v6' );
if ( ! self::get_file_size( $database ) ) {
return false;
@ -301,14 +294,14 @@ class WC_Geolocation {
* @return bool|int
*/
private static function get_file_size( $filename ) {
$handle = @fopen( $filename, 'r' );
$s_array = fstat( $handle );
@fclose( $handle );
$handle = @fopen( $filename, 'r' ); // @codingStandardsIgnoreLine
$s_array = fstat( $handle ); // @codingStandardsIgnoreLine
@fclose( $handle ); // @codingStandardsIgnoreLine
if ( ! isset( $s_array['size'] ) || 0 === $s_array['size'] ) {
$logger = wc_get_logger();
$logger->notice( 'Empty database file, deleting local copy.', array( 'source' => 'geolocation' ) );
// Delete the file as we do not want to keep empty files around.
@unlink( $filename );
@unlink( $filename ); // @codingStandardsIgnoreLine
return false;
}
return $s_array['size'];
@ -316,7 +309,8 @@ class WC_Geolocation {
/**
* Use APIs to Geolocate the user.
* @param string $ip_address
*
* @param string $ip_address IP address.
* @return string|bool
*/
private static function geolocate_via_api( $ip_address ) {
@ -333,21 +327,21 @@ class WC_Geolocation {
if ( ! is_wp_error( $response ) && $response['body'] ) {
switch ( $service_name ) {
case 'ipinfo.io' :
case 'ipinfo.io':
$data = json_decode( $response['body'] );
$country_code = isset( $data->country ) ? $data->country : '';
break;
case 'ip-api.com' :
break;
case 'ip-api.com':
$data = json_decode( $response['body'] );
$country_code = isset( $data->countryCode ) ? $data->countryCode : '';
break;
case 'freegeoip' :
$country_code = isset( $data->countryCode ) ? $data->countryCode : ''; // @codingStandardsIgnoreLine
break;
case 'freegeoip':
$data = json_decode( $response['body'] );
$country_code = isset( $data->country_code ) ? $data->country_code : '';
break;
default :
break;
default:
$country_code = apply_filters( 'woocommerce_geolocation_geoip_response_' . $service_name, '', $response['body'] );
break;
break;
}
$country_code = sanitize_text_field( strtoupper( $country_code ) );
@ -369,10 +363,10 @@ class WC_Geolocation {
*
* @since 2.4.0
*
* @param string $ip_address
* @param string $ip_address IP Address.
* @return bool
*/
private static function is_IPv6( $ip_address ) {
private static function is_ipv6( $ip_address ) {
return false !== filter_var( $ip_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 );
}
}

View File

@ -98,6 +98,9 @@ class WC_Install {
),
'3.3.0' => array(
'wc_update_330_image_options',
'wc_update_330_product_stock_status',
'wc_update_330_set_default_product_cat',
'wc_update_330_clear_transients',
'wc_update_330_db_version',
),
);
@ -128,7 +131,7 @@ class WC_Install {
* Init background updates
*/
public static function init_background_updater() {
include_once( dirname( __FILE__ ) . '/class-wc-background-updater.php' );
include_once dirname( __FILE__ ) . '/class-wc-background-updater.php';
self::$background_updater = new WC_Background_Updater();
}
@ -202,7 +205,7 @@ class WC_Install {
* @since 3.2.0
*/
private static function remove_admin_notices() {
include_once( dirname( __FILE__ ) . '/admin/class-wc-admin-notices.php' );
include_once dirname( __FILE__ ) . '/admin/class-wc-admin-notices.php';
WC_Admin_Notices::remove_all_notices();
}
@ -319,7 +322,8 @@ class WC_Install {
/**
* Update DB version to current.
* @param string $version
*
* @param string|null $version New WooCommerce DB version or null.
*/
public static function update_db_version( $version = null ) {
delete_option( 'woocommerce_db_version' );
@ -328,7 +332,8 @@ class WC_Install {
/**
* Add more cron schedules.
* @param array $schedules
*
* @param array $schedules List of WP scheduled cron jobs.
* @return array
*/
public static function cron_schedules( $schedules ) {
@ -368,30 +373,32 @@ class WC_Install {
* Create pages that the plugin relies on, storing page IDs in variables.
*/
public static function create_pages() {
include_once( dirname( __FILE__ ) . '/admin/wc-admin-functions.php' );
include_once dirname( __FILE__ ) . '/admin/wc-admin-functions.php';
$pages = apply_filters( 'woocommerce_create_pages', array(
'shop' => array(
'name' => _x( 'shop', 'Page slug', 'woocommerce' ),
'title' => _x( 'Shop', 'Page title', 'woocommerce' ),
'content' => '',
),
'cart' => array(
'name' => _x( 'cart', 'Page slug', 'woocommerce' ),
'title' => _x( 'Cart', 'Page title', 'woocommerce' ),
'content' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']',
),
'checkout' => array(
'name' => _x( 'checkout', 'Page slug', 'woocommerce' ),
'title' => _x( 'Checkout', 'Page title', 'woocommerce' ),
'content' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']',
),
'myaccount' => array(
'name' => _x( 'my-account', 'Page slug', 'woocommerce' ),
'title' => _x( 'My account', 'Page title', 'woocommerce' ),
'content' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']',
),
) );
$pages = apply_filters(
'woocommerce_create_pages', array(
'shop' => array(
'name' => _x( 'shop', 'Page slug', 'woocommerce' ),
'title' => _x( 'Shop', 'Page title', 'woocommerce' ),
'content' => '',
),
'cart' => array(
'name' => _x( 'cart', 'Page slug', 'woocommerce' ),
'title' => _x( 'Cart', 'Page title', 'woocommerce' ),
'content' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']',
),
'checkout' => array(
'name' => _x( 'checkout', 'Page slug', 'woocommerce' ),
'title' => _x( 'Checkout', 'Page title', 'woocommerce' ),
'content' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']',
),
'myaccount' => array(
'name' => _x( 'my-account', 'Page slug', 'woocommerce' ),
'title' => _x( 'My account', 'Page title', 'woocommerce' ),
'content' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']',
),
)
);
foreach ( $pages as $key => $page ) {
wc_create_page( esc_sql( $page['name'] ), 'woocommerce_' . $key . '_page_id', $page['title'], $page['content'], ! empty( $page['parent'] ) ? wc_get_page_id( $page['parent'] ) : '' );
@ -406,8 +413,8 @@ class WC_Install {
* Sets up the default options used on the settings page.
*/
private static function create_options() {
// Include settings so that we can run through defaults
include_once( dirname( __FILE__ ) . '/admin/class-wc-admin-settings.php' );
// Include settings so that we can run through defaults.
include_once dirname( __FILE__ ) . '/admin/class-wc-admin-settings.php';
$settings = WC_Admin_Settings::get_settings_pages();
@ -433,7 +440,7 @@ class WC_Install {
*/
public static function create_terms() {
$taxonomies = array(
'product_type' => array(
'product_type' => array(
'simple',
'grouped',
'variable',
@ -454,32 +461,54 @@ class WC_Install {
foreach ( $taxonomies as $taxonomy => $terms ) {
foreach ( $terms as $term ) {
if ( ! get_term_by( 'name', $term, $taxonomy ) ) {
if ( ! get_term_by( 'name', $term, $taxonomy ) ) { // @codingStandardsIgnoreLine.
wp_insert_term( $term, $taxonomy );
}
}
}
$woocommerce_default_category = get_option( 'default_product_cat', 0 );
if ( ! $woocommerce_default_category || ! term_exists( $woocommerce_default_category, 'product_cat' ) ) {
$default_product_cat_id = 0;
$default_product_cat_slug = sanitize_title( _x( 'Uncategorized', 'Default category slug', 'woocommerce' ) );
$default_product_cat = get_term_by( 'slug', $default_product_cat_slug, 'product_cat' ); // @codingStandardsIgnoreLine.
if ( $default_product_cat ) {
$default_product_cat_id = absint( $default_product_cat->term_taxonomy_id );
} else {
$result = wp_insert_term( _x( 'Uncategorized', 'Default category slug', 'woocommerce' ), 'product_cat', array( 'slug' => $default_product_cat_slug ) );
if ( ! empty( $result['term_taxonomy_id'] ) ) {
$default_product_cat_id = absint( $result['term_taxonomy_id'] );
}
}
if ( $default_product_cat_id ) {
update_option( 'default_product_cat', $default_product_cat_id );
}
}
}
/**
* Set up the database tables which the plugin needs to function.
*
* Tables:
* woocommerce_attribute_taxonomies - Table for storing attribute taxonomies - these are user defined
* woocommerce_termmeta - Term meta table - sadly WordPress does not have termmeta so we need our own
* woocommerce_downloadable_product_permissions - Table for storing user and guest download permissions.
* KEY(order_id, product_id, download_id) used for organizing downloads on the My Account page
* woocommerce_order_items - Order line items are stored in a table to make them easily queryable for reports
* woocommerce_order_itemmeta - Order line item meta is stored in a table for storing extra data.
* woocommerce_tax_rates - Tax Rates are stored inside 2 tables making tax queries simple and efficient.
* woocommerce_tax_rate_locations - Each rate can be applied to more than one postcode/city hence the second table.
* woocommerce_attribute_taxonomies - Table for storing attribute taxonomies - these are user defined
* woocommerce_termmeta - Term meta table - sadly WordPress does not have termmeta so we need our own
* woocommerce_downloadable_product_permissions - Table for storing user and guest download permissions.
* KEY(order_id, product_id, download_id) used for organizing downloads on the My Account page
* woocommerce_order_items - Order line items are stored in a table to make them easily queryable for reports
* woocommerce_order_itemmeta - Order line item meta is stored in a table for storing extra data.
* woocommerce_tax_rates - Tax Rates are stored inside 2 tables making tax queries simple and efficient.
* woocommerce_tax_rate_locations - Each rate can be applied to more than one postcode/city hence the second table.
*/
private static function create_tables() {
global $wpdb;
$wpdb->hide_errors();
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
/**
* Before updating with DBDELTA, remove any primary keys which could be
@ -505,7 +534,7 @@ class WC_Install {
/**
* Get Table schema.
*
* https://github.com/woocommerce/woocommerce/wiki/Database-Description/
* See https://github.com/woocommerce/woocommerce/wiki/Database-Description/
*
* A note on indexes; Indexes have a maximum size of 767 bytes. Historically, we haven't need to be concerned about that.
* As of WordPress 4.2, however, we moved to utf8mb4, which uses 4 bytes per character. This means that an index which
@ -713,56 +742,64 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
}
if ( ! isset( $wp_roles ) ) {
$wp_roles = new WP_Roles();
$wp_roles = new WP_Roles(); // @codingStandardsIgnoreLine
}
// Customer role
add_role( 'customer', __( 'Customer', 'woocommerce' ), array(
'read' => true,
) );
// Customer role.
add_role(
'customer',
__( 'Customer', 'woocommerce' ),
array(
'read' => true,
)
);
// Shop manager role
add_role( 'shop_manager', __( 'Shop manager', 'woocommerce' ), array(
'level_9' => true,
'level_8' => true,
'level_7' => true,
'level_6' => true,
'level_5' => true,
'level_4' => true,
'level_3' => true,
'level_2' => true,
'level_1' => true,
'level_0' => true,
'read' => true,
'read_private_pages' => true,
'read_private_posts' => true,
'edit_users' => true,
'edit_posts' => true,
'edit_pages' => true,
'edit_published_posts' => true,
'edit_published_pages' => true,
'edit_private_pages' => true,
'edit_private_posts' => true,
'edit_others_posts' => true,
'edit_others_pages' => true,
'publish_posts' => true,
'publish_pages' => true,
'delete_posts' => true,
'delete_pages' => true,
'delete_private_pages' => true,
'delete_private_posts' => true,
'delete_published_pages' => true,
'delete_published_posts' => true,
'delete_others_posts' => true,
'delete_others_pages' => true,
'manage_categories' => true,
'manage_links' => true,
'moderate_comments' => true,
'upload_files' => true,
'export' => true,
'import' => true,
'list_users' => true,
) );
// Shop manager role.
add_role(
'shop_manager',
__( 'Shop manager', 'woocommerce' ),
array(
'level_9' => true,
'level_8' => true,
'level_7' => true,
'level_6' => true,
'level_5' => true,
'level_4' => true,
'level_3' => true,
'level_2' => true,
'level_1' => true,
'level_0' => true,
'read' => true,
'read_private_pages' => true,
'read_private_posts' => true,
'edit_users' => true,
'edit_posts' => true,
'edit_pages' => true,
'edit_published_posts' => true,
'edit_published_pages' => true,
'edit_private_pages' => true,
'edit_private_posts' => true,
'edit_others_posts' => true,
'edit_others_pages' => true,
'publish_posts' => true,
'publish_pages' => true,
'delete_posts' => true,
'delete_pages' => true,
'delete_private_pages' => true,
'delete_private_posts' => true,
'delete_published_pages' => true,
'delete_published_posts' => true,
'delete_others_posts' => true,
'delete_others_pages' => true,
'manage_categories' => true,
'manage_links' => true,
'moderate_comments' => true,
'upload_files' => true,
'export' => true,
'import' => true,
'list_users' => true,
)
);
$capabilities = self::get_core_capabilities();
@ -779,7 +816,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
*
* @return array
*/
private static function get_core_capabilities() {
private static function get_core_capabilities() {
$capabilities = array();
$capabilities['core'] = array(
@ -792,7 +829,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
foreach ( $capability_types as $capability_type ) {
$capabilities[ $capability_type ] = array(
// Post type
// Post type.
"edit_{$capability_type}",
"read_{$capability_type}",
"delete_{$capability_type}",
@ -807,7 +844,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
"edit_private_{$capability_type}s",
"edit_published_{$capability_type}s",
// Terms
// Terms.
"manage_{$capability_type}_terms",
"edit_{$capability_type}_terms",
"delete_{$capability_type}_terms",
@ -819,7 +856,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
}
/**
* woocommerce_remove_roles function.
* Remove WooCommerce roles.
*/
public static function remove_roles() {
global $wp_roles;
@ -829,7 +866,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
}
if ( ! isset( $wp_roles ) ) {
$wp_roles = new WP_Roles();
$wp_roles = new WP_Roles(); // @codingStandardsIgnoreLine
}
$capabilities = self::get_core_capabilities();
@ -849,44 +886,45 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
* Create files/directories.
*/
private static function create_files() {
// Bypass if filesystem is read-only and/or non-standard upload system is used
// Bypass if filesystem is read-only and/or non-standard upload system is used.
if ( apply_filters( 'woocommerce_install_skip_create_files', false ) ) {
return;
}
// Install files and folders for uploading files and prevent hotlinking
// Install files and folders for uploading files and prevent hotlinking.
$upload_dir = wp_upload_dir();
$download_method = get_option( 'woocommerce_file_download_method', 'force' );
$files = array(
array(
'base' => $upload_dir['basedir'] . '/woocommerce_uploads',
'file' => 'index.html',
'content' => '',
'base' => $upload_dir['basedir'] . '/woocommerce_uploads',
'file' => 'index.html',
'content' => '',
),
array(
'base' => WC_LOG_DIR,
'file' => '.htaccess',
'content' => 'deny from all',
'base' => WC_LOG_DIR,
'file' => '.htaccess',
'content' => 'deny from all',
),
array(
'base' => WC_LOG_DIR,
'file' => 'index.html',
'content' => '',
'base' => WC_LOG_DIR,
'file' => 'index.html',
'content' => '',
),
);
if ( 'redirect' !== $download_method ) {
$files[] = array(
'base' => $upload_dir['basedir'] . '/woocommerce_uploads',
'file' => '.htaccess',
'content' => 'deny from all',
'base' => $upload_dir['basedir'] . '/woocommerce_uploads',
'file' => '.htaccess',
'content' => 'deny from all',
);
}
foreach ( $files as $file ) {
if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
if ( $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ) ) {
$file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' );
if ( $file_handle ) {
fwrite( $file_handle, $file['content'] );
fclose( $file_handle );
}
@ -897,8 +935,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/**
* Show action links on the plugin screen.
*
* @param mixed $links Plugin Action links
* @return array
* @param mixed $links Plugin Action links.
* @return array
*/
public static function plugin_action_links( $links ) {
$action_links = array(
@ -911,9 +949,9 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/**
* Show row meta on the plugin screen.
*
* @param mixed $links Plugin Row Meta
* @param mixed $file Plugin Base file
* @return array
* @param mixed $links Plugin Row Meta.
* @param mixed $file Plugin Base file.
* @return array
*/
public static function plugin_row_meta( $links, $file ) {
if ( WC_PLUGIN_BASENAME == $file ) {
@ -931,7 +969,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/**
* Uninstall tables when MU blog is deleted.
* @param array $tables
*
* @param array $tables List of tables that will be deleted by WP.
* @return string[]
*/
public static function wpmu_drop_tables( $tables ) {
@ -956,7 +995,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/**
* Get slug from path
* @param string $key
*
* @param string $key Plugin relative path. Example: woocommerce/woocommerce.php.
* @return string
*/
private static function format_plugin_slug( $key ) {
@ -968,8 +1008,10 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/**
* Install a plugin from .org in the background via a cron job (used by
* installer - opt in).
* @param string $plugin_to_install_id
* @param array $plugin_to_install
*
* @param string $plugin_to_install_id Plugin ID.
* @param array $plugin_to_install Plugin information.
* @throws Exception If unable to proceed with plugin installation.
* @since 2.6.0
*/
public static function background_installer( $plugin_to_install_id, $plugin_to_install ) {
@ -977,14 +1019,14 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
wp_clear_scheduled_hook( 'woocommerce_plugin_background_installer', func_get_args() );
if ( ! empty( $plugin_to_install['repo-slug'] ) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
require_once ABSPATH . 'wp-admin/includes/plugin.php';
WP_Filesystem();
$skin = new Automatic_Upgrader_Skin;
$skin = new Automatic_Upgrader_Skin();
$upgrader = new WP_Upgrader( $skin );
$installed_plugins = array_map( array( __CLASS__, 'format_plugin_slug' ), array_keys( get_plugins() ) );
$plugin_slug = $plugin_to_install['repo-slug'];
@ -992,7 +1034,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
$installed = false;
$activate = false;
// See if the plugin is installed already
// See if the plugin is installed already.
if ( in_array( $plugin_to_install['repo-slug'], $installed_plugins ) ) {
$installed = true;
$activate = ! is_plugin_active( $plugin );
@ -1000,28 +1042,31 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
// Install this thing!
if ( ! $installed ) {
// Suppress feedback
// Suppress feedback.
ob_start();
try {
$plugin_information = plugins_api( 'plugin_information', array(
'slug' => $plugin_to_install['repo-slug'],
'fields' => array(
'short_description' => false,
'sections' => false,
'requires' => false,
'rating' => false,
'ratings' => false,
'downloaded' => false,
'last_updated' => false,
'added' => false,
'tags' => false,
'homepage' => false,
'donate_link' => false,
'author_profile' => false,
'author' => false,
),
) );
$plugin_information = plugins_api(
'plugin_information',
array(
'slug' => $plugin_to_install['repo-slug'],
'fields' => array(
'short_description' => false,
'sections' => false,
'requires' => false,
'rating' => false,
'ratings' => false,
'downloaded' => false,
'last_updated' => false,
'added' => false,
'tags' => false,
'homepage' => false,
'donate_link' => false,
'author_profile' => false,
'author' => false,
),
)
);
if ( is_wp_error( $plugin_information ) ) {
throw new Exception( $plugin_information->get_error_message() );
@ -1040,17 +1085,19 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
throw new Exception( $working_dir->get_error_message() );
}
$result = $upgrader->install_package( array(
'source' => $working_dir,
'destination' => WP_PLUGIN_DIR,
'clear_destination' => false,
'abort_if_destination_exists' => false,
'clear_working' => true,
'hook_extra' => array(
'type' => 'plugin',
'action' => 'install',
),
) );
$result = $upgrader->install_package(
array(
'source' => $working_dir,
'destination' => WP_PLUGIN_DIR,
'clear_destination' => false,
'abort_if_destination_exists' => false,
'clear_working' => true,
'hook_extra' => array(
'type' => 'plugin',
'action' => 'install',
),
)
);
if ( is_wp_error( $result ) ) {
throw new Exception( $result->get_error_message() );
@ -1062,6 +1109,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
WC_Admin_Notices::add_custom_notice(
$plugin_to_install_id . '_install_error',
sprintf(
// translators: 1: plugin name, 2: error message, 3: URL to install plugin manually.
__( '%1$s could not be installed (%2$s). <a href="%3$s">Please install it manually by clicking here.</a>', 'woocommerce' ),
$plugin_to_install['name'],
$e->getMessage(),
@ -1070,13 +1118,13 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
);
}
// Discard feedback
// Discard feedback.
ob_end_clean();
}
wp_clean_plugins_cache();
// Activate this thing
// Activate this thing.
if ( $activate ) {
try {
$result = activate_plugin( $plugin );
@ -1088,6 +1136,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
WC_Admin_Notices::add_custom_notice(
$plugin_to_install_id . '_install_error',
sprintf(
// translators: 1: plugin name, 2: URL to WP plugin page.
__( '%1$s was installed but could not be activated. <a href="%2$s">Please activate it manually by clicking here.</a>', 'woocommerce' ),
$plugin_to_install['name'],
admin_url( 'plugins.php' )
@ -1101,7 +1150,8 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
/**
* Install a theme from .org in the background via a cron job (used by installer - opt in).
*
* @param string $theme_slug
* @param string $theme_slug Theme slug.
* @throws Exception If unable to proceed with theme installation.
* @since 3.1.0
*/
public static function theme_background_installer( $theme_slug ) {
@ -1109,25 +1159,27 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
wp_clear_scheduled_hook( 'woocommerce_theme_background_installer', func_get_args() );
if ( ! empty( $theme_slug ) ) {
// Suppress feedback
// Suppress feedback.
ob_start();
try {
$theme = wp_get_theme( $theme_slug );
if ( ! $theme->exists() ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
include_once( ABSPATH . 'wp-admin/includes/theme.php' );
require_once ABSPATH . 'wp-admin/includes/file.php';
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
include_once ABSPATH . 'wp-admin/includes/theme.php';
WP_Filesystem();
$skin = new Automatic_Upgrader_Skin;
$skin = new Automatic_Upgrader_Skin();
$upgrader = new Theme_Upgrader( $skin );
$api = themes_api( 'theme_information', array(
'slug' => $theme_slug,
'fields' => array( 'sections' => false ),
) );
$api = themes_api(
'theme_information', array(
'slug' => $theme_slug,
'fields' => array( 'sections' => false ),
)
);
$result = $upgrader->install( $api->download_link );
if ( is_wp_error( $result ) ) {
@ -1144,6 +1196,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
WC_Admin_Notices::add_custom_notice(
$theme_slug . '_install_error',
sprintf(
// translators: 1: theme slug, 2: error message, 3: URL to install theme manually.
__( '%1$s could not be installed (%2$s). <a href="%3$s">Please install it manually by clicking here.</a>', 'woocommerce' ),
$theme_slug,
$e->getMessage(),
@ -1152,7 +1205,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_termmeta (
);
}
// Discard feedback
// Discard feedback.
ob_end_clean();
}
}

View File

@ -258,7 +258,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
$meta->value = rawurldecode( (string) $meta->value );
$attribute_key = str_replace( 'attribute_', '', $meta->key );
$display_key = wc_attribute_label( $attribute_key, $product );
$display_value = $meta->value;
$display_value = sanitize_text_field( $meta->value );
if ( taxonomy_exists( $attribute_key ) ) {
$term = get_term_by( 'slug', $meta->value, $attribute_key );

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@ class WC_Post_Data {
add_filter( 'post_type_link', array( __CLASS__, 'variation_post_link' ), 10, 2 );
add_action( 'shutdown', array( __CLASS__, 'do_deferred_product_sync' ), 10 );
add_action( 'set_object_terms', array( __CLASS__, 'set_object_terms' ), 10, 6 );
add_action( 'set_object_terms', array( __CLASS__, 'force_default_term' ), 10, 5 );
add_action( 'transition_post_status', array( __CLASS__, 'transition_post_status' ), 10, 3 );
add_action( 'woocommerce_product_set_stock_status', array( __CLASS__, 'delete_product_query_transients' ) );
@ -500,6 +501,27 @@ class WC_Post_Data {
public static function flush_object_meta_cache( $meta_id, $object_id, $meta_key, $meta_value ) {
WC_Cache_Helper::incr_cache_prefix( 'object_' . $object_id );
}
/**
* Ensure default category gets set.
*
* @since 3.3.0
* @param int $object_id Product ID.
* @param array $terms Terms array.
* @param array $tt_ids Term ids array.
* @param string $taxonomy Taxonomy name.
* @param bool $append Are we appending or setting terms.
*/
public static function force_default_term( $object_id, $terms, $tt_ids, $taxonomy, $append ) {
if ( ! $append && 'product_cat' === $taxonomy && empty( $tt_ids ) && 'product' === get_post_type( $object_id ) ) {
$default_term = absint( get_option( 'default_product_cat', 0 ) );
$tt_ids = array_map( 'absint', $tt_ids );
if ( $default_term && ! in_array( $default_term, $tt_ids, true ) ) {
wp_set_post_terms( $object_id, array( $default_term ), 'product_cat', true );
}
}
}
}
WC_Post_Data::init();

View File

@ -29,6 +29,7 @@ class WC_Post_types {
add_action( 'init', array( __CLASS__, 'register_post_status' ), 9 );
add_action( 'init', array( __CLASS__, 'support_jetpack_omnisearch' ) );
add_filter( 'rest_api_allowed_post_types', array( __CLASS__, 'rest_api_allowed_post_types' ) );
add_action( 'woocommerce_after_register_post_type', array( __CLASS__, 'maybe_flush_rewrite_rules' ) );
add_action( 'woocommerce_flush_rewrite_rules', array( __CLASS__, 'flush_rewrite_rules' ) );
}
@ -529,6 +530,18 @@ class WC_Post_types {
}
}
/**
* Flush rules if the event is queued.
*
* @since 3.3.0
*/
public static function maybe_flush_rewrite_rules() {
if ( 'true' === get_option( 'woocommerce_queue_flush_rewrite_rules' ) ) {
delete_option( 'woocommerce_queue_flush_rewrite_rules' );
self::flush_rewrite_rules();
}
}
/**
* Flush rewrite rules.
*/

View File

@ -376,21 +376,21 @@ class WC_Product_Variable extends WC_Product {
if ( ! $this->get_manage_stock() ) {
$this->set_stock_quantity( '' );
$this->set_backorders( 'no' );
$this->set_stock_status( $this->child_is_in_stock() ? 'instock' : 'outofstock' );
$this->data_store->sync_stock_status( $this );
// If backorders are enabled, always in stock.
} elseif ( 'no' !== $this->get_backorders() ) {
$this->set_stock_status( 'instock' );
// If we are stock managing, backorders are allowed, and we don't have stock, force on backorder status.
} elseif ( $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount', 0 ) && 'no' !== $this->get_backorders() ) {
$this->set_stock_status( 'onbackorder' );
// If we are stock managing and we don't have stock, force out of stock status.
} elseif ( $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount' ) ) {
// If we are stock managing and we don't have stock, force out of stock status.
} elseif ( $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount', 0 ) && 'no' === $this->get_backorders() ) {
$this->set_stock_status( 'outofstock' );
// If the stock level is changing and we do now have enough, force in stock status.
} elseif ( $this->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount' ) && array_key_exists( 'stock_quantity', $this->get_changes() ) ) {
// If the stock level is changing and we do now have enough, force in stock status.
} elseif ( $this->get_stock_quantity() > get_option( 'woocommerce_notify_no_stock_amount', 0 ) && array_key_exists( 'stock_quantity', $this->get_changes() ) ) {
$this->set_stock_status( 'instock' );
// Otherwise revert to status the children have.
// Otherwise revert to status the children have.
} else {
$this->set_stock_status( $this->child_is_in_stock() ? 'instock' : 'outofstock' );
}
@ -451,6 +451,16 @@ class WC_Product_Variable extends WC_Product {
return $this->data_store->child_is_in_stock( $this );
}
/**
* Is a child on backorder?
*
* @since 3.3.0
* @return boolean
*/
public function child_is_on_backorder() {
return $this->data_store->child_has_stock_status( $this, 'onbackorder' );
}
/**
* Does a child have a weight set?
* @return boolean

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