Merge branch 'master' of github.com:woothemes/woocommerce
This commit is contained in:
commit
04d7e10982
|
@ -1,4 +1,4 @@
|
|||
# [WooCommerce](http://www.woothemes.com/woocommerce/) [![Built with Grunt](https://cdn.gruntjs.com/builtwith.png)](http://gruntjs.com/) [![Build Status](https://api.travis-ci.org/woothemes/woocommerce.svg?branch=master)](http://travis-ci.org/woothemes/woocommerce) [![Coverage Status](https://img.shields.io/coveralls/woothemes/woocommerce.svg)](https://coveralls.io/r/woothemes/woocommerce)
|
||||
# [WooCommerce](http://www.woothemes.com/woocommerce/) [![Built with Grunt](https://cdn.gruntjs.com/builtwith.png)](http://gruntjs.com/) [![Build Status](https://api.travis-ci.org/woothemes/woocommerce.svg?branch=master)](http://travis-ci.org/woothemes/woocommerce) [![Coverage Status](https://coveralls.io/repos/woothemes/woocommerce/badge.svg?branch=master&service=github)](https://coveralls.io/github/woothemes/woocommerce?branch=master)
|
||||
|
||||
Welcome to the WooCommerce repository on GitHub. Here you can browse the source, look at open issues and keep track of development. We recommend all developers to follow the [WooCommerce development blog](http://develop.woothemes.com/woocommerce/) to stay up to date about everything happening in the project. You can also [follow @DevelopWC](https://twitter.com/DevelopWC) on Twitter for the latest development updates.
|
||||
|
||||
|
|
|
@ -391,7 +391,7 @@ jQuery( function( $ ) {
|
|||
url: woocommerce_admin_meta_boxes_variations.ajax_url,
|
||||
data: data,
|
||||
type: 'POST',
|
||||
success: function() {
|
||||
success: function( response ) {
|
||||
// Allow change page, delete and add new variations
|
||||
need_update.removeClass( 'variation-needs-update' );
|
||||
$( 'button.cancel-variation-changes, button.save-variation-changes' ).attr( 'disabled', 'disabled' );
|
||||
|
@ -399,7 +399,7 @@ jQuery( function( $ ) {
|
|||
$( '#woocommerce-product-data' ).trigger( 'woocommerce_variations_saved' );
|
||||
|
||||
if ( typeof callback === 'function' ) {
|
||||
callback();
|
||||
callback( response );
|
||||
}
|
||||
|
||||
wc_meta_boxes_product_variations_ajax.unblock();
|
||||
|
@ -416,8 +416,15 @@ jQuery( function( $ ) {
|
|||
save_variations: function() {
|
||||
$( '#variable_product_options' ).trigger( 'woocommerce_variations_save_variations_button' );
|
||||
|
||||
wc_meta_boxes_product_variations_ajax.save_changes( function() {
|
||||
var current = $( '#variable_product_options .woocommerce_variations' ).attr( 'data-page' );
|
||||
wc_meta_boxes_product_variations_ajax.save_changes( function( error ) {
|
||||
var wrapper = $( '#variable_product_options .woocommerce_variations' ),
|
||||
current = wrapper.attr( 'data-page' );
|
||||
|
||||
$( '#variable_product_options #woocommerce_errors' ).remove();
|
||||
|
||||
if ( error ) {
|
||||
wrapper.before( error );
|
||||
}
|
||||
|
||||
$( '.variations-defaults select' ).each( function() {
|
||||
$( this ).attr( 'data-current', $( this ).val() );
|
||||
|
@ -666,6 +673,7 @@ jQuery( function( $ ) {
|
|||
break;
|
||||
default :
|
||||
$( 'select.variation_actions' ).trigger( do_variation_action );
|
||||
data = $( 'select.variation_actions' ).triggerHandler( do_variation_action + '_ajax_data', data );
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -520,7 +520,6 @@ jQuery( function( $ ) {
|
|||
|
||||
jQuery( '.add_product_images' ).on( 'click', 'a', function( event ) {
|
||||
var $el = $( this );
|
||||
var attachment_ids = $image_gallery_ids.val();
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
|
@ -549,12 +548,13 @@ jQuery( function( $ ) {
|
|||
// When an image is selected, run a callback.
|
||||
product_gallery_frame.on( 'select', function() {
|
||||
var selection = product_gallery_frame.state().get( 'selection' );
|
||||
var attachment_ids = $image_gallery_ids.val();
|
||||
|
||||
selection.map( function( attachment ) {
|
||||
attachment = attachment.toJSON();
|
||||
|
||||
if ( attachment.id ) {
|
||||
var attachment_ids = attachment_ids ? attachment_ids + ',' + attachment.id : attachment.id;
|
||||
attachment_ids = attachment_ids ? attachment_ids + ',' + attachment.id : attachment.id;
|
||||
var attachment_image = attachment.sizes.thumbnail ? attachment.sizes.thumbnail.url : attachment.url;
|
||||
|
||||
$product_images.append( '<li class="image" data-attachment_id="' + attachment.id + '"><img src="' + attachment_image + '" /><ul class="actions"><li><a href="#" class="delete" title="' + $el.data('delete') + '">' + $el.data('text') + '</a></li></ul></li>' );
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -94,7 +94,8 @@ jQuery( function( $ ) {
|
|||
return {
|
||||
term: term,
|
||||
action: $( this ).data( 'action' ) || 'woocommerce_json_search_products_and_variations',
|
||||
security: wc_enhanced_select_params.search_products_nonce
|
||||
security: wc_enhanced_select_params.search_products_nonce,
|
||||
exclude: $( this ).data( 'exclude' )
|
||||
};
|
||||
},
|
||||
results: function( data ) {
|
||||
|
@ -104,7 +105,9 @@ jQuery( function( $ ) {
|
|||
terms.push( { id: id, text: text } );
|
||||
});
|
||||
}
|
||||
return { results: terms };
|
||||
return {
|
||||
results: terms
|
||||
};
|
||||
},
|
||||
cache: true
|
||||
}
|
||||
|
@ -117,7 +120,10 @@ jQuery( function( $ ) {
|
|||
var selected = [];
|
||||
|
||||
$( element.val().split( ',' ) ).each( function( i, val ) {
|
||||
selected.push( { id: val, text: data[ val ] } );
|
||||
selected.push({
|
||||
id: val,
|
||||
text: data[ val ]
|
||||
});
|
||||
});
|
||||
return callback( selected );
|
||||
};
|
||||
|
@ -127,7 +133,10 @@ jQuery( function( $ ) {
|
|||
} else {
|
||||
select2_args.multiple = false;
|
||||
select2_args.initSelection = function( element, callback ) {
|
||||
var data = {id: element.val(), text: element.attr( 'data-selected' )};
|
||||
var data = {
|
||||
id: element.val(),
|
||||
text: element.attr( 'data-selected' )
|
||||
};
|
||||
return callback( data );
|
||||
};
|
||||
}
|
||||
|
@ -161,7 +170,10 @@ jQuery( function( $ ) {
|
|||
var terms = [];
|
||||
if ( data ) {
|
||||
$.each( data, function( id, text ) {
|
||||
terms.push( { id: id, text: text } );
|
||||
terms.push({
|
||||
id: id,
|
||||
text: text
|
||||
});
|
||||
});
|
||||
}
|
||||
return { results: terms };
|
||||
|
@ -176,7 +188,10 @@ jQuery( function( $ ) {
|
|||
var selected = [];
|
||||
|
||||
$( element.val().split( ',' ) ).each( function( i, val ) {
|
||||
selected.push( { id: val, text: data[ val ] } );
|
||||
selected.push({
|
||||
id: val,
|
||||
text: data[ val ]
|
||||
});
|
||||
});
|
||||
return callback( selected );
|
||||
};
|
||||
|
@ -186,7 +201,10 @@ jQuery( function( $ ) {
|
|||
} else {
|
||||
select2_args.multiple = false;
|
||||
select2_args.initSelection = function( element, callback ) {
|
||||
var data = {id: element.val(), text: element.attr( 'data-selected' )};
|
||||
var data = {
|
||||
id: element.val(),
|
||||
text: element.attr( 'data-selected' )
|
||||
};
|
||||
return callback( data );
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
jQuery(function(a){function b(){var a={formatMatches:function(a){return 1===a?wc_enhanced_select_params.i18n_matches_1:wc_enhanced_select_params.i18n_matches_n.replace("%qty%",a)},formatNoMatches:function(){return wc_enhanced_select_params.i18n_no_matches},formatAjaxError:function(){return wc_enhanced_select_params.i18n_ajax_error},formatInputTooShort:function(a,b){var c=b-a.length;return 1===c?wc_enhanced_select_params.i18n_input_too_short_1:wc_enhanced_select_params.i18n_input_too_short_n.replace("%qty%",c)},formatInputTooLong:function(a,b){var c=a.length-b;return 1===c?wc_enhanced_select_params.i18n_input_too_long_1:wc_enhanced_select_params.i18n_input_too_long_n.replace("%qty%",c)},formatSelectionTooBig:function(a){return 1===a?wc_enhanced_select_params.i18n_selection_too_long_1:wc_enhanced_select_params.i18n_selection_too_long_n.replace("%qty%",a)},formatLoadMore:function(){return wc_enhanced_select_params.i18n_load_more},formatSearching:function(){return wc_enhanced_select_params.i18n_searching}};return a}a(document.body).on("wc-enhanced-select-init",function(){a(":input.wc-enhanced-select, :input.chosen_select").filter(":not(.enhanced)").each(function(){var c=a.extend({minimumResultsForSearch:10,allowClear:a(this).data("allow_clear")?!0:!1,placeholder:a(this).data("placeholder")},b());a(this).select2(c).addClass("enhanced")}),a(":input.wc-enhanced-select-nostd, :input.chosen_select_nostd").filter(":not(.enhanced)").each(function(){var c=a.extend({minimumResultsForSearch:10,allowClear:!0,placeholder:a(this).data("placeholder")},b());a(this).select2(c).addClass("enhanced")}),a(":input.wc-product-search").filter(":not(.enhanced)").each(function(){var c={allowClear:a(this).data("allow_clear")?!0:!1,placeholder:a(this).data("placeholder"),minimumInputLength:a(this).data("minimum_input_length")?a(this).data("minimum_input_length"):"3",escapeMarkup:function(a){return a},ajax:{url:wc_enhanced_select_params.ajax_url,dataType:"json",quietMillis:250,data:function(b){return{term:b,action:a(this).data("action")||"woocommerce_json_search_products_and_variations",security:wc_enhanced_select_params.search_products_nonce}},results:function(b){var c=[];return b&&a.each(b,function(a,b){c.push({id:a,text:b})}),{results:c}},cache:!0}};a(this).data("multiple")===!0?(c.multiple=!0,c.initSelection=function(b,c){var d=a.parseJSON(b.attr("data-selected")),e=[];return a(b.val().split(",")).each(function(a,b){e.push({id:b,text:d[b]})}),c(e)},c.formatSelection=function(a){return'<div class="selected-option" data-id="'+a.id+'">'+a.text+"</div>"}):(c.multiple=!1,c.initSelection=function(a,b){var c={id:a.val(),text:a.attr("data-selected")};return b(c)}),c=a.extend(c,b()),a(this).select2(c).addClass("enhanced")}),a(":input.wc-customer-search").filter(":not(.enhanced)").each(function(){var c={allowClear:a(this).data("allow_clear")?!0:!1,placeholder:a(this).data("placeholder"),minimumInputLength:a(this).data("minimum_input_length")?a(this).data("minimum_input_length"):"3",escapeMarkup:function(a){return a},ajax:{url:wc_enhanced_select_params.ajax_url,dataType:"json",quietMillis:250,data:function(a){return{term:a,action:"woocommerce_json_search_customers",security:wc_enhanced_select_params.search_customers_nonce}},results:function(b){var c=[];return b&&a.each(b,function(a,b){c.push({id:a,text:b})}),{results:c}},cache:!0}};a(this).data("multiple")===!0?(c.multiple=!0,c.initSelection=function(b,c){var d=a.parseJSON(b.attr("data-selected")),e=[];return a(b.val().split(",")).each(function(a,b){e.push({id:b,text:d[b]})}),c(e)},c.formatSelection=function(a){return'<div class="selected-option" data-id="'+a.id+'">'+a.text+"</div>"}):(c.multiple=!1,c.initSelection=function(a,b){var c={id:a.val(),text:a.attr("data-selected")};return b(c)}),c=a.extend(c,b()),a(this).select2(c).addClass("enhanced")})}).on("wc_backbone_modal_before_remove",function(){a(":input.wc-enhanced-select, :input.wc-product-search, :input.wc-customer-search").select2("close")}).trigger("wc-enhanced-select-init")});
|
||||
jQuery(function(a){function b(){var a={formatMatches:function(a){return 1===a?wc_enhanced_select_params.i18n_matches_1:wc_enhanced_select_params.i18n_matches_n.replace("%qty%",a)},formatNoMatches:function(){return wc_enhanced_select_params.i18n_no_matches},formatAjaxError:function(){return wc_enhanced_select_params.i18n_ajax_error},formatInputTooShort:function(a,b){var c=b-a.length;return 1===c?wc_enhanced_select_params.i18n_input_too_short_1:wc_enhanced_select_params.i18n_input_too_short_n.replace("%qty%",c)},formatInputTooLong:function(a,b){var c=a.length-b;return 1===c?wc_enhanced_select_params.i18n_input_too_long_1:wc_enhanced_select_params.i18n_input_too_long_n.replace("%qty%",c)},formatSelectionTooBig:function(a){return 1===a?wc_enhanced_select_params.i18n_selection_too_long_1:wc_enhanced_select_params.i18n_selection_too_long_n.replace("%qty%",a)},formatLoadMore:function(){return wc_enhanced_select_params.i18n_load_more},formatSearching:function(){return wc_enhanced_select_params.i18n_searching}};return a}a(document.body).on("wc-enhanced-select-init",function(){a(":input.wc-enhanced-select, :input.chosen_select").filter(":not(.enhanced)").each(function(){var c=a.extend({minimumResultsForSearch:10,allowClear:a(this).data("allow_clear")?!0:!1,placeholder:a(this).data("placeholder")},b());a(this).select2(c).addClass("enhanced")}),a(":input.wc-enhanced-select-nostd, :input.chosen_select_nostd").filter(":not(.enhanced)").each(function(){var c=a.extend({minimumResultsForSearch:10,allowClear:!0,placeholder:a(this).data("placeholder")},b());a(this).select2(c).addClass("enhanced")}),a(":input.wc-product-search").filter(":not(.enhanced)").each(function(){var c={allowClear:a(this).data("allow_clear")?!0:!1,placeholder:a(this).data("placeholder"),minimumInputLength:a(this).data("minimum_input_length")?a(this).data("minimum_input_length"):"3",escapeMarkup:function(a){return a},ajax:{url:wc_enhanced_select_params.ajax_url,dataType:"json",quietMillis:250,data:function(b){return{term:b,action:a(this).data("action")||"woocommerce_json_search_products_and_variations",security:wc_enhanced_select_params.search_products_nonce,exclude:a(this).data("exclude")}},results:function(b){var c=[];return b&&a.each(b,function(a,b){c.push({id:a,text:b})}),{results:c}},cache:!0}};a(this).data("multiple")===!0?(c.multiple=!0,c.initSelection=function(b,c){var d=a.parseJSON(b.attr("data-selected")),e=[];return a(b.val().split(",")).each(function(a,b){e.push({id:b,text:d[b]})}),c(e)},c.formatSelection=function(a){return'<div class="selected-option" data-id="'+a.id+'">'+a.text+"</div>"}):(c.multiple=!1,c.initSelection=function(a,b){var c={id:a.val(),text:a.attr("data-selected")};return b(c)}),c=a.extend(c,b()),a(this).select2(c).addClass("enhanced")}),a(":input.wc-customer-search").filter(":not(.enhanced)").each(function(){var c={allowClear:a(this).data("allow_clear")?!0:!1,placeholder:a(this).data("placeholder"),minimumInputLength:a(this).data("minimum_input_length")?a(this).data("minimum_input_length"):"3",escapeMarkup:function(a){return a},ajax:{url:wc_enhanced_select_params.ajax_url,dataType:"json",quietMillis:250,data:function(a){return{term:a,action:"woocommerce_json_search_customers",security:wc_enhanced_select_params.search_customers_nonce}},results:function(b){var c=[];return b&&a.each(b,function(a,b){c.push({id:a,text:b})}),{results:c}},cache:!0}};a(this).data("multiple")===!0?(c.multiple=!0,c.initSelection=function(b,c){var d=a.parseJSON(b.attr("data-selected")),e=[];return a(b.val().split(",")).each(function(a,b){e.push({id:b,text:d[b]})}),c(e)},c.formatSelection=function(a){return'<div class="selected-option" data-id="'+a.id+'">'+a.text+"</div>"}):(c.multiple=!1,c.initSelection=function(a,b){var c={id:a.val(),text:a.attr("data-selected")};return b(c)}),c=a.extend(c,b()),a(this).select2(c).addClass("enhanced")})}).on("wc_backbone_modal_before_remove",function(){a(":input.wc-enhanced-select, :input.wc-product-search, :input.wc-customer-search").select2("close")}).trigger("wc-enhanced-select-init")});
|
|
@ -29,6 +29,12 @@
|
|||
return false;
|
||||
} )
|
||||
|
||||
// Reload product variations data
|
||||
.on( 'reload_product_variations', function() {
|
||||
$product_variations = $form.data( 'product_variations' );
|
||||
$use_ajax = $product_variations === false;
|
||||
} )
|
||||
|
||||
// Reset product data
|
||||
.on( 'reset_data', function() {
|
||||
var to_reset = {
|
||||
|
@ -102,7 +108,7 @@
|
|||
data.product_id = $product_id;
|
||||
|
||||
$xhr = $.ajax( {
|
||||
url: wc_cart_fragments_params.wc_ajax_url + 'get_variation/',
|
||||
url: wc_cart_fragments_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_variation' ),
|
||||
type: 'POST',
|
||||
data: data,
|
||||
success: function( variation ) {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -31,7 +31,7 @@ jQuery( function( $ ) {
|
|||
$( document.body ).trigger( 'adding_to_cart', [ $thisbutton, data ] );
|
||||
|
||||
// Ajax action
|
||||
$.post( wc_add_to_cart_params.wc_ajax_url + 'add_to_cart/', data, function( response ) {
|
||||
$.post( wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'add_to_cart' ), data, function( response ) {
|
||||
|
||||
if ( ! response ) {
|
||||
return;
|
||||
|
|
|
@ -1 +1 @@
|
|||
jQuery(function(a){return"undefined"==typeof wc_add_to_cart_params?!1:void a(document).on("click",".add_to_cart_button",function(){var b=a(this);if(b.is(".product_type_simple")){if(!b.attr("data-product_id"))return!0;b.removeClass("added"),b.addClass("loading");var c={};return a.each(b.data(),function(a,b){c[a]=b}),a(document.body).trigger("adding_to_cart",[b,c]),a.post(wc_add_to_cart_params.wc_ajax_url+"add_to_cart/",c,function(c){if(c){var d=window.location.toString();if(d=d.replace("add-to-cart","added-to-cart"),c.error&&c.product_url)return void(window.location=c.product_url);if("yes"===wc_add_to_cart_params.cart_redirect_after_add)return void(window.location=wc_add_to_cart_params.cart_url);b.removeClass("loading");var e=c.fragments,f=c.cart_hash;e&&a.each(e,function(b){a(b).addClass("updating")}),a(".shop_table.cart, .updating, .cart_totals").fadeTo("400","0.6").block({message:null,overlayCSS:{opacity:.6}}),b.addClass("added"),wc_add_to_cart_params.is_cart||0!==b.parent().find(".added_to_cart").size()||b.after(' <a href="'+wc_add_to_cart_params.cart_url+'" class="added_to_cart wc-forward" title="'+wc_add_to_cart_params.i18n_view_cart+'">'+wc_add_to_cart_params.i18n_view_cart+"</a>"),e&&a.each(e,function(b,c){a(b).replaceWith(c)}),a(".widget_shopping_cart, .updating").stop(!0).css("opacity","1").unblock(),a(".shop_table.cart").load(d+" .shop_table.cart:eq(0) > *",function(){a(".shop_table.cart").stop(!0).css("opacity","1").unblock(),a(document.body).trigger("cart_page_refreshed")}),a(".cart_totals").load(d+" .cart_totals:eq(0) > *",function(){a(".cart_totals").stop(!0).css("opacity","1").unblock()}),a(document.body).trigger("added_to_cart",[e,f,b])}}),!1}return!0})});
|
||||
jQuery(function(a){return"undefined"==typeof wc_add_to_cart_params?!1:void a(document).on("click",".add_to_cart_button",function(){var b=a(this);if(b.is(".product_type_simple")){if(!b.attr("data-product_id"))return!0;b.removeClass("added"),b.addClass("loading");var c={};return a.each(b.data(),function(a,b){c[a]=b}),a(document.body).trigger("adding_to_cart",[b,c]),a.post(wc_add_to_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","add_to_cart"),c,function(c){if(c){var d=window.location.toString();if(d=d.replace("add-to-cart","added-to-cart"),c.error&&c.product_url)return void(window.location=c.product_url);if("yes"===wc_add_to_cart_params.cart_redirect_after_add)return void(window.location=wc_add_to_cart_params.cart_url);b.removeClass("loading");var e=c.fragments,f=c.cart_hash;e&&a.each(e,function(b){a(b).addClass("updating")}),a(".shop_table.cart, .updating, .cart_totals").fadeTo("400","0.6").block({message:null,overlayCSS:{opacity:.6}}),b.addClass("added"),wc_add_to_cart_params.is_cart||0!==b.parent().find(".added_to_cart").size()||b.after(' <a href="'+wc_add_to_cart_params.cart_url+'" class="added_to_cart wc-forward" title="'+wc_add_to_cart_params.i18n_view_cart+'">'+wc_add_to_cart_params.i18n_view_cart+"</a>"),e&&a.each(e,function(b,c){a(b).replaceWith(c)}),a(".widget_shopping_cart, .updating").stop(!0).css("opacity","1").unblock(),a(".shop_table.cart").load(d+" .shop_table.cart:eq(0) > *",function(){a(".shop_table.cart").stop(!0).css("opacity","1").unblock(),a(document.body).trigger("cart_page_refreshed")}),a(".cart_totals").load(d+" .cart_totals:eq(0) > *",function(){a(".cart_totals").stop(!0).css("opacity","1").unblock()}),a(document.body).trigger("added_to_cart",[e,f,b])}}),!1}return!0})});
|
|
@ -95,13 +95,23 @@ jQuery( function( $ ) {
|
|||
}
|
||||
}
|
||||
|
||||
if ( key !== 'state' ) {
|
||||
if ( 'state' !== key ) {
|
||||
if ( typeof locale['default'][ key ].hidden === 'undefined' || locale['default'][ key ].hidden === false ) {
|
||||
field.show();
|
||||
} else if ( locale['default'][ key ].hidden === true ) {
|
||||
field.hide().find( 'input' ).val( '' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'postcode' === key ) {
|
||||
if ( locale['default'][ key ].label ) {
|
||||
field.find( 'label' ).html( locale['default'][ key ].label );
|
||||
}
|
||||
|
||||
if ( locale['default'][ key ].placeholder ) {
|
||||
field.find( 'input' ).attr( 'placeholder', locale['default'][ key ].placeholder );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -1 +1 @@
|
|||
jQuery(function(a){function b(a,b){b?(a.find("label").append(' <abbr class="required" title="'+wc_address_i18n_params.i18n_required_text+'">*</abbr>'),a.addClass("validate-required")):(a.find("label abbr").remove(),a.removeClass("validate-required"))}if("undefined"==typeof wc_address_i18n_params)return!1;var c=wc_address_i18n_params.locale.replace(/"/g,'"'),d=a.parseJSON(c);a(document.body).bind("country_to_state_changing",function(c,e,f){var g,h=f;g="undefined"!=typeof d[e]?d[e]:d["default"];var i=h.find("#billing_postcode_field, #shipping_postcode_field"),j=h.find("#billing_city_field, #shipping_city_field"),k=h.find("#billing_state_field, #shipping_state_field");i.attr("data-o_class")||(i.attr("data-o_class",i.attr("class")),j.attr("data-o_class",j.attr("class")),k.attr("data-o_class",k.attr("class"))),g.postcode_before_city?(i.add(j).add(k).removeClass("form-row-first form-row-last").addClass("form-row-first"),j.removeClass("form-row-wide form-row-first").addClass("form-row-last"),i.insertBefore(j)):(i.attr("class",i.attr("data-o_class")),j.attr("class",j.attr("data-o_class")),k.attr("class",k.attr("data-o_class")),i.insertAfter(k));var l=a.parseJSON(wc_address_i18n_params.locale_fields);a.each(l,function(a,c){var e=h.find(c);g[a]?(g[a].label&&e.find("label").html(g[a].label),g[a].placeholder&&e.find("input").attr("placeholder",g[a].placeholder),b(e,!1),"undefined"==typeof g[a].required&&d["default"][a].required===!0?b(e,!0):g[a].required===!0&&b(e,!0),"state"!==a&&(g[a].hidden===!0?e.hide().find("input").val(""):e.show())):d["default"][a]&&(d["default"][a].required===!0&&0===e.find("label abbr").size()&&b(e,!0),"state"!==a&&("undefined"==typeof d["default"][a].hidden||d["default"][a].hidden===!1?e.show():d["default"][a].hidden===!0&&e.hide().find("input").val("")))})})});
|
||||
jQuery(function(a){function b(a,b){b?(a.find("label").append(' <abbr class="required" title="'+wc_address_i18n_params.i18n_required_text+'">*</abbr>'),a.addClass("validate-required")):(a.find("label abbr").remove(),a.removeClass("validate-required"))}if("undefined"==typeof wc_address_i18n_params)return!1;var c=wc_address_i18n_params.locale.replace(/"/g,'"'),d=a.parseJSON(c);a(document.body).bind("country_to_state_changing",function(c,e,f){var g,h=f;g="undefined"!=typeof d[e]?d[e]:d["default"];var i=h.find("#billing_postcode_field, #shipping_postcode_field"),j=h.find("#billing_city_field, #shipping_city_field"),k=h.find("#billing_state_field, #shipping_state_field");i.attr("data-o_class")||(i.attr("data-o_class",i.attr("class")),j.attr("data-o_class",j.attr("class")),k.attr("data-o_class",k.attr("class"))),g.postcode_before_city?(i.add(j).add(k).removeClass("form-row-first form-row-last").addClass("form-row-first"),j.removeClass("form-row-wide form-row-first").addClass("form-row-last"),i.insertBefore(j)):(i.attr("class",i.attr("data-o_class")),j.attr("class",j.attr("data-o_class")),k.attr("class",k.attr("data-o_class")),i.insertAfter(k));var l=a.parseJSON(wc_address_i18n_params.locale_fields);a.each(l,function(a,c){var e=h.find(c);g[a]?(g[a].label&&e.find("label").html(g[a].label),g[a].placeholder&&e.find("input").attr("placeholder",g[a].placeholder),b(e,!1),"undefined"==typeof g[a].required&&d["default"][a].required===!0?b(e,!0):g[a].required===!0&&b(e,!0),"state"!==a&&(g[a].hidden===!0?e.hide().find("input").val(""):e.show())):d["default"][a]&&(d["default"][a].required===!0&&0===e.find("label abbr").size()&&b(e,!0),"state"!==a&&("undefined"==typeof d["default"][a].hidden||d["default"][a].hidden===!1?e.show():d["default"][a].hidden===!0&&e.hide().find("input").val("")),"postcode"===a&&(d["default"][a].label&&e.find("label").html(d["default"][a].label),d["default"][a].placeholder&&e.find("input").attr("placeholder",d["default"][a].placeholder)))})})});
|
|
@ -18,7 +18,7 @@ jQuery( function( $ ) {
|
|||
}
|
||||
|
||||
var $fragment_refresh = {
|
||||
url: wc_cart_fragments_params.wc_ajax_url + 'get_refreshed_fragments/',
|
||||
url: wc_cart_fragments_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_refreshed_fragments' ),
|
||||
type: 'POST',
|
||||
success: function( data ) {
|
||||
if ( data && data.fragments ) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
jQuery(function(a){if("undefined"==typeof wc_cart_fragments_params)return!1;var b;try{b="sessionStorage"in window&&null!==window.sessionStorage,window.sessionStorage.setItem("wc","test"),window.sessionStorage.removeItem("wc")}catch(c){b=!1}var d={url:wc_cart_fragments_params.wc_ajax_url+"get_refreshed_fragments/",type:"POST",success:function(c){c&&c.fragments&&(a.each(c.fragments,function(b,c){a(b).replaceWith(c)}),b&&(sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(c.fragments)),sessionStorage.setItem("wc_cart_hash",c.cart_hash)),a(document.body).trigger("wc_fragments_refreshed"))}};if(b){a(document.body).bind("added_to_cart",function(a,b,c){sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(b)),sessionStorage.setItem("wc_cart_hash",c)});try{var e=a.parseJSON(sessionStorage.getItem(wc_cart_fragments_params.fragment_name)),f=sessionStorage.getItem("wc_cart_hash"),g=a.cookie("woocommerce_cart_hash");if((null===f||void 0===f||""===f)&&(f=""),(null===g||void 0===g||""===g)&&(g=""),!e||!e["div.widget_shopping_cart_content"]||f!==g)throw"No fragment";a.each(e,function(b,c){a(b).replaceWith(c)}),a(document.body).trigger("wc_fragments_loaded")}catch(c){a.ajax(d)}}else a.ajax(d);a.cookie("woocommerce_items_in_cart")>0?a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").show():a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").hide(),a(document.body).bind("adding_to_cart",function(){a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").show()})});
|
||||
jQuery(function(a){if("undefined"==typeof wc_cart_fragments_params)return!1;var b;try{b="sessionStorage"in window&&null!==window.sessionStorage,window.sessionStorage.setItem("wc","test"),window.sessionStorage.removeItem("wc")}catch(c){b=!1}var d={url:wc_cart_fragments_params.wc_ajax_url.toString().replace("%%endpoint%%","get_refreshed_fragments"),type:"POST",success:function(c){c&&c.fragments&&(a.each(c.fragments,function(b,c){a(b).replaceWith(c)}),b&&(sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(c.fragments)),sessionStorage.setItem("wc_cart_hash",c.cart_hash)),a(document.body).trigger("wc_fragments_refreshed"))}};if(b){a(document.body).bind("added_to_cart",function(a,b,c){sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(b)),sessionStorage.setItem("wc_cart_hash",c)});try{var e=a.parseJSON(sessionStorage.getItem(wc_cart_fragments_params.fragment_name)),f=sessionStorage.getItem("wc_cart_hash"),g=a.cookie("woocommerce_cart_hash");if((null===f||void 0===f||""===f)&&(f=""),(null===g||void 0===g||""===g)&&(g=""),!e||!e["div.widget_shopping_cart_content"]||f!==g)throw"No fragment";a.each(e,function(b,c){a(b).replaceWith(c)}),a(document.body).trigger("wc_fragments_loaded")}catch(c){a.ajax(d)}}else a.ajax(d);a.cookie("woocommerce_items_in_cart")>0?a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").show():a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").hide(),a(document.body).bind("adding_to_cart",function(){a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").show()})});
|
|
@ -30,7 +30,7 @@ jQuery( function( $ ) {
|
|||
shipping_method: shipping_methods
|
||||
};
|
||||
|
||||
$.post( wc_cart_params.wc_ajax_url + 'update_shipping_method/', data, function( response ) {
|
||||
$.post( wc_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'update_shipping_method' ), data, function( response ) {
|
||||
$( 'div.cart_totals' ).replaceWith( response );
|
||||
$( document.body ).trigger( 'updated_shipping_method' );
|
||||
});
|
||||
|
|
|
@ -1 +1 @@
|
|||
jQuery(function(a){return"undefined"==typeof wc_cart_params?!1:(a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var b=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){b[a(this).data("index")]=a(this).val()}),a("div.cart_totals").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_cart_params.update_shipping_method_nonce,shipping_method:b};a.post(wc_cart_params.wc_ajax_url+"update_shipping_method/",c,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),void a(".shipping-calculator-form").hide())});
|
||||
jQuery(function(a){return"undefined"==typeof wc_cart_params?!1:(a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var b=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){b[a(this).data("index")]=a(this).val()}),a("div.cart_totals").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_cart_params.update_shipping_method_nonce,shipping_method:b};a.post(wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","update_shipping_method"),c,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),void a(".shipping-calculator-form").hide())});
|
|
@ -241,7 +241,7 @@ jQuery( function( $ ) {
|
|||
|
||||
wc_checkout_form.xhr = $.ajax({
|
||||
type: 'POST',
|
||||
url: wc_checkout_params.wc_ajax_url + 'update_order_review/',
|
||||
url: wc_checkout_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'update_order_review' ),
|
||||
data: data,
|
||||
success: function( data ) {
|
||||
// Always update the fragments
|
||||
|
@ -410,7 +410,7 @@ jQuery( function( $ ) {
|
|||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: wc_checkout_params.wc_ajax_url + 'apply_coupon/',
|
||||
url: wc_checkout_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'apply_coupon' ),
|
||||
data: data,
|
||||
success: function( code ) {
|
||||
$( '.woocommerce-error, .woocommerce-message' ).remove();
|
||||
|
@ -449,7 +449,7 @@ jQuery( function( $ ) {
|
|||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: wc_checkout_params.wc_ajax_url + 'remove_coupon/',
|
||||
url: wc_checkout_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'remove_coupon' ),
|
||||
data: data,
|
||||
success: function( code ) {
|
||||
$( '.woocommerce-error, .woocommerce-message' ).remove();
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -31,7 +31,7 @@ jQuery( function( $ ) {
|
|||
};
|
||||
|
||||
var $geolocate_customer = {
|
||||
url: wc_geolocation_params.wc_ajax_url + 'get_customer_location/',
|
||||
url: wc_geolocation_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'get_customer_location' ),
|
||||
type: 'GET',
|
||||
success: function( response ) {
|
||||
if ( response.success && response.data.hash && response.data.hash !== wc_geolocation_params.hash ) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
jQuery(function(a){var b=window.location.toString(),c=function(){wc_geolocation_params.hash&&a('a[href^="'+wc_geolocation_params.home_url+'"]:not(a[href*="v="]), a[href^="/"]:not(a[href*="v="])').each(function(){var b=a(this),c=b.attr("href");c.indexOf("?")>0?b.attr("href",c+"&v="+wc_geolocation_params.hash):b.attr("href",c+"?v="+wc_geolocation_params.hash)})},d=function(a){b=b.indexOf("?v=")>0||b.indexOf("&v=")>0?b.replace(/v=[^&]+/,"v="+a):b.indexOf("?")>0?b+"&v="+a:b+"?v="+a,window.location=b},e={url:wc_geolocation_params.wc_ajax_url+"get_customer_location/",type:"GET",success:function(a){a.success&&a.data.hash&&a.data.hash!==wc_geolocation_params.hash&&d(a.data.hash)}};"1"!==wc_geolocation_params.is_checkout&&a.ajax(e),a(document.body).on("added_to_cart",function(){c()}),c()});
|
||||
jQuery(function(a){var b=window.location.toString(),c=function(){wc_geolocation_params.hash&&a('a[href^="'+wc_geolocation_params.home_url+'"]:not(a[href*="v="]), a[href^="/"]:not(a[href*="v="])').each(function(){var b=a(this),c=b.attr("href");c.indexOf("?")>0?b.attr("href",c+"&v="+wc_geolocation_params.hash):b.attr("href",c+"?v="+wc_geolocation_params.hash)})},d=function(a){b=b.indexOf("?v=")>0||b.indexOf("&v=")>0?b.replace(/v=[^&]+/,"v="+a):b.indexOf("?")>0?b+"&v="+a:b+"?v="+a,window.location=b},e={url:wc_geolocation_params.wc_ajax_url.toString().replace("%%endpoint%%","get_customer_location"),type:"GET",success:function(a){a.success&&a.data.hash&&a.data.hash!==wc_geolocation_params.hash&&d(a.data.hash)}};"1"!==wc_geolocation_params.is_checkout&&a.ajax(e),a(document.body).on("added_to_cart",function(){c()}),c()});
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -35,9 +35,9 @@ $states['JP'] = array(
|
|||
'JP23' => __( 'Aichi', 'woocommerce' ),
|
||||
'JP24' => __( 'Mie', 'woocommerce' ),
|
||||
'JP25' => __( 'Shiga', 'woocommerce' ),
|
||||
'JP26' => __( 'Kyouto', 'woocommerce' ),
|
||||
'JP26' => __( 'Kyoto', 'woocommerce' ),
|
||||
'JP27' => __( 'Osaka', 'woocommerce' ),
|
||||
'JP28' => __( 'Hyougo', 'woocommerce' ),
|
||||
'JP28' => __( 'Hyogo', 'woocommerce' ),
|
||||
'JP29' => __( 'Nara', 'woocommerce' ),
|
||||
'JP30' => __( 'Wakayama', 'woocommerce' ),
|
||||
'JP31' => __( 'Tottori', 'woocommerce' ),
|
||||
|
|
|
@ -1180,36 +1180,27 @@ abstract class WC_Abstract_Order {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets order total - formatted for display.
|
||||
*
|
||||
* @param string $type
|
||||
* Gets the count of order items of a certain type.
|
||||
*
|
||||
* @param string $item_type
|
||||
* @return string
|
||||
*/
|
||||
public function get_item_count( $type = '' ) {
|
||||
|
||||
if ( empty( $type ) ) {
|
||||
$type = array( 'line_item' );
|
||||
public function get_item_count( $item_type = '' ) {
|
||||
if ( empty( $item_type ) ) {
|
||||
$item_type = array( 'line_item' );
|
||||
}
|
||||
if ( ! is_array( $item_type ) ) {
|
||||
$item_type = array( $item_type );
|
||||
}
|
||||
|
||||
if ( ! is_array( $type ) ) {
|
||||
$type = array( $type );
|
||||
}
|
||||
|
||||
$items = $this->get_items( $type );
|
||||
|
||||
$items = $this->get_items( $item_type );
|
||||
$count = 0;
|
||||
|
||||
foreach ( $items as $item ) {
|
||||
|
||||
if ( ! empty( $item['qty'] ) ) {
|
||||
$count += $item['qty'];
|
||||
} else {
|
||||
$count ++;
|
||||
}
|
||||
$count += empty( $item['qty'] ) ? 1 : $item['qty'];
|
||||
}
|
||||
|
||||
return apply_filters( 'woocommerce_get_item_count', $count, $type, $this );
|
||||
return apply_filters( 'woocommerce_get_item_count', $count, $item_type, $this );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1859,7 +1850,7 @@ abstract class WC_Abstract_Order {
|
|||
if ( 'excl' == $tax_display ) {
|
||||
|
||||
$total_rows[ 'fee_' . $id ] = array(
|
||||
'label' => $fee['name'] . ':',
|
||||
'label' => ( $fee['name'] ? $fee['name'] : __( 'Fee', 'woocommerce' ) ) . ':',
|
||||
'value' => wc_price( $fee['line_total'], array('currency' => $this->get_order_currency()) )
|
||||
);
|
||||
|
||||
|
|
|
@ -192,14 +192,15 @@ class WC_Product {
|
|||
/**
|
||||
* Check if the stock status needs changing
|
||||
*/
|
||||
protected function check_stock_status() {
|
||||
|
||||
// Update stock status
|
||||
public function check_stock_status() {
|
||||
if ( ! $this->backorders_allowed() && $this->get_total_stock() <= get_option( 'woocommerce_notify_no_stock_amount' ) ) {
|
||||
$this->set_stock_status( 'outofstock' );
|
||||
|
||||
if ( $this->stock_status !== 'outofstock' ) {
|
||||
$this->set_stock_status( 'outofstock' );
|
||||
}
|
||||
} elseif ( $this->backorders_allowed() || $this->get_total_stock() > get_option( 'woocommerce_notify_no_stock_amount' ) ) {
|
||||
$this->set_stock_status( 'instock' );
|
||||
if ( $this->stock_status !== 'instock' ) {
|
||||
$this->set_stock_status( 'instock' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -560,7 +561,6 @@ class WC_Product {
|
|||
* @return bool
|
||||
*/
|
||||
public function is_in_stock() {
|
||||
|
||||
if ( $this->managing_stock() && $this->backorders_allowed() ) {
|
||||
return true;
|
||||
} elseif ( $this->managing_stock() && $this->get_total_stock() <= get_option( 'woocommerce_notify_no_stock_amount' ) ) {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Admin Settings API used by Shipping Methods and Payment Gateways
|
||||
*
|
||||
* @class WC_Settings_API
|
||||
* @version 2.3.0
|
||||
* @version 2.4.0
|
||||
* @package WooCommerce/Abstracts
|
||||
* @category Abstract Class
|
||||
* @author WooThemes
|
||||
|
@ -849,12 +849,13 @@ abstract class WC_Settings_API {
|
|||
|
||||
$text = $this->get_option( $key );
|
||||
$field = $this->get_field_key( $key );
|
||||
$value = trim( stripslashes( $_POST[ $field ] ) );
|
||||
|
||||
if ( isset( $_POST[ $field ] ) ) {
|
||||
$text = wc_clean( stripslashes( $_POST[ $field ] ) );
|
||||
$text = wp_kses_post( $value );
|
||||
}
|
||||
|
||||
return $text;
|
||||
return $text === $value ? $text : '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -158,7 +158,7 @@ class WC_Admin_API_Keys_Table_List extends WP_List_Table {
|
|||
return apply_filters( 'woocommerce_api_key_last_access_datetime', $date, $key['last_access'] );
|
||||
}
|
||||
|
||||
return __( 'Unknown' );
|
||||
return __( 'Unknown', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,7 +20,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
class WC_Admin_Meta_Boxes {
|
||||
|
||||
private static $saved_meta_boxes = false;
|
||||
private static $meta_box_errors = array();
|
||||
public static $meta_box_errors = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
/**
|
||||
* Post Types Admin
|
||||
*
|
||||
* @author WooThemes
|
||||
* @category Admin
|
||||
* @package WooCommerce/Admin
|
||||
* @version 2.3.0
|
||||
* @author WooThemes
|
||||
* @category Admin
|
||||
* @package WooCommerce/Admin
|
||||
* @version 2.4.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
|
@ -46,6 +46,9 @@ class WC_Admin_Post_Types {
|
|||
|
||||
add_filter( 'bulk_actions-edit-shop_order', array( $this, 'shop_order_bulk_actions' ) );
|
||||
|
||||
add_filter( 'list_table_primary_column', array( $this, 'list_table_primary_column' ), 10, 2 );
|
||||
add_filter( 'post_row_actions', array( $this, 'row_actions' ), 2, 100 );
|
||||
|
||||
// Views
|
||||
add_filter( 'views_edit-product', array( $this, 'product_sorting_link' ) );
|
||||
|
||||
|
@ -93,6 +96,9 @@ class WC_Admin_Post_Types {
|
|||
|
||||
// Download permissions
|
||||
add_action( 'woocommerce_process_product_file_download_paths', array( $this, 'process_product_file_download_paths' ), 10, 3 );
|
||||
|
||||
// Disable DFW feature pointer
|
||||
add_action( 'admin_footer', array( $this, 'disable_dfw_feature_pointer' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -265,7 +271,8 @@ class WC_Admin_Post_Types {
|
|||
|
||||
/**
|
||||
* Ouput custom columns for products
|
||||
* @param string $column
|
||||
*
|
||||
* @param string $column
|
||||
*/
|
||||
public function render_product_columns( $column ) {
|
||||
global $post, $the_product;
|
||||
|
@ -279,12 +286,10 @@ class WC_Admin_Post_Types {
|
|||
echo '<a href="' . get_edit_post_link( $post->ID ) . '">' . $the_product->get_image( 'thumbnail' ) . '</a>';
|
||||
break;
|
||||
case 'name' :
|
||||
$edit_link = get_edit_post_link( $post->ID );
|
||||
$title = _draft_or_post_title();
|
||||
$post_type_object = get_post_type_object( $post->post_type );
|
||||
$can_edit_post = current_user_can( $post_type_object->cap->edit_post, $post->ID );
|
||||
$edit_link = get_edit_post_link( $post->ID );
|
||||
$title = _draft_or_post_title();
|
||||
|
||||
echo '<strong><a class="row-title" href="' . esc_url( $edit_link ) .'">' . $title.'</a>';
|
||||
echo '<strong><a class="row-title" href="' . esc_url( $edit_link ) .'">' . $title .'</a>';
|
||||
|
||||
_post_states( $post );
|
||||
|
||||
|
@ -299,48 +304,7 @@ class WC_Admin_Post_Types {
|
|||
echo apply_filters( 'the_excerpt', $post->post_excerpt );
|
||||
}
|
||||
|
||||
// Get actions
|
||||
$actions = array();
|
||||
|
||||
$actions['id'] = 'ID: ' . $post->ID;
|
||||
|
||||
if ( $can_edit_post && 'trash' != $post->post_status ) {
|
||||
$actions['edit'] = '<a href="' . get_edit_post_link( $post->ID, true ) . '" title="' . esc_attr( __( 'Edit this item', 'woocommerce' ) ) . '">' . __( 'Edit', 'woocommerce' ) . '</a>';
|
||||
$actions['inline hide-if-no-js'] = '<a href="#" class="editinline" title="' . esc_attr( __( 'Edit this item inline', 'woocommerce' ) ) . '">' . __( 'Quick Edit', 'woocommerce' ) . '</a>';
|
||||
}
|
||||
if ( current_user_can( $post_type_object->cap->delete_post, $post->ID ) ) {
|
||||
if ( 'trash' == $post->post_status ) {
|
||||
$actions['untrash'] = '<a title="' . esc_attr( __( 'Restore this item from the Trash', 'woocommerce' ) ) . '" href="' . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&action=untrash', $post->ID ) ), 'untrash-post_' . $post->ID ) . '">' . __( 'Restore', 'woocommerce' ) . '</a>';
|
||||
} elseif ( EMPTY_TRASH_DAYS ) {
|
||||
$actions['trash'] = '<a class="submitdelete" title="' . esc_attr( __( 'Move this item to the Trash', 'woocommerce' ) ) . '" href="' . get_delete_post_link( $post->ID ) . '">' . __( 'Trash', 'woocommerce' ) . '</a>';
|
||||
}
|
||||
|
||||
if ( 'trash' == $post->post_status || ! EMPTY_TRASH_DAYS ) {
|
||||
$actions['delete'] = '<a class="submitdelete" title="' . esc_attr( __( 'Delete this item permanently', 'woocommerce' ) ) . '" href="' . get_delete_post_link( $post->ID, '', true ) . '">' . __( 'Delete Permanently', 'woocommerce' ) . '</a>';
|
||||
}
|
||||
}
|
||||
if ( $post_type_object->public ) {
|
||||
if ( in_array( $post->post_status, array( 'pending', 'draft', 'future' ) ) ) {
|
||||
if ( $can_edit_post )
|
||||
$actions['view'] = '<a href="' . esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) . '" title="' . esc_attr( sprintf( __( 'Preview “%s”', 'woocommerce' ), $title ) ) . '" rel="permalink">' . __( 'Preview', 'woocommerce' ) . '</a>';
|
||||
} elseif ( 'trash' != $post->post_status ) {
|
||||
$actions['view'] = '<a href="' . get_permalink( $post->ID ) . '" title="' . esc_attr( sprintf( __( 'View “%s”', 'woocommerce' ), $title ) ) . '" rel="permalink">' . __( 'View', 'woocommerce' ) . '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
$actions = apply_filters( 'post_row_actions', $actions, $post );
|
||||
|
||||
echo '<div class="row-actions">';
|
||||
|
||||
$i = 0;
|
||||
$action_count = sizeof( $actions );
|
||||
|
||||
foreach ( $actions as $action => $link ) {
|
||||
++$i;
|
||||
( $i == $action_count ) ? $sep = '' : $sep = ' | ';
|
||||
echo '<span class="' . $action . '">' . $link . $sep . '</span>';
|
||||
}
|
||||
echo '</div>';
|
||||
$this->_render_product_row_actions( $post, $title );
|
||||
|
||||
get_inline_data( $post );
|
||||
|
||||
|
@ -440,57 +404,85 @@ class WC_Admin_Post_Types {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render product row actions for old version of WordPress
|
||||
* Since WordPress 4.3 we don't have to build the row actions
|
||||
*
|
||||
* @param WP_Post $post
|
||||
* @param string $title
|
||||
*/
|
||||
private function _render_product_row_actions( $post, $title ) {
|
||||
global $wp_version;
|
||||
|
||||
if ( version_compare( $wp_version, '4.3-beta', '>=' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$post_type_object = get_post_type_object( $post->post_type );
|
||||
$can_edit_post = current_user_can( $post_type_object->cap->edit_post, $post->ID );
|
||||
|
||||
// Get actions
|
||||
$actions = array();
|
||||
|
||||
$actions['id'] = 'ID: ' . $post->ID;
|
||||
|
||||
if ( $can_edit_post && 'trash' != $post->post_status ) {
|
||||
$actions['edit'] = '<a href="' . get_edit_post_link( $post->ID, true ) . '" title="' . esc_attr( __( 'Edit this item', 'woocommerce' ) ) . '">' . __( 'Edit', 'woocommerce' ) . '</a>';
|
||||
$actions['inline hide-if-no-js'] = '<a href="#" class="editinline" title="' . esc_attr( __( 'Edit this item inline', 'woocommerce' ) ) . '">' . __( 'Quick Edit', 'woocommerce' ) . '</a>';
|
||||
}
|
||||
if ( current_user_can( $post_type_object->cap->delete_post, $post->ID ) ) {
|
||||
if ( 'trash' == $post->post_status ) {
|
||||
$actions['untrash'] = '<a title="' . esc_attr( __( 'Restore this item from the Trash', 'woocommerce' ) ) . '" href="' . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&action=untrash', $post->ID ) ), 'untrash-post_' . $post->ID ) . '">' . __( 'Restore', 'woocommerce' ) . '</a>';
|
||||
} elseif ( EMPTY_TRASH_DAYS ) {
|
||||
$actions['trash'] = '<a class="submitdelete" title="' . esc_attr( __( 'Move this item to the Trash', 'woocommerce' ) ) . '" href="' . get_delete_post_link( $post->ID ) . '">' . __( 'Trash', 'woocommerce' ) . '</a>';
|
||||
}
|
||||
|
||||
if ( 'trash' == $post->post_status || ! EMPTY_TRASH_DAYS ) {
|
||||
$actions['delete'] = '<a class="submitdelete" title="' . esc_attr( __( 'Delete this item permanently', 'woocommerce' ) ) . '" href="' . get_delete_post_link( $post->ID, '', true ) . '">' . __( 'Delete Permanently', 'woocommerce' ) . '</a>';
|
||||
}
|
||||
}
|
||||
if ( $post_type_object->public ) {
|
||||
if ( in_array( $post->post_status, array( 'pending', 'draft', 'future' ) ) ) {
|
||||
if ( $can_edit_post )
|
||||
$actions['view'] = '<a href="' . esc_url( add_query_arg( 'preview', 'true', get_permalink( $post->ID ) ) ) . '" title="' . esc_attr( sprintf( __( 'Preview “%s”', 'woocommerce' ), $title ) ) . '" rel="permalink">' . __( 'Preview', 'woocommerce' ) . '</a>';
|
||||
} elseif ( 'trash' != $post->post_status ) {
|
||||
$actions['view'] = '<a href="' . get_permalink( $post->ID ) . '" title="' . esc_attr( sprintf( __( 'View “%s”', 'woocommerce' ), $title ) ) . '" rel="permalink">' . __( 'View', 'woocommerce' ) . '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
$actions = apply_filters( 'post_row_actions', $actions, $post );
|
||||
|
||||
echo '<div class="row-actions">';
|
||||
|
||||
$i = 0;
|
||||
$action_count = sizeof( $actions );
|
||||
|
||||
foreach ( $actions as $action => $link ) {
|
||||
++$i;
|
||||
( $i == $action_count ) ? $sep = '' : $sep = ' | ';
|
||||
echo '<span class="' . $action . '">' . $link . $sep . '</span>';
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output custom columns for coupons
|
||||
* @param string $column
|
||||
*
|
||||
* @param string $column
|
||||
*/
|
||||
public function render_shop_coupon_columns( $column ) {
|
||||
global $post, $woocommerce;
|
||||
|
||||
switch ( $column ) {
|
||||
case 'coupon_code' :
|
||||
$edit_link = get_edit_post_link( $post->ID );
|
||||
$title = _draft_or_post_title();
|
||||
$post_type_object = get_post_type_object( $post->post_type );
|
||||
$edit_link = get_edit_post_link( $post->ID );
|
||||
$title = _draft_or_post_title();
|
||||
|
||||
echo '<strong><a href="' . esc_attr( $edit_link ) . '" class="row-title">' . esc_html( $title ). '</a></strong>';
|
||||
|
||||
_post_states( $post );
|
||||
|
||||
// Get actions
|
||||
$actions = array();
|
||||
|
||||
if ( current_user_can( $post_type_object->cap->edit_post, $post->ID ) ) {
|
||||
$actions['edit'] = '<a href="' . admin_url( sprintf( $post_type_object->_edit_link . '&action=edit', $post->ID ) ) . '">' . __( 'Edit', 'woocommerce' ) . '</a>';
|
||||
}
|
||||
|
||||
if ( current_user_can( $post_type_object->cap->delete_post, $post->ID ) ) {
|
||||
|
||||
if ( 'trash' == $post->post_status ) {
|
||||
$actions['untrash'] = "<a title='" . esc_attr( __( 'Restore this item from the Trash', 'woocommerce' ) ) . "' href='" . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&action=untrash', $post->ID ) ), 'untrash-post_' . $post->ID ) . "'>" . __( 'Restore', 'woocommerce' ) . "</a>";
|
||||
} elseif ( EMPTY_TRASH_DAYS ) {
|
||||
$actions['trash'] = "<a class='submitdelete' title='" . esc_attr( __( 'Move this item to the Trash', 'woocommerce' ) ) . "' href='" . get_delete_post_link( $post->ID ) . "'>" . __( 'Trash', 'woocommerce' ) . "</a>";
|
||||
}
|
||||
|
||||
if ( 'trash' == $post->post_status || ! EMPTY_TRASH_DAYS ) {
|
||||
$actions['delete'] = "<a class='submitdelete' title='" . esc_attr( __( 'Delete this item permanently', 'woocommerce' ) ) . "' href='" . get_delete_post_link( $post->ID, '', true ) . "'>" . __( 'Delete Permanently', 'woocommerce' ) . "</a>";
|
||||
}
|
||||
}
|
||||
|
||||
$actions = apply_filters( 'post_row_actions', $actions, $post );
|
||||
|
||||
echo '<div class="row-actions">';
|
||||
|
||||
$i = 0;
|
||||
$action_count = sizeof( $actions );
|
||||
|
||||
foreach ( $actions as $action => $link ) {
|
||||
++$i;
|
||||
( $i == $action_count ) ? $sep = '' : $sep = ' | ';
|
||||
echo "<span class='$action'>$link$sep</span>";
|
||||
}
|
||||
echo '</div>';
|
||||
|
||||
$this->_render_shop_coupon_row_actions( $post, $title );
|
||||
break;
|
||||
case 'type' :
|
||||
echo esc_html( wc_get_coupon_type( get_post_meta( $post->ID, 'discount_type', true ) ) );
|
||||
|
@ -543,6 +535,57 @@ class WC_Admin_Post_Types {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render shop_coupon row actions for old version of WordPress
|
||||
* Since WordPress 4.3 we don't have to build the row actions
|
||||
*
|
||||
* @param WP_Post $post
|
||||
* @param string $title
|
||||
*/
|
||||
private function _render_shop_coupon_row_actions( $post, $title ) {
|
||||
global $wp_version;
|
||||
|
||||
if ( version_compare( $wp_version, '4.3-beta', '>=' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$post_type_object = get_post_type_object( $post->post_type );
|
||||
|
||||
// Get actions
|
||||
$actions = array();
|
||||
|
||||
if ( current_user_can( $post_type_object->cap->edit_post, $post->ID ) ) {
|
||||
$actions['edit'] = '<a href="' . admin_url( sprintf( $post_type_object->_edit_link . '&action=edit', $post->ID ) ) . '">' . __( 'Edit', 'woocommerce' ) . '</a>';
|
||||
}
|
||||
|
||||
if ( current_user_can( $post_type_object->cap->delete_post, $post->ID ) ) {
|
||||
|
||||
if ( 'trash' == $post->post_status ) {
|
||||
$actions['untrash'] = "<a title='" . esc_attr( __( 'Restore this item from the Trash', 'woocommerce' ) ) . "' href='" . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&action=untrash', $post->ID ) ), 'untrash-post_' . $post->ID ) . "'>" . __( 'Restore', 'woocommerce' ) . "</a>";
|
||||
} elseif ( EMPTY_TRASH_DAYS ) {
|
||||
$actions['trash'] = "<a class='submitdelete' title='" . esc_attr( __( 'Move this item to the Trash', 'woocommerce' ) ) . "' href='" . get_delete_post_link( $post->ID ) . "'>" . __( 'Trash', 'woocommerce' ) . "</a>";
|
||||
}
|
||||
|
||||
if ( 'trash' == $post->post_status || ! EMPTY_TRASH_DAYS ) {
|
||||
$actions['delete'] = "<a class='submitdelete' title='" . esc_attr( __( 'Delete this item permanently', 'woocommerce' ) ) . "' href='" . get_delete_post_link( $post->ID, '', true ) . "'>" . __( 'Delete Permanently', 'woocommerce' ) . "</a>";
|
||||
}
|
||||
}
|
||||
|
||||
$actions = apply_filters( 'post_row_actions', $actions, $post );
|
||||
|
||||
echo '<div class="row-actions">';
|
||||
|
||||
$i = 0;
|
||||
$action_count = sizeof( $actions );
|
||||
|
||||
foreach ( $actions as $action => $link ) {
|
||||
++$i;
|
||||
( $i == $action_count ) ? $sep = '' : $sep = ' | ';
|
||||
echo "<span class='$action'>$link$sep</span>";
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Output custom columns for coupons
|
||||
* @param string $column
|
||||
|
@ -814,6 +857,58 @@ class WC_Admin_Post_Types {
|
|||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set list table primary column for products and orders
|
||||
* Support for WordPress 4.3
|
||||
*
|
||||
* @param string $default
|
||||
* @param string $screen_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function list_table_primary_column( $default, $screen_id ) {
|
||||
|
||||
if ( 'edit-product' === $screen_id ) {
|
||||
return 'name';
|
||||
}
|
||||
|
||||
if ( 'edit-shop_order' === $screen_id ) {
|
||||
return 'order_title';
|
||||
}
|
||||
|
||||
if ( 'edit-shop_coupon' === $screen_id ) {
|
||||
return 'coupon_code';
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set row actions for products and orders
|
||||
*
|
||||
* @param array $actions
|
||||
* @param WP_Post $post
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function row_actions( $actions, $post ) {
|
||||
if ( 'product' === $post->post_type ) {
|
||||
return array_merge( array( 'id' => 'ID: ' . $post->ID ), $actions );
|
||||
}
|
||||
|
||||
if ( 'shop_order' === $post->post_type ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ( 'shop_coupon' === $post->post_type ) {
|
||||
if ( isset( $actions['inline hide-if-no-js'] ) ) {
|
||||
unset( $actions['inline hide-if-no-js'] );
|
||||
}
|
||||
}
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Product sorting link
|
||||
*
|
||||
|
@ -1560,7 +1655,7 @@ class WC_Admin_Post_Types {
|
|||
break;
|
||||
}
|
||||
|
||||
$output .= " ($term->count)</option>";
|
||||
$output .= '</option>';
|
||||
|
||||
if ( 'simple' == $term->name ) {
|
||||
|
||||
|
@ -2130,6 +2225,18 @@ class WC_Admin_Post_Types {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Disable DFW feature pointer
|
||||
*/
|
||||
public function disable_dfw_feature_pointer() {
|
||||
$screen = get_current_screen();
|
||||
|
||||
if ( 'product' === $screen->id && 'post' === $screen->base ) {
|
||||
remove_action( 'admin_print_footer_scripts', array( 'WP_Internal_Pointers', 'pointer_wp410_dfw' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endif;
|
||||
|
|
|
@ -471,7 +471,7 @@ class WC_Meta_Box_Product_Data {
|
|||
|
||||
<p class="form-field">
|
||||
<label for="upsell_ids"><?php _e( 'Up-Sells', 'woocommerce' ); ?></label>
|
||||
<input type="hidden" class="wc-product-search" style="width: 50%;" id="upsell_ids" name="upsell_ids" data-placeholder="<?php _e( 'Search for a product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products" data-multiple="true" data-selected="<?php
|
||||
<input type="hidden" class="wc-product-search" style="width: 50%;" id="upsell_ids" name="upsell_ids" data-placeholder="<?php _e( 'Search for a product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products" data-multiple="true" data-exclude="<?php echo intval( $post->ID ); ?>" data-selected="<?php
|
||||
$product_ids = array_filter( array_map( 'absint', (array) get_post_meta( $post->ID, '_upsell_ids', true ) ) );
|
||||
$json_ids = array();
|
||||
|
||||
|
@ -488,7 +488,7 @@ class WC_Meta_Box_Product_Data {
|
|||
|
||||
<p class="form-field">
|
||||
<label for="crosssell_ids"><?php _e( 'Cross-Sells', 'woocommerce' ); ?></label>
|
||||
<input type="hidden" class="wc-product-search" style="width: 50%;" id="crosssell_ids" name="crosssell_ids" data-placeholder="<?php _e( 'Search for a product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products" data-multiple="true" data-selected="<?php
|
||||
<input type="hidden" class="wc-product-search" style="width: 50%;" id="crosssell_ids" name="crosssell_ids" data-placeholder="<?php _e( 'Search for a product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products" data-multiple="true" data-exclude="<?php echo intval( $post->ID ); ?>" data-selected="<?php
|
||||
$product_ids = array_filter( array_map( 'absint', (array) get_post_meta( $post->ID, '_crosssell_ids', true ) ) );
|
||||
$json_ids = array();
|
||||
|
||||
|
@ -508,7 +508,7 @@ class WC_Meta_Box_Product_Data {
|
|||
|
||||
<p class="form-field">
|
||||
<label for="parent_id"><?php _e( 'Grouping', 'woocommerce' ); ?></label>
|
||||
<input type="hidden" class="wc-product-search" style="width: 50%;" id="parent_id" name="parent_id" data-placeholder="<?php _e( 'Search for a product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_grouped_products" data-allow_clear="true" data-multiple="false" data-selected="<?php
|
||||
<input type="hidden" class="wc-product-search" style="width: 50%;" id="parent_id" name="parent_id" data-placeholder="<?php _e( 'Search for a product…', 'woocommerce' ); ?>" data-action="woocommerce_json_search_grouped_products" data-allow_clear="true" data-multiple="false" data-exclude="<?php echo intval( $post->ID ); ?>" data-selected="<?php
|
||||
$parent_id = absint( $post->post_parent );
|
||||
|
||||
if ( $parent_id ) {
|
||||
|
@ -643,7 +643,8 @@ class WC_Meta_Box_Product_Data {
|
|||
$options = wc_get_text_attributes( $attribute['value'] );
|
||||
|
||||
foreach ( $options as $option ) {
|
||||
echo '<option ' . selected( $variation_selected_value, $option, false ) . ' value="' . esc_attr( $option ) . '">' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ) . '</option>';
|
||||
$selected = sanitize_title( $variation_selected_value ) === $variation_selected_value ? selected( $variation_selected_value, sanitize_title( $option ), false ) : selected( $variation_selected_value, $option, false );
|
||||
echo '<option ' . $selected . ' value="' . esc_attr( $option ) . '">' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ) . '</option>';
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -881,15 +882,18 @@ class WC_Meta_Box_Product_Data {
|
|||
|
||||
if ( $is_taxonomy ) {
|
||||
|
||||
$values_are_slugs = false;
|
||||
|
||||
if ( isset( $attribute_values[ $i ] ) ) {
|
||||
|
||||
// Select based attributes - Format values (posted values are slugs)
|
||||
if ( is_array( $attribute_values[ $i ] ) ) {
|
||||
$values = array_map( 'sanitize_title', $attribute_values[ $i ] );
|
||||
$values = array_map( 'sanitize_title', $attribute_values[ $i ] );
|
||||
$values_are_slugs = true;
|
||||
|
||||
// Text based attributes - Posted values are term names - don't change to slugs
|
||||
} else {
|
||||
$values = array_map( 'stripslashes', array_map( 'strip_tags', explode( WC_DELIMITER, $attribute_values[ $i ] ) ) );
|
||||
$values = array_map( 'stripslashes', array_map( 'strip_tags', explode( WC_DELIMITER, $attribute_values[ $i ] ) ) );
|
||||
}
|
||||
|
||||
// Remove empty items in the array
|
||||
|
@ -903,7 +907,8 @@ class WC_Meta_Box_Product_Data {
|
|||
if ( taxonomy_exists( $attribute_names[ $i ] ) ) {
|
||||
|
||||
foreach( $values as $key => $value ) {
|
||||
$term = get_term_by( 'name', trim( $value ), $attribute_names[ $i ] );
|
||||
$term = get_term_by( $values_are_slugs ? 'slug' : 'name', trim( $value ), $attribute_names[ $i ] );
|
||||
|
||||
if ( $term ) {
|
||||
$values[ $key ] = intval( $term->term_id );
|
||||
} else {
|
||||
|
@ -1163,7 +1168,10 @@ class WC_Meta_Box_Product_Data {
|
|||
|
||||
// Validate the file exists
|
||||
if ( 'relative' === $file_is ) {
|
||||
$_file_url = '..' === substr( $file_url, 0, 2 ) ? realpath( ABSPATH . $file_url ) : $file_url;
|
||||
$_file_url = $file_url;
|
||||
if ( '..' === substr( $file_url, 0, 2 ) || '/' !== substr( $file_url, 0, 1 ) ) {
|
||||
$_file_url = realpath( ABSPATH . $file_url );
|
||||
}
|
||||
|
||||
if ( ! apply_filters( 'woocommerce_downloadable_file_exists', file_exists( $_file_url ), $file_url ) ) {
|
||||
WC_Admin_Meta_Boxes::add_error( sprintf( __( 'The downloadable file %s cannot be used as it does not exist on the server.', 'woocommerce' ), '<code>' . $file_url . '</code>' ) );
|
||||
|
@ -1205,9 +1213,6 @@ class WC_Meta_Box_Product_Data {
|
|||
|
||||
// Save variations
|
||||
if ( 'variable' == $product_type ) {
|
||||
// Deprecated since WooCommerce 2.4.0 in favor to WC_AJAX::save_variations()
|
||||
// self::save_variations( $post_id, $post );
|
||||
|
||||
// Update parent if variable so price sorting works and stays in sync with the cheapest child
|
||||
WC_Product_Variable::sync( $post_id );
|
||||
}
|
||||
|
@ -1225,7 +1230,6 @@ class WC_Meta_Box_Product_Data {
|
|||
/**
|
||||
* Save meta box data
|
||||
*
|
||||
* @deprecated 2.4.0 Deprecated in favor to WC_AJAX::save_variations()
|
||||
*/
|
||||
public static function save_variations( $post_id, $post ) {
|
||||
global $wpdb;
|
||||
|
@ -1233,7 +1237,6 @@ class WC_Meta_Box_Product_Data {
|
|||
$attributes = (array) maybe_unserialize( get_post_meta( $post_id, '_product_attributes', true ) );
|
||||
|
||||
if ( isset( $_POST['variable_sku'] ) ) {
|
||||
|
||||
$variable_post_id = $_POST['variable_post_id'];
|
||||
$variable_sku = $_POST['variable_sku'];
|
||||
$variable_regular_price = $_POST['variable_regular_price'];
|
||||
|
@ -1273,10 +1276,10 @@ class WC_Meta_Box_Product_Data {
|
|||
$variation_id = absint( $variable_post_id[ $i ] );
|
||||
|
||||
// Checkboxes
|
||||
$is_virtual = isset( $variable_is_virtual[ $i ] ) ? 'yes' : 'no';
|
||||
$is_downloadable = isset( $variable_is_downloadable[ $i ] ) ? 'yes' : 'no';
|
||||
$post_status = isset( $variable_enabled[ $i ] ) ? 'publish' : 'private';
|
||||
$manage_stock = isset( $variable_manage_stock[ $i ] ) ? 'yes' : 'no';
|
||||
$is_virtual = isset( $variable_is_virtual[ $i ] ) ? 'yes' : 'no';
|
||||
$is_downloadable = isset( $variable_is_downloadable[ $i ] ) ? 'yes' : 'no';
|
||||
$post_status = isset( $variable_enabled[ $i ] ) ? 'publish' : 'private';
|
||||
$manage_stock = isset( $variable_manage_stock[ $i ] ) ? 'yes' : 'no';
|
||||
|
||||
// Generate a useful post title
|
||||
$variation_post_title = sprintf( __( 'Variation #%s of %s', 'woocommerce' ), absint( $variation_id ), esc_html( get_the_title( $post_id ) ) );
|
||||
|
@ -1323,7 +1326,7 @@ class WC_Meta_Box_Product_Data {
|
|||
$unique_sku = wc_product_has_unique_sku( $variation_id, $new_sku );
|
||||
|
||||
if ( ! $unique_sku ) {
|
||||
WC_Admin_Meta_Boxes::add_error( __( 'Variation SKU must be unique.', 'woocommerce' ) );
|
||||
WC_Admin_Meta_Boxes::add_error( sprintf( __( '#%s – Variation SKU must be unique.', 'woocommerce' ), $variation_id ) );
|
||||
} else {
|
||||
update_post_meta( $variation_id, '_sku', $new_sku );
|
||||
}
|
||||
|
@ -1443,14 +1446,14 @@ class WC_Meta_Box_Product_Data {
|
|||
$extension = pathinfo( $parsed_url, PATHINFO_EXTENSION );
|
||||
|
||||
if ( ! empty( $extension ) && ! in_array( $file_type['type'], $allowed_file_types ) ) {
|
||||
WC_Admin_Meta_Boxes::add_error( sprintf( __( 'The downloadable file %s cannot be used as it does not have an allowed file type. Allowed types include: %s', 'woocommerce' ), '<code>' . basename( $file_url ) . '</code>', '<code>' . implode( ', ', array_keys( $allowed_file_types ) ) . '</code>' ) );
|
||||
WC_Admin_Meta_Boxes::add_error( sprintf( __( '#%s – The downloadable file %s cannot be used as it does not have an allowed file type. Allowed types include: %s', 'woocommerce' ), $variation_id, '<code>' . basename( $file_url ) . '</code>', '<code>' . implode( ', ', array_keys( $allowed_file_types ) ) . '</code>' ) );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the file exists
|
||||
if ( 'relative' === $file_is && ! apply_filters( 'woocommerce_downloadable_file_exists', file_exists( $file_url ), $file_url ) ) {
|
||||
WC_Admin_Meta_Boxes::add_error( sprintf( __( 'The downloadable file %s cannot be used as it does not exist on the server.', 'woocommerce' ), '<code>' . $file_url . '</code>' ) );
|
||||
WC_Admin_Meta_Boxes::add_error( sprintf( __( '#%s – The downloadable file %s cannot be used as it does not exist on the server.', 'woocommerce' ), $variation_id, '<code>' . $file_url . '</code>' ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1515,12 +1518,15 @@ class WC_Meta_Box_Product_Data {
|
|||
foreach ( $attributes as $attribute ) {
|
||||
|
||||
if ( $attribute['is_variation'] ) {
|
||||
$value = '';
|
||||
|
||||
// Don't use wc_clean as it destroys sanitized characters
|
||||
if ( isset( $_POST[ 'default_attribute_' . sanitize_title( $attribute['name'] ) ] ) ) {
|
||||
$value = sanitize_title( trim( stripslashes( $_POST[ 'default_attribute_' . sanitize_title( $attribute['name'] ) ] ) ) );
|
||||
} else {
|
||||
$value = '';
|
||||
if ( $attribute['is_taxonomy'] ) {
|
||||
// Don't use wc_clean as it destroys sanitized characters
|
||||
$value = sanitize_title( trim( stripslashes( $_POST[ 'default_attribute_' . sanitize_title( $attribute['name'] ) ] ) ) );
|
||||
} else {
|
||||
$value = wc_clean( trim( stripslashes( $_POST[ 'default_attribute_' . sanitize_title( $attribute['name'] ) ] ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $value ) {
|
||||
|
|
|
@ -237,7 +237,7 @@ if ( wc_tax_enabled() ) {
|
|||
<?php if ( wc_tax_enabled() && $order->is_editable() ) : ?>
|
||||
<button type="button" class="button add-order-tax"><?php _e( 'Add Tax', 'woocommerce' ); ?></button>
|
||||
<?php endif; ?>
|
||||
<?php if ( ( $order->get_total() - $order->get_total_refunded() ) > 0 ) : ?>
|
||||
<?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>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
|
@ -261,7 +261,7 @@ if ( wc_tax_enabled() ) {
|
|||
do_action( 'woocommerce_order_item_add_line_buttons', $order );
|
||||
?>
|
||||
</div>
|
||||
<?php if ( ( $order->get_total() - $order->get_total_refunded() ) > 0 ) : ?>
|
||||
<?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" style="display: none;">
|
||||
<table class="wc-order-totals">
|
||||
<tr style="display:none;">
|
||||
|
|
|
@ -45,7 +45,8 @@ extract( $variation_data );
|
|||
$options = wc_get_text_attributes( $attribute['value'] );
|
||||
|
||||
foreach ( $options as $option ) {
|
||||
echo '<option ' . selected( $variation_selected_value, $option, false ) . ' value="' . esc_attr( $option ) . '">' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ) . '</option>';
|
||||
$selected = sanitize_title( $variation_selected_value ) === $variation_selected_value ? selected( $variation_selected_value, sanitize_title( $option ), false ) : selected( $variation_selected_value, $option, false );
|
||||
echo '<option ' . $selected . ' value="' . esc_attr( $option ) . '">' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ) . '</option>';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -389,16 +389,6 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td data-export-label="API Enabled"><?php _e( 'API Enabled', 'woocommerce' ); ?>:</td>
|
||||
<td class="help"><?php echo '<a href="#" class="help_tip" data-tip="' . esc_attr__( 'Does your site have REST API enabled?', 'woocommerce' ) . '">[?]</a>'; ?></td>
|
||||
<td><?php echo 'yes' === get_option( 'woocommerce_api_enabled' ) ? '<mark class="yes">'.'✔'.'</mark>' : '<mark class="no">'.'–'.'</mark>'; ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td data-export-label="API Version"><?php _e( 'API Version', 'woocommerce' ); ?>:</td>
|
||||
<td class="help"><?php echo '<a href="#" class="help_tip" data-tip="' . esc_attr__( 'What version of the REST API does your site use?', 'woocommerce' ) . '">[?]</a>'; ?></td>
|
||||
<td><?php echo WC_API::VERSION ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td data-export-label="Force SSL"><?php _e( 'Force SSL', 'woocommerce' ); ?>:</td>
|
||||
<td class="help"><?php echo '<a href="#" class="help_tip" data-tip="' . esc_attr__( 'Does your site force a SSL Certificate for transactions?', 'woocommerce' ) . '">[?]</a>'; ?></td>
|
||||
|
|
|
@ -226,7 +226,7 @@ class WC_API_Authentication {
|
|||
$server_path = WC()->api->server->path;
|
||||
|
||||
// if the requested URL has a trailingslash, make sure our base URL does as well
|
||||
if ( '/' === substr( $_SERVER['REDIRECT_URL'], -1 ) ) {
|
||||
if ( isset( $_SERVER['REDIRECT_URL'] ) && '/' === substr( $_SERVER['REDIRECT_URL'], -1 ) ) {
|
||||
$server_path .= '/';
|
||||
}
|
||||
|
||||
|
|
|
@ -358,8 +358,17 @@ class WC_API_Coupons extends WC_API_Resource {
|
|||
throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 );
|
||||
}
|
||||
|
||||
$id = wp_update_post( array( 'ID' => intval( $id ), 'post_title' => $coupon_code, 'post_excerpt' => isset( $data['description'] ) ? $data['description'] : '' ) );
|
||||
if ( 0 === $id ) {
|
||||
$updated = wp_update_post( array( 'ID' => intval( $id ), 'post_title' => $coupon_code ) );
|
||||
|
||||
if ( 0 === $updated ) {
|
||||
throw new WC_API_Exception( 'woocommerce_api_cannot_update_coupon', __( 'Failed to update coupon', 'woocommerce' ), 400 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $data['description'] ) ) {
|
||||
$updated = wp_update_post( array( 'ID' => intval( $id ), 'post_excerpt' => $data['description'] ) );
|
||||
|
||||
if ( 0 === $updated ) {
|
||||
throw new WC_API_Exception( 'woocommerce_api_cannot_update_coupon', __( 'Failed to update coupon', 'woocommerce' ), 400 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1467,11 +1467,17 @@ class WC_API_Products extends WC_API_Resource {
|
|||
}
|
||||
|
||||
if ( isset( $_attribute['is_variation'] ) && $_attribute['is_variation'] ) {
|
||||
$attribute_key = 'attribute_' . sanitize_title( $_attribute['name'] );
|
||||
$attribute_value = isset( $attribute['option'] ) ? sanitize_title( stripslashes( $attribute['option'] ) ) : '';
|
||||
$updated_attribute_keys[] = $attribute_key;
|
||||
$_attribute_key = 'attribute_' . sanitize_title( $_attribute['name'] );
|
||||
$updated_attribute_keys[] = $_attribute_key;
|
||||
|
||||
update_post_meta( $variation_id, $attribute_key, $attribute_value );
|
||||
if ( isset( $_attribute['is_taxonomy'] ) && $_attribute['is_taxonomy'] ) {
|
||||
// Don't use wc_clean as it destroys sanitized characters
|
||||
$_attribute_value = isset( $attribute['option'] ) ? sanitize_title( stripslashes( $attribute['option'] ) ) : '';
|
||||
} else {
|
||||
$_attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : '';
|
||||
}
|
||||
|
||||
update_post_meta( $variation_id, $_attribute_key, $_attribute_value );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1512,11 +1518,15 @@ class WC_API_Products extends WC_API_Resource {
|
|||
$_attribute = $attributes[ $taxonomy ];
|
||||
|
||||
if ( $_attribute['is_variation'] ) {
|
||||
// Don't use wc_clean as it destroys sanitized characters
|
||||
$value = '';
|
||||
|
||||
if ( isset( $default_attr['option'] ) ) {
|
||||
$value = sanitize_title( trim( stripslashes( $default_attr['option'] ) ) );
|
||||
} else {
|
||||
$value = '';
|
||||
if ( $_attribute['is_taxonomy'] ) {
|
||||
// Don't use wc_clean as it destroys sanitized characters
|
||||
$value = sanitize_title( trim( stripslashes( $default_attr['option'] ) ) );
|
||||
} else {
|
||||
$value = wc_clean( trim( stripslashes( $default_attr['option'] ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $value ) {
|
||||
|
|
|
@ -358,8 +358,17 @@ class WC_API_Coupons extends WC_API_Resource {
|
|||
throw new WC_API_Exception( 'woocommerce_api_coupon_code_already_exists', __( 'The coupon code already exists', 'woocommerce' ), 400 );
|
||||
}
|
||||
|
||||
$id = wp_update_post( array( 'ID' => intval( $id ), 'post_title' => $coupon_code, 'post_excerpt' => isset( $data['description'] ) ? $data['description'] : '' ) );
|
||||
if ( 0 === $id ) {
|
||||
$updated = wp_update_post( array( 'ID' => intval( $id ), 'post_title' => $coupon_code ) );
|
||||
|
||||
if ( 0 === $updated ) {
|
||||
throw new WC_API_Exception( 'woocommerce_api_cannot_update_coupon', __( 'Failed to update coupon', 'woocommerce' ), 400 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $data['description'] ) ) {
|
||||
$updated = wp_update_post( array( 'ID' => intval( $id ), 'post_excerpt' => $data['description'] ) );
|
||||
|
||||
if ( 0 === $updated ) {
|
||||
throw new WC_API_Exception( 'woocommerce_api_cannot_update_coupon', __( 'Failed to update coupon', 'woocommerce' ), 400 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1467,11 +1467,17 @@ class WC_API_Products extends WC_API_Resource {
|
|||
}
|
||||
|
||||
if ( isset( $_attribute['is_variation'] ) && $_attribute['is_variation'] ) {
|
||||
$attribute_key = 'attribute_' . sanitize_title( $_attribute['name'] );
|
||||
$attribute_value = isset( $attribute['option'] ) ? sanitize_title( stripslashes( $attribute['option'] ) ) : '';
|
||||
$updated_attribute_keys[] = $attribute_key;
|
||||
$_attribute_key = 'attribute_' . sanitize_title( $_attribute['name'] );
|
||||
$updated_attribute_keys[] = $_attribute_key;
|
||||
|
||||
update_post_meta( $variation_id, $attribute_key, $attribute_value );
|
||||
if ( isset( $_attribute['is_taxonomy'] ) && $_attribute['is_taxonomy'] ) {
|
||||
// Don't use wc_clean as it destroys sanitized characters
|
||||
$_attribute_value = isset( $attribute['option'] ) ? sanitize_title( stripslashes( $attribute['option'] ) ) : '';
|
||||
} else {
|
||||
$_attribute_value = isset( $attribute['option'] ) ? wc_clean( stripslashes( $attribute['option'] ) ) : '';
|
||||
}
|
||||
|
||||
update_post_meta( $variation_id, $_attribute_key, $_attribute_value );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1512,11 +1518,15 @@ class WC_API_Products extends WC_API_Resource {
|
|||
$_attribute = $attributes[ $taxonomy ];
|
||||
|
||||
if ( $_attribute['is_variation'] ) {
|
||||
// Don't use wc_clean as it destroys sanitized characters
|
||||
$value = '';
|
||||
|
||||
if ( isset( $default_attr['option'] ) ) {
|
||||
$value = sanitize_title( trim( stripslashes( $default_attr['option'] ) ) );
|
||||
} else {
|
||||
$value = '';
|
||||
if ( $_attribute['is_taxonomy'] ) {
|
||||
// Don't use wc_clean as it destroys sanitized characters
|
||||
$value = sanitize_title( trim( stripslashes( $default_attr['option'] ) ) );
|
||||
} else {
|
||||
$value = wc_clean( trim( stripslashes( $default_attr['option'] ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $value ) {
|
||||
|
|
|
@ -47,7 +47,7 @@ class WC_AJAX {
|
|||
} elseif ( get_option( 'permalink_structure' ) ) {
|
||||
$endpoint = trailingslashit( home_url( '/wc-ajax/' . $request, 'relative' ) );
|
||||
} else {
|
||||
$endpoint = add_query_arg( 'wc-ajax=', $request, trailingslashit( home_url( '', 'relative' ) ) );
|
||||
$endpoint = add_query_arg( $request ? 'wc-ajax' : 'wc-ajax=', $request, trailingslashit( home_url( '', 'relative' ) ) );
|
||||
}
|
||||
return esc_url_raw( $endpoint );
|
||||
}
|
||||
|
@ -59,13 +59,16 @@ class WC_AJAX {
|
|||
global $wp_query;
|
||||
|
||||
if ( ! empty( $_GET['wc-ajax'] ) ) {
|
||||
$wp_query->set( 'wc-ajax', sanitize_text_field( $_GET['wc-ajax'] ) );
|
||||
$wp_query->set( 'wc-ajax', sanitize_text_field( $_GET['wc-ajax'] ) );
|
||||
}
|
||||
|
||||
if ( $action = $wp_query->get( 'wc-ajax' ) ) {
|
||||
if ( ! defined( 'DOING_AJAX' ) ) {
|
||||
define( 'DOING_AJAX', true );
|
||||
}
|
||||
if ( ! defined( 'WC_DOING_AJAX' ) ) {
|
||||
define( 'WC_DOING_AJAX', true );
|
||||
}
|
||||
do_action( 'wc_ajax_' . sanitize_text_field( $action ) );
|
||||
die();
|
||||
}
|
||||
|
@ -872,7 +875,7 @@ class WC_AJAX {
|
|||
$options = explode( WC_DELIMITER, $attribute['value'] );
|
||||
}
|
||||
|
||||
$options = array_map( 'sanitize_title', array_map( 'trim', $options ) );
|
||||
$options = array_map( 'trim', $options );
|
||||
|
||||
$variations[ $attribute_field_name ] = $options;
|
||||
}
|
||||
|
@ -1739,39 +1742,50 @@ class WC_AJAX {
|
|||
|
||||
check_ajax_referer( 'search-products', 'security' );
|
||||
|
||||
$term = (string) wc_clean( stripslashes( $_GET['term'] ) );
|
||||
$term = (string) wc_clean( stripslashes( $_GET['term'] ) );
|
||||
$exclude = array();
|
||||
|
||||
if ( empty( $term ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
if ( ! empty( $_GET['exclude'] ) ) {
|
||||
$exclude = array_map( 'intval', explode( ',', $_GET['exclude'] ) );
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'post_type' => $post_types,
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => -1,
|
||||
's' => $term,
|
||||
'fields' => 'ids'
|
||||
'fields' => 'ids',
|
||||
'exclude' => $exclude
|
||||
);
|
||||
|
||||
if ( is_numeric( $term ) ) {
|
||||
|
||||
$args2 = array(
|
||||
'post_type' => $post_types,
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => -1,
|
||||
'post__in' => array( 0, $term ),
|
||||
'fields' => 'ids'
|
||||
);
|
||||
if ( false === array_search( $term, $exclude ) ) {
|
||||
$posts2 = get_posts( array(
|
||||
'post_type' => $post_types,
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => -1,
|
||||
'post__in' => array( 0, $term ),
|
||||
'fields' => 'ids'
|
||||
) );
|
||||
} else {
|
||||
$posts2 = array();
|
||||
}
|
||||
|
||||
$args3 = array(
|
||||
$posts3 = get_posts( array(
|
||||
'post_type' => $post_types,
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => -1,
|
||||
'post_parent' => $term,
|
||||
'fields' => 'ids'
|
||||
);
|
||||
'fields' => 'ids',
|
||||
'exclude' => $exclude
|
||||
) );
|
||||
|
||||
$args4 = array(
|
||||
$posts4 = get_posts( array(
|
||||
'post_type' => $post_types,
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => -1,
|
||||
|
@ -1782,10 +1796,11 @@ class WC_AJAX {
|
|||
'compare' => 'LIKE'
|
||||
)
|
||||
),
|
||||
'fields' => 'ids'
|
||||
);
|
||||
'fields' => 'ids',
|
||||
'exclude' => $exclude
|
||||
) );
|
||||
|
||||
$posts = array_unique( array_merge( get_posts( $args ), get_posts( $args2 ), get_posts( $args3 ), get_posts( $args4 ) ) );
|
||||
$posts = array_unique( array_merge( get_posts( $args ), $posts2, $posts3, $posts4 ) );
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -1800,7 +1815,8 @@ class WC_AJAX {
|
|||
'compare' => 'LIKE'
|
||||
)
|
||||
),
|
||||
'fields' => 'ids'
|
||||
'fields' => 'ids',
|
||||
'exclude' => $exclude
|
||||
);
|
||||
|
||||
$posts = array_unique( array_merge( get_posts( $args ), get_posts( $args2 ) ) );
|
||||
|
@ -1843,12 +1859,17 @@ class WC_AJAX {
|
|||
|
||||
check_ajax_referer( 'search-products', 'security' );
|
||||
|
||||
$term = (string) wc_clean( stripslashes( $_GET['term'] ) );
|
||||
$term = (string) wc_clean( stripslashes( $_GET['term'] ) );
|
||||
$exclude = array();
|
||||
|
||||
if ( empty( $term ) ) {
|
||||
die();
|
||||
}
|
||||
|
||||
if ( ! empty( $_GET['exclude'] ) ) {
|
||||
$exclude = array_map( 'intval', explode( ',', $_GET['exclude'] ) );
|
||||
}
|
||||
|
||||
$found_products = array();
|
||||
|
||||
if ( $grouped_term = get_term_by( 'slug', 'grouped', 'product_type' ) ) {
|
||||
|
@ -1867,7 +1888,8 @@ class WC_AJAX {
|
|||
'suppress_filters' => 0,
|
||||
'include' => $posts_in,
|
||||
's' => $term,
|
||||
'fields' => 'ids'
|
||||
'fields' => 'ids',
|
||||
'exclude' => $exclude
|
||||
);
|
||||
|
||||
$posts = get_posts( $args );
|
||||
|
@ -1901,7 +1923,12 @@ class WC_AJAX {
|
|||
|
||||
check_ajax_referer( 'search-products', 'security' );
|
||||
|
||||
$term = (string) wc_clean( stripslashes( $_GET['term'] ) );
|
||||
$term = (string) wc_clean( stripslashes( $_GET['term'] ) );
|
||||
$exclude = array();
|
||||
|
||||
if ( ! empty( $_GET['exclude'] ) ) {
|
||||
$exclude = array_map( 'intval', explode( ',', $_GET['exclude'] ) );
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'post_type' => array( 'product', 'product_variation' ),
|
||||
|
@ -1915,7 +1942,8 @@ class WC_AJAX {
|
|||
'value' => 'yes'
|
||||
)
|
||||
),
|
||||
's' => $term
|
||||
's' => $term,
|
||||
'exclude' => $exclude
|
||||
);
|
||||
|
||||
$posts = get_posts( $args );
|
||||
|
@ -2213,7 +2241,10 @@ class WC_AJAX {
|
|||
}
|
||||
}
|
||||
|
||||
if ( $refund_amount == $max_refund ) {
|
||||
// Check if items are refunded fully
|
||||
$max_remaining_items = absint( $order->get_item_count() - $order->get_item_count_refunded() );
|
||||
|
||||
if ( $refund_amount == $max_refund && 0 === $max_remaining_items ) {
|
||||
$order->update_status( apply_filters( 'woocommerce_order_fully_refunded_status', 'refunded', $order_id, $refund->id ) );
|
||||
$response_data['status'] = 'fully_refunded';
|
||||
}
|
||||
|
@ -2499,31 +2530,7 @@ class WC_AJAX {
|
|||
}
|
||||
|
||||
// Add the variation attributes
|
||||
foreach ( $variation_meta as $key => $value ) {
|
||||
if ( 0 !== strpos( $key, 'attribute_' ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre 2.4 handling where 'slugs' were saved instead of the full text attribute.
|
||||
* Attempt to get full version of the text attribute from the parent.
|
||||
*/
|
||||
if ( sanitize_title( $value[0] ) === $value[0] && version_compare( get_post_meta( $product_id, '_product_version', true ), '2.4.0', '<' ) ) {
|
||||
foreach ( $attributes as $attribute ) {
|
||||
if ( $key !== 'attribute_' . sanitize_title( $attribute['name'] ) ) {
|
||||
continue;
|
||||
}
|
||||
$text_attributes = wc_get_text_attributes( $attribute['value'] );
|
||||
|
||||
foreach ( $text_attributes as $text_attribute ) {
|
||||
if ( sanitize_title( $text_attribute ) === $value[0] ) {
|
||||
$value[0] = $text_attribute;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$variation_data[ $key ] = $value[0];
|
||||
}
|
||||
$variation_data = array_merge( $variation_data, wc_get_product_variation_attributes( $variation_id ) );
|
||||
|
||||
// Formatting
|
||||
$variation_data['_regular_price'] = wc_format_localized_price( $variation_data['_regular_price'] );
|
||||
|
@ -2563,313 +2570,30 @@ class WC_AJAX {
|
|||
die( -1 );
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
// Remove previous meta box errors
|
||||
WC_Admin_Meta_Boxes::$meta_box_errors = array();
|
||||
|
||||
$product_id = absint( $_POST['product_id'] );
|
||||
$attributes = (array) maybe_unserialize( get_post_meta( $product_id, '_product_attributes', true ) );
|
||||
|
||||
if ( isset( $_POST['variable_sku'] ) ) {
|
||||
$variable_post_id = $_POST['variable_post_id'];
|
||||
$variable_sku = $_POST['variable_sku'];
|
||||
$variable_regular_price = $_POST['variable_regular_price'];
|
||||
$variable_sale_price = $_POST['variable_sale_price'];
|
||||
$upload_image_id = $_POST['upload_image_id'];
|
||||
$variable_download_limit = $_POST['variable_download_limit'];
|
||||
$variable_download_expiry = $_POST['variable_download_expiry'];
|
||||
$variable_shipping_class = $_POST['variable_shipping_class'];
|
||||
$variable_tax_class = isset( $_POST['variable_tax_class'] ) ? $_POST['variable_tax_class'] : array();
|
||||
$variable_menu_order = $_POST['variation_menu_order'];
|
||||
$variable_sale_price_dates_from = $_POST['variable_sale_price_dates_from'];
|
||||
$variable_sale_price_dates_to = $_POST['variable_sale_price_dates_to'];
|
||||
|
||||
$variable_weight = isset( $_POST['variable_weight'] ) ? $_POST['variable_weight'] : array();
|
||||
$variable_length = isset( $_POST['variable_length'] ) ? $_POST['variable_length'] : array();
|
||||
$variable_width = isset( $_POST['variable_width'] ) ? $_POST['variable_width'] : array();
|
||||
$variable_height = isset( $_POST['variable_height'] ) ? $_POST['variable_height'] : array();
|
||||
$variable_enabled = isset( $_POST['variable_enabled'] ) ? $_POST['variable_enabled'] : array();
|
||||
$variable_is_virtual = isset( $_POST['variable_is_virtual'] ) ? $_POST['variable_is_virtual'] : array();
|
||||
$variable_is_downloadable = isset( $_POST['variable_is_downloadable'] ) ? $_POST['variable_is_downloadable'] : array();
|
||||
|
||||
$variable_manage_stock = isset( $_POST['variable_manage_stock'] ) ? $_POST['variable_manage_stock'] : array();
|
||||
$variable_stock = isset( $_POST['variable_stock'] ) ? $_POST['variable_stock'] : array();
|
||||
$variable_backorders = isset( $_POST['variable_backorders'] ) ? $_POST['variable_backorders'] : array();
|
||||
$variable_stock_status = isset( $_POST['variable_stock_status'] ) ? $_POST['variable_stock_status'] : array();
|
||||
|
||||
$variable_description = isset( $_POST['variable_description'] ) ? $_POST['variable_description'] : array();
|
||||
|
||||
$max_loop = max( array_keys( $_POST['variable_post_id'] ) );
|
||||
|
||||
for ( $i = 0; $i <= $max_loop; $i ++ ) {
|
||||
|
||||
if ( ! isset( $variable_post_id[ $i ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$variation_id = absint( $variable_post_id[ $i ] );
|
||||
|
||||
// Checkboxes
|
||||
$is_virtual = isset( $variable_is_virtual[ $i ] ) ? 'yes' : 'no';
|
||||
$is_downloadable = isset( $variable_is_downloadable[ $i ] ) ? 'yes' : 'no';
|
||||
$post_status = isset( $variable_enabled[ $i ] ) ? 'publish' : 'private';
|
||||
$manage_stock = isset( $variable_manage_stock[ $i ] ) ? 'yes' : 'no';
|
||||
|
||||
// Generate a useful post title
|
||||
$variation_post_title = sprintf( __( 'Variation #%s of %s', 'woocommerce' ), absint( $variation_id ), esc_html( get_the_title( $product_id ) ) );
|
||||
|
||||
// Update or Add post
|
||||
if ( ! $variation_id ) {
|
||||
|
||||
$variation = array(
|
||||
'post_title' => $variation_post_title,
|
||||
'post_content' => '',
|
||||
'post_status' => $post_status,
|
||||
'post_author' => get_current_user_id(),
|
||||
'post_parent' => $product_id,
|
||||
'post_type' => 'product_variation',
|
||||
'menu_order' => $variable_menu_order[ $i ]
|
||||
);
|
||||
|
||||
$variation_id = wp_insert_post( $variation );
|
||||
|
||||
do_action( 'woocommerce_create_product_variation', $variation_id );
|
||||
|
||||
} else {
|
||||
|
||||
$wpdb->update( $wpdb->posts, array( 'post_status' => $post_status, 'post_title' => $variation_post_title, 'menu_order' => $variable_menu_order[ $i ] ), array( 'ID' => $variation_id ) );
|
||||
|
||||
do_action( 'woocommerce_update_product_variation', $variation_id );
|
||||
|
||||
}
|
||||
|
||||
// Only continue if we have a variation ID
|
||||
if ( ! $variation_id ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Unique SKU
|
||||
$sku = get_post_meta( $variation_id, '_sku', true );
|
||||
$new_sku = wc_clean( stripslashes( $variable_sku[ $i ] ) );
|
||||
|
||||
if ( '' == $new_sku ) {
|
||||
update_post_meta( $variation_id, '_sku', '' );
|
||||
} elseif ( $new_sku !== $sku ) {
|
||||
|
||||
if ( ! empty( $new_sku ) ) {
|
||||
$unique_sku = wc_product_has_unique_sku( $variation_id, $new_sku );
|
||||
|
||||
if ( ! $unique_sku ) {
|
||||
WC_Admin_Meta_Boxes::add_error( __( 'Variation SKU must be unique.', 'woocommerce' ) );
|
||||
} else {
|
||||
update_post_meta( $variation_id, '_sku', $new_sku );
|
||||
}
|
||||
} else {
|
||||
update_post_meta( $variation_id, '_sku', '' );
|
||||
}
|
||||
}
|
||||
|
||||
// Update post meta
|
||||
update_post_meta( $variation_id, '_thumbnail_id', absint( $upload_image_id[ $i ] ) );
|
||||
update_post_meta( $variation_id, '_virtual', wc_clean( $is_virtual ) );
|
||||
update_post_meta( $variation_id, '_downloadable', wc_clean( $is_downloadable ) );
|
||||
|
||||
if ( isset( $variable_weight[ $i ] ) ) {
|
||||
update_post_meta( $variation_id, '_weight', ( '' === $variable_weight[ $i ] ) ? '' : wc_format_decimal( $variable_weight[ $i ] ) );
|
||||
}
|
||||
|
||||
if ( isset( $variable_length[ $i ] ) ) {
|
||||
update_post_meta( $variation_id, '_length', ( '' === $variable_length[ $i ] ) ? '' : wc_format_decimal( $variable_length[ $i ] ) );
|
||||
}
|
||||
|
||||
if ( isset( $variable_width[ $i ] ) ) {
|
||||
update_post_meta( $variation_id, '_width', ( '' === $variable_width[ $i ] ) ? '' : wc_format_decimal( $variable_width[ $i ] ) );
|
||||
}
|
||||
|
||||
if ( isset( $variable_height[ $i ] ) ) {
|
||||
update_post_meta( $variation_id, '_height', ( '' === $variable_height[ $i ] ) ? '' : wc_format_decimal( $variable_height[ $i ] ) );
|
||||
}
|
||||
|
||||
// Stock handling
|
||||
update_post_meta( $variation_id, '_manage_stock', $manage_stock );
|
||||
|
||||
// Only update stock status to user setting if changed by the user, but do so before looking at stock levels at variation level
|
||||
if ( ! empty( $variable_stock_status[ $i ] ) ) {
|
||||
wc_update_product_stock_status( $variation_id, $variable_stock_status[ $i ] );
|
||||
}
|
||||
|
||||
if ( 'yes' === $manage_stock ) {
|
||||
update_post_meta( $variation_id, '_backorders', wc_clean( $variable_backorders[ $i ] ) );
|
||||
wc_update_product_stock( $variation_id, wc_stock_amount( $variable_stock[ $i ] ) );
|
||||
} else {
|
||||
delete_post_meta( $variation_id, '_backorders' );
|
||||
delete_post_meta( $variation_id, '_stock' );
|
||||
}
|
||||
|
||||
// Price handling
|
||||
$regular_price = wc_format_decimal( $variable_regular_price[ $i ] );
|
||||
$sale_price = $variable_sale_price[ $i ] === '' ? '' : wc_format_decimal( $variable_sale_price[ $i ] );
|
||||
$date_from = wc_clean( $variable_sale_price_dates_from[ $i ] );
|
||||
$date_to = wc_clean( $variable_sale_price_dates_to[ $i ] );
|
||||
|
||||
update_post_meta( $variation_id, '_regular_price', $regular_price );
|
||||
update_post_meta( $variation_id, '_sale_price', $sale_price );
|
||||
|
||||
// Save Dates
|
||||
update_post_meta( $variation_id, '_sale_price_dates_from', $date_from ? strtotime( $date_from ) : '' );
|
||||
update_post_meta( $variation_id, '_sale_price_dates_to', $date_to ? strtotime( $date_to ) : '' );
|
||||
|
||||
if ( $date_to && ! $date_from ) {
|
||||
update_post_meta( $variation_id, '_sale_price_dates_from', strtotime( 'NOW', current_time( 'timestamp' ) ) );
|
||||
}
|
||||
|
||||
// Update price if on sale
|
||||
if ( '' !== $sale_price && '' === $date_to && '' === $date_from ) {
|
||||
update_post_meta( $variation_id, '_price', $sale_price );
|
||||
} else {
|
||||
update_post_meta( $variation_id, '_price', $regular_price );
|
||||
}
|
||||
|
||||
if ( '' !== $sale_price && $date_from && strtotime( $date_from ) < strtotime( 'NOW', current_time( 'timestamp' ) ) ) {
|
||||
update_post_meta( $variation_id, '_price', $sale_price );
|
||||
}
|
||||
|
||||
if ( $date_to && strtotime( $date_to ) < strtotime( 'NOW', current_time( 'timestamp' ) ) ) {
|
||||
update_post_meta( $variation_id, '_price', $regular_price );
|
||||
update_post_meta( $variation_id, '_sale_price_dates_from', '' );
|
||||
update_post_meta( $variation_id, '_sale_price_dates_to', '' );
|
||||
}
|
||||
|
||||
if ( isset( $variable_tax_class[ $i ] ) && $variable_tax_class[ $i ] !== 'parent' ) {
|
||||
update_post_meta( $variation_id, '_tax_class', wc_clean( $variable_tax_class[ $i ] ) );
|
||||
} else {
|
||||
delete_post_meta( $variation_id, '_tax_class' );
|
||||
}
|
||||
|
||||
if ( 'yes' == $is_downloadable ) {
|
||||
update_post_meta( $variation_id, '_download_limit', wc_clean( $variable_download_limit[ $i ] ) );
|
||||
update_post_meta( $variation_id, '_download_expiry', wc_clean( $variable_download_expiry[ $i ] ) );
|
||||
|
||||
$files = array();
|
||||
$file_names = isset( $_POST['_wc_variation_file_names'][ $variation_id ] ) ? array_map( 'wc_clean', $_POST['_wc_variation_file_names'][ $variation_id ] ) : array();
|
||||
$file_urls = isset( $_POST['_wc_variation_file_urls'][ $variation_id ] ) ? array_map( 'wc_clean', $_POST['_wc_variation_file_urls'][ $variation_id ] ) : array();
|
||||
$file_url_size = sizeof( $file_urls );
|
||||
$allowed_file_types = get_allowed_mime_types();
|
||||
|
||||
for ( $ii = 0; $ii < $file_url_size; $ii ++ ) {
|
||||
if ( ! empty( $file_urls[ $ii ] ) ) {
|
||||
// Find type and file URL
|
||||
if ( 0 === strpos( $file_urls[ $ii ], 'http' ) ) {
|
||||
$file_is = 'absolute';
|
||||
$file_url = esc_url_raw( $file_urls[ $ii ] );
|
||||
} elseif ( '[' === substr( $file_urls[ $ii ], 0, 1 ) && ']' === substr( $file_urls[ $ii ], -1 ) ) {
|
||||
$file_is = 'shortcode';
|
||||
$file_url = wc_clean( $file_urls[ $ii ] );
|
||||
} else {
|
||||
$file_is = 'relative';
|
||||
$file_url = wc_clean( $file_urls[ $ii ] );
|
||||
}
|
||||
|
||||
$file_name = wc_clean( $file_names[ $ii ] );
|
||||
$file_hash = md5( $file_url );
|
||||
|
||||
// Validate the file extension
|
||||
if ( in_array( $file_is, array( 'absolute', 'relative' ) ) ) {
|
||||
$file_type = wp_check_filetype( strtok( $file_url, '?' ) );
|
||||
$parsed_url = parse_url( $file_url, PHP_URL_PATH );
|
||||
$extension = pathinfo( $parsed_url, PATHINFO_EXTENSION );
|
||||
|
||||
if ( ! empty( $extension ) && ! in_array( $file_type['type'], $allowed_file_types ) ) {
|
||||
WC_Admin_Meta_Boxes::add_error( sprintf( __( 'The downloadable file %s cannot be used as it does not have an allowed file type. Allowed types include: %s', 'woocommerce' ), '<code>' . basename( $file_url ) . '</code>', '<code>' . implode( ', ', array_keys( $allowed_file_types ) ) . '</code>' ) );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the file exists
|
||||
if ( 'relative' === $file_is && ! apply_filters( 'woocommerce_downloadable_file_exists', file_exists( $file_url ), $file_url ) ) {
|
||||
WC_Admin_Meta_Boxes::add_error( sprintf( __( 'The downloadable file %s cannot be used as it does not exist on the server.', 'woocommerce' ), '<code>' . $file_url . '</code>' ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
$files[ $file_hash ] = array(
|
||||
'name' => $file_name,
|
||||
'file' => $file_url
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// grant permission to any newly added files on any existing orders for this product prior to saving
|
||||
do_action( 'woocommerce_process_product_file_download_paths', $product_id, $variation_id, $files );
|
||||
|
||||
update_post_meta( $variation_id, '_downloadable_files', $files );
|
||||
} else {
|
||||
update_post_meta( $variation_id, '_download_limit', '' );
|
||||
update_post_meta( $variation_id, '_download_expiry', '' );
|
||||
update_post_meta( $variation_id, '_downloadable_files', '' );
|
||||
}
|
||||
|
||||
update_post_meta( $variation_id, '_variation_description', wp_kses_post( $variable_description[ $i ] ) );
|
||||
|
||||
// Save shipping class
|
||||
$variable_shipping_class[ $i ] = ! empty( $variable_shipping_class[ $i ] ) ? (int) $variable_shipping_class[ $i ] : '';
|
||||
wp_set_object_terms( $variation_id, $variable_shipping_class[ $i ], 'product_shipping_class');
|
||||
|
||||
// Update Attributes
|
||||
$updated_attribute_keys = array();
|
||||
foreach ( $attributes as $attribute ) {
|
||||
if ( $attribute['is_variation'] ) {
|
||||
$attribute_key = 'attribute_' . sanitize_title( $attribute['name'] );
|
||||
$updated_attribute_keys[] = $attribute_key;
|
||||
|
||||
if ( $attribute['is_taxonomy'] ) {
|
||||
// Don't use wc_clean as it destroys sanitized characters
|
||||
$value = isset( $_POST[ $attribute_key ][ $i ] ) ? sanitize_title( stripslashes( $_POST[ $attribute_key ][ $i ] ) ) : '';
|
||||
} else {
|
||||
$value = isset( $_POST[ $attribute_key ][ $i ] ) ? wc_clean( stripslashes( $_POST[ $attribute_key ][ $i ] ) ) : '';
|
||||
}
|
||||
|
||||
update_post_meta( $variation_id, $attribute_key, $value );
|
||||
}
|
||||
}
|
||||
|
||||
// Remove old taxonomies attributes so data is kept up to date - first get attribute key names
|
||||
$delete_attribute_keys = $wpdb->get_col( $wpdb->prepare( "SELECT meta_key FROM {$wpdb->postmeta} WHERE meta_key LIKE 'attribute_%%' AND meta_key NOT IN ( '" . implode( "','", $updated_attribute_keys ) . "' ) AND post_id = %d;", $variation_id ) );
|
||||
|
||||
foreach ( $delete_attribute_keys as $key ) {
|
||||
delete_post_meta( $variation_id, $key );
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_save_product_variation', $variation_id, $i );
|
||||
}
|
||||
}
|
||||
|
||||
// Update parent if variable so price sorting works and stays in sync with the cheapest child
|
||||
WC_Product_Variable::sync( $product_id );
|
||||
|
||||
// Update default attribute options setting
|
||||
$default_attributes = array();
|
||||
|
||||
foreach ( $attributes as $attribute ) {
|
||||
|
||||
if ( $attribute['is_variation'] ) {
|
||||
|
||||
// Don't use wc_clean as it destroys sanitized characters
|
||||
if ( isset( $_POST[ 'default_attribute_' . sanitize_title( $attribute['name'] ) ] ) ) {
|
||||
$value = sanitize_title( trim( stripslashes( $_POST[ 'default_attribute_' . sanitize_title( $attribute['name'] ) ] ) ) );
|
||||
} else {
|
||||
$value = '';
|
||||
}
|
||||
|
||||
if ( $value ) {
|
||||
$default_attributes[ sanitize_title( $attribute['name'] ) ] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_post_meta( $product_id, '_default_attributes', $default_attributes );
|
||||
WC_Meta_Box_Product_Data::save_variations( $product_id, get_post( $product_id ) );
|
||||
|
||||
do_action( 'woocommerce_ajax_save_product_variations', $product_id );
|
||||
|
||||
// Clear cache/transients
|
||||
wc_delete_product_transients( $product_id );
|
||||
|
||||
if ( $errors = WC_Admin_Meta_Boxes::$meta_box_errors ) {
|
||||
echo '<div id="woocommerce_errors" class="error">';
|
||||
|
||||
foreach ( $errors as $error ) {
|
||||
echo '<p>' . wp_kses_post( $error ) . '</p>';
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
|
||||
delete_option( 'woocommerce_meta_box_errors' );
|
||||
}
|
||||
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1746,7 +1746,7 @@ class WC_Cart {
|
|||
$discount_amount += $this->get_coupon_discount_tax_amount( $code );
|
||||
}
|
||||
|
||||
return round( $discount_amount, $this->dp, WC_DISCOUNT_ROUNDING_MODE );
|
||||
return wc_cart_round_discount( $discount_amount, $this->dp );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1756,7 +1756,7 @@ class WC_Cart {
|
|||
* @return float discount amount
|
||||
*/
|
||||
public function get_coupon_discount_tax_amount( $code ) {
|
||||
return round( isset( $this->coupon_discount_tax_amounts[ $code ] ) ? $this->coupon_discount_tax_amounts[ $code ] : 0, $this->dp, WC_DISCOUNT_ROUNDING_MODE );
|
||||
return wc_cart_round_discount( isset( $this->coupon_discount_tax_amounts[ $code ] ) ? $this->coupon_discount_tax_amounts[ $code ] : 0, $this->dp );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2156,7 +2156,7 @@ class WC_Cart {
|
|||
* @return float
|
||||
*/
|
||||
public function get_cart_discount_total() {
|
||||
return round( $this->discount_cart, $this->dp, WC_DISCOUNT_ROUNDING_MODE );
|
||||
return wc_cart_round_discount( $this->discount_cart, $this->dp );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2165,7 +2165,7 @@ class WC_Cart {
|
|||
* @return float
|
||||
*/
|
||||
public function get_cart_discount_tax_total() {
|
||||
return round( $this->discount_cart_tax, $this->dp, WC_DISCOUNT_ROUNDING_MODE );
|
||||
return wc_cart_round_discount( $this->discount_cart_tax, $this->dp );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -143,14 +143,13 @@ class WC_Download_Handler {
|
|||
|
||||
/**
|
||||
* Log the download + increase counts
|
||||
* @param object $download_data
|
||||
* @access private
|
||||
* @param object $download_data
|
||||
*/
|
||||
private static function count_download( $download_data ) {
|
||||
public static function count_download( $download_data ) {
|
||||
global $wpdb;
|
||||
|
||||
$wpdb->update(
|
||||
$wpdb->prefix . "woocommerce_downloadable_product_permissions",
|
||||
$wpdb->prefix . 'woocommerce_downloadable_product_permissions',
|
||||
array(
|
||||
'download_count' => $download_data->download_count + 1,
|
||||
'downloads_remaining' => $download_data->downloads_remaining > 0 ? $download_data->downloads_remaining - 1 : $download_data->downloads_remaining,
|
||||
|
@ -247,19 +246,17 @@ class WC_Download_Handler {
|
|||
public static function download_file_xsendfile( $file_path, $filename ) {
|
||||
$parsed_file_path = self::parse_file_path( $file_path );
|
||||
|
||||
extract( $parsed_file_path );
|
||||
|
||||
if ( function_exists( 'apache_get_modules' ) && in_array( 'mod_xsendfile', apache_get_modules() ) ) {
|
||||
self::download_headers( $file_path, $filename );
|
||||
header( "X-Sendfile: $file_path" );
|
||||
self::download_headers( $parsed_file_path['file_path'], $filename );
|
||||
header( "X-Sendfile: " . $parsed_file_path['file_path'] );
|
||||
exit;
|
||||
} elseif ( stristr( getenv( 'SERVER_SOFTWARE' ), 'lighttpd' ) ) {
|
||||
self::download_headers( $file_path, $filename );
|
||||
header( "X-Lighttpd-Sendfile: $file_path" );
|
||||
self::download_headers( $parsed_file_path['file_path'], $filename );
|
||||
header( "X-Lighttpd-Sendfile: " . $parsed_file_path['file_path'] );
|
||||
exit;
|
||||
} elseif ( stristr( getenv( 'SERVER_SOFTWARE' ), 'nginx' ) || stristr( getenv( 'SERVER_SOFTWARE' ), 'cherokee' ) ) {
|
||||
self::download_headers( $file_path, $filename );
|
||||
$xsendfile_path = trim( preg_replace( '`^' . str_replace( '\\', '/', getcwd() ) . '`', '', $file_path ), '/' );
|
||||
self::download_headers( $parsed_file_path['file_path'], $filename );
|
||||
$xsendfile_path = trim( preg_replace( '`^' . str_replace( '\\', '/', getcwd() ) . '`', '', $parsed_file_path['file_path'] ), '/' );
|
||||
header( "X-Accel-Redirect: /$xsendfile_path" );
|
||||
exit;
|
||||
}
|
||||
|
@ -276,12 +273,10 @@ class WC_Download_Handler {
|
|||
public static function download_file_force( $file_path, $filename ) {
|
||||
$parsed_file_path = self::parse_file_path( $file_path );
|
||||
|
||||
extract( $parsed_file_path );
|
||||
self::download_headers( $parsed_file_path['file_path'], $filename );
|
||||
|
||||
self::download_headers( $file_path, $filename );
|
||||
|
||||
if ( ! self::readfile_chunked( $file_path ) ) {
|
||||
if ( $remote_file ) {
|
||||
if ( ! self::readfile_chunked( $parsed_file_path['file_path'] ) ) {
|
||||
if ( $parsed_file_path['remote_file'] ) {
|
||||
self::download_file_redirect( $file_path );
|
||||
} else {
|
||||
self::download_error( __( 'File not found', 'woocommerce' ) );
|
||||
|
|
|
@ -622,20 +622,6 @@ class WC_Form_Handler {
|
|||
|
||||
// Allow if valid
|
||||
if ( '' === $valid_value || $valid_value === $value ) {
|
||||
|
||||
// Pre 2.4 handling where 'slugs' were saved instead of the full text attribute
|
||||
if ( ! $attribute['is_taxonomy'] ) {
|
||||
if ( $value === sanitize_title( $value ) && version_compare( get_post_meta( $product_id, '_product_version', true ), '2.4.0', '<' ) ) {
|
||||
$text_attributes = wc_get_text_attributes( $attribute['value'] );
|
||||
foreach ( $text_attributes as $text_attribute ) {
|
||||
if ( sanitize_title( $text_attribute ) === $value ) {
|
||||
$value = $text_attribute;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$variations[ $taxonomy ] = $value;
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -198,12 +198,12 @@ class WC_Frontend_Scripts {
|
|||
case 'woocommerce' :
|
||||
return array(
|
||||
'ajax_url' => WC()->ajax_url(),
|
||||
'wc_ajax_url' => WC_AJAX::get_endpoint()
|
||||
'wc_ajax_url' => WC_AJAX::get_endpoint( "%%endpoint%%" )
|
||||
);
|
||||
break;
|
||||
case 'wc-geolocation' :
|
||||
return array(
|
||||
'wc_ajax_url' => WC_AJAX::get_endpoint(),
|
||||
'wc_ajax_url' => WC_AJAX::get_endpoint( "%%endpoint%%" ),
|
||||
'home_url' => home_url(),
|
||||
'is_checkout' => is_checkout() ? '1' : '0',
|
||||
'hash' => isset( $_GET['v'] ) ? wc_clean( $_GET['v'] ) : ''
|
||||
|
@ -218,7 +218,7 @@ class WC_Frontend_Scripts {
|
|||
case 'wc-checkout' :
|
||||
return array(
|
||||
'ajax_url' => WC()->ajax_url(),
|
||||
'wc_ajax_url' => WC_AJAX::get_endpoint(),
|
||||
'wc_ajax_url' => WC_AJAX::get_endpoint( "%%endpoint%%" ),
|
||||
'update_order_review_nonce' => wp_create_nonce( 'update-order-review' ),
|
||||
'apply_coupon_nonce' => wp_create_nonce( 'apply-coupon' ),
|
||||
'remove_coupon_nonce' => wp_create_nonce( 'remove-coupon' ),
|
||||
|
@ -239,21 +239,21 @@ class WC_Frontend_Scripts {
|
|||
case 'wc-cart' :
|
||||
return array(
|
||||
'ajax_url' => WC()->ajax_url(),
|
||||
'wc_ajax_url' => WC_AJAX::get_endpoint(),
|
||||
'wc_ajax_url' => WC_AJAX::get_endpoint( "%%endpoint%%" ),
|
||||
'update_shipping_method_nonce' => wp_create_nonce( "update-shipping-method" ),
|
||||
);
|
||||
break;
|
||||
case 'wc-cart-fragments' :
|
||||
return array(
|
||||
'ajax_url' => WC()->ajax_url(),
|
||||
'wc_ajax_url' => WC_AJAX::get_endpoint(),
|
||||
'wc_ajax_url' => WC_AJAX::get_endpoint( "%%endpoint%%" ),
|
||||
'fragment_name' => apply_filters( 'woocommerce_cart_fragment_name', 'wc_fragments' )
|
||||
);
|
||||
break;
|
||||
case 'wc-add-to-cart' :
|
||||
return array(
|
||||
'ajax_url' => WC()->ajax_url(),
|
||||
'wc_ajax_url' => WC_AJAX::get_endpoint(),
|
||||
'wc_ajax_url' => WC_AJAX::get_endpoint( "%%endpoint%%" ),
|
||||
'i18n_view_cart' => esc_attr__( 'View Cart', 'woocommerce' ),
|
||||
'cart_url' => apply_filters( 'woocommerce_add_to_cart_redirect', WC()->cart->get_cart_url() ),
|
||||
'is_cart' => is_cart(),
|
||||
|
|
|
@ -140,6 +140,48 @@ class WC_Order extends WC_Abstract_Order {
|
|||
return abs( $total );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the count of order items of a certain type that have been refunded.
|
||||
* @since 2.4.0
|
||||
* @param string $item_type
|
||||
* @return string
|
||||
*/
|
||||
public function get_item_count_refunded( $item_type = '' ) {
|
||||
if ( empty( $item_type ) ) {
|
||||
$item_type = array( 'line_item' );
|
||||
}
|
||||
if ( ! is_array( $item_type ) ) {
|
||||
$item_type = array( $item_type );
|
||||
}
|
||||
$count = 0;
|
||||
|
||||
foreach ( $this->get_refunds() as $refund ) {
|
||||
foreach ( $refund->get_items( $item_type ) as $refunded_item ) {
|
||||
$count += empty( $refunded_item['qty'] ) ? 0 : $refunded_item['qty'];
|
||||
}
|
||||
}
|
||||
|
||||
return apply_filters( 'woocommerce_get_item_count_refunded', $count, $item_type, $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total number of items refunded.
|
||||
*
|
||||
* @since 2.4.0
|
||||
* @param int $item_id ID of the item we're checking
|
||||
* @param string $item_type type of the item we're checking, if not a line_item
|
||||
* @return integer
|
||||
*/
|
||||
public function get_total_qty_refunded( $item_type = 'line_item' ) {
|
||||
$qty = 0;
|
||||
foreach ( $this->get_refunds() as $refund ) {
|
||||
foreach ( $refund->get_items( $item_type ) as $refunded_item ) {
|
||||
$qty += $refunded_item['qty'];
|
||||
}
|
||||
}
|
||||
return $qty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the refunded amount for a line item
|
||||
*
|
||||
|
|
|
@ -75,7 +75,11 @@ class WC_Payment_Gateways {
|
|||
|
||||
if ( 'US' === WC()->countries->get_base_country() ) {
|
||||
if ( class_exists( 'WC_Subscriptions_Order' ) || class_exists( 'WC_Pre_Orders_Order' ) ) {
|
||||
$load_gateways[] = 'WC_Addons_Gateway_Simplify_Commerce';
|
||||
if ( ! function_exists( 'wcs_create_renewal_order' ) ) { // Subscriptions < 2.0
|
||||
$load_gateways[] = 'WC_Addons_Gateway_Simplify_Commerce_Deprecated';
|
||||
} else {
|
||||
$load_gateways[] = 'WC_Addons_Gateway_Simplify_Commerce';
|
||||
}
|
||||
} else {
|
||||
$load_gateways[] = 'WC_Gateway_Simplify_Commerce';
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ class WC_Post_Data {
|
|||
add_filter( 'update_post_metadata', array( __CLASS__, 'update_post_metadata' ), 10, 5 );
|
||||
add_filter( 'wp_insert_post_data', array( __CLASS__, 'wp_insert_post_data' ) );
|
||||
add_action( 'pre_post_update', array( __CLASS__, 'pre_post_update' ) );
|
||||
add_action( 'update_post_meta', array( __CLASS__, 'sync_product_stock_status' ), 10, 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -160,6 +161,20 @@ class WC_Post_Data {
|
|||
return $check;
|
||||
}
|
||||
|
||||
/**
|
||||
* When setting stock level, ensure the stock status is kept in sync
|
||||
* @param int $meta_id
|
||||
* @param int $object_id
|
||||
* @param string $meta_key
|
||||
* @param mixed $_meta_value
|
||||
*/
|
||||
public static function sync_product_stock_status( $meta_id, $object_id, $meta_key, $_meta_value ) {
|
||||
if ( '_stock' === $meta_key && 'product' !== get_post_type( $object_id ) ) {
|
||||
$product = wc_get_product( $object_id );
|
||||
$product->check_stock_status();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the order posts to have a title in a certain format (containing the date).
|
||||
* Forces certain product data based on the product's type, e.g. grouped products cannot have a parent.
|
||||
|
|
|
@ -88,7 +88,7 @@ class WC_Product_Variable extends WC_Product {
|
|||
/**
|
||||
* Performed after a stock level change at product level
|
||||
*/
|
||||
protected function check_stock_status() {
|
||||
public function check_stock_status() {
|
||||
$set_child_stock_status = '';
|
||||
|
||||
if ( ! $this->backorders_allowed() && $this->get_stock_quantity() <= get_option( 'woocommerce_notify_no_stock_amount' ) ) {
|
||||
|
@ -249,7 +249,7 @@ class WC_Product_Variable extends WC_Product {
|
|||
* @return array()
|
||||
*/
|
||||
public function get_variation_prices( $display = false ) {
|
||||
$cache_key = 'var_prices_' . md5( json_encode( apply_filters( 'woocommerce_get_variation_prices_hash', array(
|
||||
$cache_key = 'wc_var_prices' . md5( json_encode( apply_filters( 'woocommerce_get_variation_prices_hash', array(
|
||||
$this->id,
|
||||
$display ? WC_Tax::get_rates() : '',
|
||||
WC_Cache_Helper::get_transient_version( 'product' )
|
||||
|
@ -373,7 +373,7 @@ class WC_Product_Variable extends WC_Product {
|
|||
if ( in_array( '', $values ) ) {
|
||||
$values = $attribute['is_taxonomy'] ? wp_get_post_terms( $this->id, $attribute['name'], array( 'fields' => 'slugs' ) ) : wc_get_text_attributes( $attribute['value'] );
|
||||
|
||||
// Order custom attributes (non taxonomy) as defined
|
||||
// Get custom attributes (non taxonomy) as defined
|
||||
} elseif ( ! $attribute['is_taxonomy'] ) {
|
||||
$text_attributes = wc_get_text_attributes( $attribute['value'] );
|
||||
$assigned_text_attributes = $values;
|
||||
|
@ -414,6 +414,18 @@ class WC_Product_Variable extends WC_Product {
|
|||
return apply_filters( 'woocommerce_product_default_attributes', (array) maybe_unserialize( $default ), $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* If set, get the default attributes for a variable product.
|
||||
*
|
||||
* @param string $attribute_name
|
||||
* @return string
|
||||
*/
|
||||
public function get_variation_default_attribute( $attribute_name ) {
|
||||
$defaults = $this->get_variation_default_attributes();
|
||||
$attribute_name = sanitize_title( $attribute_name );
|
||||
return isset( $defaults[ $attribute_name ] ) ? $defaults[ $attribute_name ] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Match a variation to a given set of attributes using a WP_Query
|
||||
* @since 2.4.0
|
||||
|
@ -591,6 +603,53 @@ class WC_Product_Variable extends WC_Product {
|
|||
wc_update_product_stock_status( $product_id, $stock_status );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync the variable product's attributes with the variations
|
||||
*/
|
||||
public static function sync_attributes( $product_id, $children = false ) {
|
||||
if ( ! $children ) {
|
||||
$children = get_posts( array(
|
||||
'post_parent' => $product_id,
|
||||
'posts_per_page'=> -1,
|
||||
'post_type' => 'product_variation',
|
||||
'fields' => 'ids',
|
||||
'post_status' => 'any'
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre 2.4 handling where 'slugs' were saved instead of the full text attribute.
|
||||
* Attempt to get full version of the text attribute from the parent and UPDATE meta.
|
||||
*/
|
||||
if ( version_compare( get_post_meta( $product_id, '_product_version', true ), '2.4.0', '<' ) ) {
|
||||
$parent_attributes = array_filter( (array) get_post_meta( $product_id, '_product_attributes', true ) );
|
||||
|
||||
foreach ( $children as $child_id ) {
|
||||
$all_meta = get_post_meta( $child_id );
|
||||
|
||||
foreach ( $all_meta as $name => $value ) {
|
||||
if ( 0 !== strpos( $name, 'attribute_' ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( sanitize_title( $value[0] ) === $value[0] ) {
|
||||
foreach ( $parent_attributes as $attribute ) {
|
||||
if ( $name !== 'attribute_' . sanitize_title( $attribute['name'] ) ) {
|
||||
continue;
|
||||
}
|
||||
$text_attributes = wc_get_text_attributes( $attribute['value'] );
|
||||
foreach ( $text_attributes as $text_attribute ) {
|
||||
if ( sanitize_title( $text_attribute ) === $value[0] ) {
|
||||
update_post_meta( $child_id, $name, $text_attribute );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync the variable product with it's children
|
||||
*/
|
||||
|
@ -691,6 +750,9 @@ class WC_Product_Variable extends WC_Product {
|
|||
update_post_meta( $product_id, '_price', $min_price );
|
||||
delete_transient( 'wc_products_onsale' );
|
||||
|
||||
// Sync attributes
|
||||
self::sync_attributes( $product_id, $children );
|
||||
|
||||
do_action( 'woocommerce_variable_product_sync', $product_id, $children );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,40 +135,7 @@ class WC_Product_Variation extends WC_Product {
|
|||
}
|
||||
|
||||
} elseif ( 'variation_data' === $key ) {
|
||||
$all_meta = get_post_meta( $this->variation_id );
|
||||
|
||||
// The variation data array
|
||||
$this->variation_data = array();
|
||||
|
||||
// Get the variation attributes from meta
|
||||
foreach ( $all_meta as $name => $value ) {
|
||||
if ( 0 !== strpos( $name, 'attribute_' ) ) {
|
||||
continue;
|
||||
}
|
||||
/**
|
||||
* Pre 2.4 handling where 'slugs' were saved instead of the full text attribute.
|
||||
* Attempt to get full version of the text attribute from the parent.
|
||||
*/
|
||||
if ( sanitize_title( $value[0] ) === $value[0] && version_compare( get_post_meta( $this->id, '_product_version', true ), '2.4.0', '<' ) ) {
|
||||
$attributes = $this->parent->get_attributes();
|
||||
|
||||
foreach ( $attributes as $attribute ) {
|
||||
if ( $name !== 'attribute_' . sanitize_title( $attribute['name'] ) ) {
|
||||
continue;
|
||||
}
|
||||
$text_attributes = wc_get_text_attributes( $attribute['value'] );
|
||||
|
||||
foreach ( $text_attributes as $text_attribute ) {
|
||||
if ( sanitize_title( $text_attribute ) === $value[0] ) {
|
||||
$value[0] = $text_attribute;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->variation_data[ $name ] = $value[0];
|
||||
}
|
||||
|
||||
return $this->variation_data;
|
||||
return $this->variation_data = wc_get_product_variation_attributes( $this->variation_id );
|
||||
|
||||
} elseif ( 'variation_has_stock' === $key ) {
|
||||
return $this->managing_stock();
|
||||
|
@ -196,7 +163,7 @@ class WC_Product_Variation extends WC_Product {
|
|||
* @return string
|
||||
*/
|
||||
public function get_permalink( $cart_item = null ) {
|
||||
return add_query_arg( array_filter( isset( $cart_item['variation'] ) ? $cart_item['variation'] : $this->variation_data ), get_permalink( $this->id ) );
|
||||
return add_query_arg( array_map( 'urlencode', array_filter( isset( $cart_item['variation'] ) ? $cart_item['variation'] : $this->variation_data ) ), get_permalink( $this->id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -155,16 +155,17 @@ class WC_Gateway_Paypal_Request {
|
|||
* @return array
|
||||
*/
|
||||
protected function get_line_item_args( $order ) {
|
||||
|
||||
/**
|
||||
* Try passing a line item per product if supported
|
||||
*/
|
||||
if ( ( ! wc_tax_enabled() || ! wc_prices_include_tax() ) && $this->prepare_line_items( $order ) ) {
|
||||
|
||||
$line_item_args = $this->get_line_items();
|
||||
$line_item_args['tax_cart'] = $order->get_total_tax();
|
||||
$line_item_args['tax_cart'] = $this->number_format( $order->get_total_tax(), $order );
|
||||
|
||||
if ( $order->get_total_discount() > 0 ) {
|
||||
$line_item_args['discount_amount_cart'] = round( $order->get_total_discount(), 2 );
|
||||
$line_item_args['discount_amount_cart'] = $this->round( $order->get_total_discount(), $order );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -176,8 +177,9 @@ class WC_Gateway_Paypal_Request {
|
|||
|
||||
$this->delete_line_items();
|
||||
|
||||
$this->add_line_item( $this->get_order_item_names( $order ), 1, number_format( $order->get_total() - round( $order->get_total_shipping() + $order->get_shipping_tax(), 2 ), 2, '.', '' ), $order->get_order_number() );
|
||||
$this->add_line_item( sprintf( __( 'Shipping via %s', 'woocommerce' ), ucwords( $order->get_shipping_method() ) ), 1, number_format( $order->get_total_shipping() + $order->get_shipping_tax(), 2, '.', '' ) );
|
||||
$all_items_name = $this->get_order_item_names( $order );
|
||||
$this->add_line_item( $all_items_name ? $all_items_name : __( 'Order', 'woocommerce' ), 1, $this->number_format( $order->get_total() - $this->round( $order->get_total_shipping() + $order->get_shipping_tax(), $order ), $order ), $order->get_order_number() );
|
||||
$this->add_line_item( sprintf( __( 'Shipping via %s', 'woocommerce' ), ucwords( $order->get_shipping_method() ) ), 1, $this->number_format( $order->get_total_shipping() + $order->get_shipping_tax(), $order ) );
|
||||
|
||||
$line_item_args = $this->get_line_items();
|
||||
}
|
||||
|
@ -244,12 +246,14 @@ class WC_Gateway_Paypal_Request {
|
|||
// Products
|
||||
foreach ( $order->get_items( array( 'line_item', 'fee' ) ) as $item ) {
|
||||
if ( 'fee' === $item['type'] ) {
|
||||
$line_item = $this->add_line_item( $item['name'], 1, $item['line_total'] );
|
||||
$calculated_total += $item['line_total'];
|
||||
$item_line_total = $this->number_format( $item['line_total'], $order );
|
||||
$line_item = $this->add_line_item( $item['name'], 1, $item_line_total );
|
||||
$calculated_total += $item_line_total;
|
||||
} else {
|
||||
$product = $order->get_product_from_item( $item );
|
||||
$line_item = $this->add_line_item( $this->get_order_item_name( $order, $item ), $item['qty'], $order->get_item_subtotal( $item, false ), $product->get_sku() );
|
||||
$calculated_total += $order->get_item_subtotal( $item, false ) * $item['qty'];
|
||||
$item_line_total = $this->number_format( $order->get_item_subtotal( $item, false ), $order );
|
||||
$line_item = $this->add_line_item( $this->get_order_item_name( $order, $item ), $item['qty'], $item_line_total, $product->get_sku() );
|
||||
$calculated_total += $item_line_total * $item['qty'];
|
||||
}
|
||||
|
||||
if ( ! $line_item ) {
|
||||
|
@ -258,12 +262,12 @@ class WC_Gateway_Paypal_Request {
|
|||
}
|
||||
|
||||
// Shipping Cost item - paypal only allows shipping per item, we want to send shipping for the order
|
||||
if ( $order->get_total_shipping() > 0 && ! $this->add_line_item( sprintf( __( 'Shipping via %s', 'woocommerce' ), $order->get_shipping_method() ), 1, round( $order->get_total_shipping(), 2 ) ) ) {
|
||||
if ( $order->get_total_shipping() > 0 && ! $this->add_line_item( sprintf( __( 'Shipping via %s', 'woocommerce' ), $order->get_shipping_method() ), 1, $this->round( $order->get_total_shipping(), $order ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for mismatched totals
|
||||
if ( wc_format_decimal( $calculated_total + $order->get_total_tax() + round( $order->get_total_shipping(), 2 ) - round( $order->get_total_discount(), 2 ), 2 ) != wc_format_decimal( $order->get_total(), 2 ) ) {
|
||||
if ( $this->number_format( $calculated_total + $order->get_total_tax() + $this->round( $order->get_total_shipping(), $order ) - $this->round( $order->get_total_discount(), $order ), $order ) != $this->number_format( $order->get_total(), $order ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -281,11 +285,11 @@ class WC_Gateway_Paypal_Request {
|
|||
protected function add_line_item( $item_name, $quantity = 1, $amount = 0, $item_number = '' ) {
|
||||
$index = ( sizeof( $this->line_items ) / 4 ) + 1;
|
||||
|
||||
if ( ! $item_name || $amount < 0 || $index > 9 ) {
|
||||
if ( $amount < 0 || $index > 9 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->line_items[ 'item_name_' . $index ] = html_entity_decode( wc_trim_string( $item_name, 127 ), ENT_NOQUOTES, 'UTF-8' );
|
||||
$this->line_items[ 'item_name_' . $index ] = html_entity_decode( wc_trim_string( $item_name ? $item_name : __( 'Item', 'woocommerce' ), 127 ), ENT_NOQUOTES, 'UTF-8' );
|
||||
$this->line_items[ 'quantity_' . $index ] = $quantity;
|
||||
$this->line_items[ 'amount_' . $index ] = $amount;
|
||||
$this->line_items[ 'item_number_' . $index ] = $item_number;
|
||||
|
@ -312,4 +316,55 @@ class WC_Gateway_Paypal_Request {
|
|||
|
||||
return $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if currency has decimals
|
||||
*
|
||||
* @param string $currency
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function currency_has_decimals( $currency ) {
|
||||
if ( in_array( $currency, array( 'HUF', 'JPY', 'TWD' ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Round prices
|
||||
*
|
||||
* @param float|int $price
|
||||
* @param WC_Order $order
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
protected function round( $price, $order ) {
|
||||
$precision = 2;
|
||||
|
||||
if ( ! $this->currency_has_decimals( $order->get_order_currency() ) ) {
|
||||
$precision = 0;
|
||||
}
|
||||
|
||||
return round( $price, $precision );
|
||||
}
|
||||
|
||||
/**
|
||||
* Format prices
|
||||
*
|
||||
* @param float|int $price
|
||||
* @param WC_Order $order
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
protected function number_format( $price, $order ) {
|
||||
$decimals = 2;
|
||||
|
||||
if ( ! $this->currency_has_decimals( $order->get_order_currency() ) ) {
|
||||
$decimals = 0;
|
||||
}
|
||||
|
||||
return number_format( $price, $decimals, '.', '' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
<?php
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplify Commerce Gateway for Subscriptions < 2.0
|
||||
*
|
||||
* @class WC_Addons_Gateway_Simplify_Commerce_Deprecated
|
||||
* @extends WC_Addons_Gateway_Simplify_Commerce
|
||||
* @since 2.4.0
|
||||
* @version 1.0.0
|
||||
* @package WooCommerce/Classes/Payment
|
||||
* @author WooThemes
|
||||
*/
|
||||
class WC_Addons_Gateway_Simplify_Commerce_Deprecated extends WC_Addons_Gateway_Simplify_Commerce {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
if ( class_exists( 'WC_Subscriptions_Order' ) ) {
|
||||
add_action( 'scheduled_subscription_payment_' . $this->id, array( $this, 'process_scheduled_subscription_payment' ), 10, 3 );
|
||||
add_filter( 'woocommerce_subscriptions_renewal_order_meta_query', array( $this, 'remove_renewal_order_meta' ), 10, 4 );
|
||||
add_action( 'woocommerce_subscriptions_changed_failing_payment_method_' . $this->id, array( $this, 'change_failing_payment_method' ), 10, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the customer and card IDs on the order and subscriptions in the order
|
||||
*
|
||||
* @param int $order_id
|
||||
* @param string $customer_id
|
||||
* @return array
|
||||
*/
|
||||
protected function save_subscription_meta( $order_id, $customer_id ) {
|
||||
update_post_meta( $order_id, '_simplify_customer_id', wc_clean( $customer_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* process_subscription_payment function.
|
||||
*
|
||||
* @param WC_order $order
|
||||
* @param integer $amount (default: 0)
|
||||
* @uses Simplify_BadRequestException
|
||||
* @return bool|WP_Error
|
||||
*/
|
||||
public function process_subscription_payment( $order, $amount = 0 ) {
|
||||
if ( 0 == $amount ) {
|
||||
// Payment complete
|
||||
$order->payment_complete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $amount * 100 < 50 ) {
|
||||
return new WP_Error( 'simplify_error', __( 'Sorry, the minimum allowed order total is 0.50 to use this payment method.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
$order_items = $order->get_items();
|
||||
$order_item = array_shift( $order_items );
|
||||
$subscription_name = sprintf( __( '%s - Subscription for "%s"', 'woocommerce' ), esc_html( get_bloginfo( 'name', 'display' ) ), $order_item['name'] ) . ' ' . sprintf( __( '(Order #%s)', 'woocommerce' ), $order->get_order_number() );
|
||||
|
||||
$customer_id = get_post_meta( $order->id, '_simplify_customer_id', true );
|
||||
|
||||
if ( ! $customer_id ) {
|
||||
return new WP_Error( 'simplify_error', __( 'Customer not found', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
try {
|
||||
// Charge the customer
|
||||
$payment = Simplify_Payment::createPayment( array(
|
||||
'amount' => $amount * 100, // In cents
|
||||
'customer' => $customer_id,
|
||||
'description' => trim( substr( $subscription_name, 0, 1024 ) ),
|
||||
'currency' => strtoupper( get_woocommerce_currency() ),
|
||||
'reference' => $order->id,
|
||||
'card.addressCity' => $order->billing_city,
|
||||
'card.addressCountry' => $order->billing_country,
|
||||
'card.addressLine1' => $order->billing_address_1,
|
||||
'card.addressLine2' => $order->billing_address_2,
|
||||
'card.addressState' => $order->billing_state,
|
||||
'card.addressZip' => $order->billing_postcode
|
||||
) );
|
||||
|
||||
} catch ( Exception $e ) {
|
||||
|
||||
$error_message = $e->getMessage();
|
||||
|
||||
if ( $e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors() ) {
|
||||
$error_message = '';
|
||||
foreach ( $e->getFieldErrors() as $error ) {
|
||||
$error_message .= ' ' . $error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')';
|
||||
}
|
||||
}
|
||||
|
||||
$order->add_order_note( sprintf( __( 'Simplify payment error: %s', 'woocommerce' ), $error_message ) );
|
||||
|
||||
return new WP_Error( 'simplify_payment_declined', $e->getMessage(), array( 'status' => $e->getCode() ) );
|
||||
}
|
||||
|
||||
if ( 'APPROVED' == $payment->paymentStatus ) {
|
||||
// Payment complete
|
||||
$order->payment_complete( $payment->id );
|
||||
|
||||
// Add order note
|
||||
$order->add_order_note( sprintf( __( 'Simplify payment approved (ID: %s, Auth Code: %s)', 'woocommerce' ), $payment->id, $payment->authCode ) );
|
||||
|
||||
return true;
|
||||
} else {
|
||||
$order->add_order_note( __( 'Simplify payment declined', 'woocommerce' ) );
|
||||
|
||||
return new WP_Error( 'simplify_payment_declined', __( 'Payment was declined - please try another card.', 'woocommerce' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* process_scheduled_subscription_payment function.
|
||||
*
|
||||
* @param float $amount_to_charge The amount to charge.
|
||||
* @param WC_Order $order The WC_Order object of the order which the subscription was purchased in.
|
||||
* @param int $product_id The ID of the subscription product for which this payment relates.
|
||||
*/
|
||||
public function process_scheduled_subscription_payment( $amount_to_charge, $order, $product_id ) {
|
||||
$result = $this->process_subscription_payment( $order, $amount_to_charge );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
WC_Subscriptions_Manager::process_subscription_payment_failure_on_order( $order, $product_id );
|
||||
} else {
|
||||
WC_Subscriptions_Manager::process_subscription_payments_on_order( $order );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't transfer customer meta when creating a parent renewal order.
|
||||
*
|
||||
* @param string $order_meta_query MySQL query for pulling the metadata
|
||||
* @param int $original_order_id Post ID of the order being used to purchased the subscription being renewed
|
||||
* @param int $renewal_order_id Post ID of the order created for renewing the subscription
|
||||
* @param string $new_order_role The role the renewal order is taking, one of 'parent' or 'child'
|
||||
* @return string
|
||||
*/
|
||||
public function remove_renewal_order_meta( $order_meta_query, $original_order_id, $renewal_order_id, $new_order_role ) {
|
||||
if ( 'parent' == $new_order_role ) {
|
||||
$order_meta_query .= " AND `meta_key` NOT LIKE '_simplify_customer_id' ";
|
||||
}
|
||||
|
||||
return $order_meta_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if order contains subscriptions.
|
||||
*
|
||||
* @param int $order_id
|
||||
* @return bool
|
||||
*/
|
||||
protected function order_contains_subscription( $order_id ) {
|
||||
return class_exists( 'WC_Subscriptions_Order' ) && ( WC_Subscriptions_Order::order_contains_subscription( $order_id ) || WC_Subscriptions_Renewal_Order::is_renewal( $order_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the customer_id for a subscription after using Simplify to complete a payment to make up for
|
||||
* an automatic renewal payment which previously failed.
|
||||
*
|
||||
* @param WC_Order $original_order The original order in which the subscription was purchased.
|
||||
* @param WC_Order $renewal_order The order which recorded the successful payment (to make up for the failed automatic payment).
|
||||
* @param string $subscription_key A subscription key of the form created by @see WC_Subscriptions_Manager::get_subscription_key()
|
||||
*/
|
||||
public function change_failing_payment_method( $original_order, $renewal_order, $subscription_key ) {
|
||||
$new_customer_id = get_post_meta( $renewal_order->id, '_simplify_customer_id', true );
|
||||
|
||||
update_post_meta( $original_order->id, '_simplify_customer_id', $new_customer_id );
|
||||
}
|
||||
}
|
|
@ -23,9 +23,14 @@ class WC_Addons_Gateway_Simplify_Commerce extends WC_Gateway_Simplify_Commerce {
|
|||
parent::__construct();
|
||||
|
||||
if ( class_exists( 'WC_Subscriptions_Order' ) ) {
|
||||
add_action( 'scheduled_subscription_payment_' . $this->id, array( $this, 'scheduled_subscription_payment' ), 10, 3 );
|
||||
add_filter( 'woocommerce_subscriptions_renewal_order_meta_query', array( $this, 'remove_renewal_order_meta' ), 10, 4 );
|
||||
add_action( 'woocommerce_subscriptions_changed_failing_payment_method_' . $this->id, array( $this, 'update_failing_payment_method' ), 10, 3 );
|
||||
add_action( 'woocommerce_scheduled_subscription_payment_' . $this->id, array( $this, 'scheduled_subscription_payment' ), 10, 2 );
|
||||
add_action( 'woocommerce_subscription_failing_payment_method_updated_' . $this->id, array( $this, 'update_failing_payment_method' ), 10, 2 );
|
||||
|
||||
add_action( 'wcs_resubscribe_order_created', array( $this, 'delete_resubscribe_meta' ), 10 );
|
||||
|
||||
// Allow store managers to manually set Simplify as the payment method on a subscription
|
||||
add_filter( 'woocommerce_subscription_payment_meta', array( $this, 'add_subscription_payment_meta' ), 10, 2 );
|
||||
add_filter( 'woocommerce_subscription_validate_payment_meta', array( $this, 'validate_subscription_payment_meta' ), 10, 2 );
|
||||
}
|
||||
|
||||
if ( class_exists( 'WC_Pre_Orders_Order' ) ) {
|
||||
|
@ -60,7 +65,7 @@ class WC_Addons_Gateway_Simplify_Commerce extends WC_Gateway_Simplify_Commerce {
|
|||
* @return bool
|
||||
*/
|
||||
protected function order_contains_subscription( $order_id ) {
|
||||
return class_exists( 'WC_Subscriptions_Order' ) && ( WC_Subscriptions_Order::order_contains_subscription( $order_id ) || WC_Subscriptions_Renewal_Order::is_renewal( $order_id ) );
|
||||
return function_exists( 'wcs_order_contains_subscription' ) && ( wcs_order_contains_subscription( $order_id ) || wcs_order_contains_renewal( $order_id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,18 +108,14 @@ class WC_Addons_Gateway_Simplify_Commerce extends WC_Gateway_Simplify_Commerce {
|
|||
) );
|
||||
|
||||
if ( is_object( $customer ) && '' != $customer->id ) {
|
||||
$customer_id = wc_clean( $customer->id );
|
||||
|
||||
// Store the customer ID in the order
|
||||
update_post_meta( $order->id, '_simplify_customer_id', $customer_id );
|
||||
$this->save_subscription_meta( $order->id, $customer->id );
|
||||
} else {
|
||||
$error_msg = __( 'Error creating user in Simplify Commerce.', 'woocommerce' );
|
||||
|
||||
throw new Simplify_ApiException( $error_msg );
|
||||
}
|
||||
|
||||
$initial_payment = WC_Subscriptions_Order::get_total_initial_payment( $order );
|
||||
$payment_response = $this->process_subscription_payment( $order, $initial_payment );
|
||||
$payment_response = $this->process_subscription_payment( $order, $order->get_total() );
|
||||
|
||||
if ( is_wp_error( $payment_response ) ) {
|
||||
throw new Exception( $payment_response->get_error_message() );
|
||||
|
@ -145,6 +146,24 @@ class WC_Addons_Gateway_Simplify_Commerce extends WC_Gateway_Simplify_Commerce {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the customer and card IDs on the order and subscriptions in the order
|
||||
*
|
||||
* @param int $order_id
|
||||
* @param string $customer_id
|
||||
*/
|
||||
protected function save_subscription_meta( $order_id, $customer_id ) {
|
||||
|
||||
$customer_id = wc_clean( $customer_id );
|
||||
|
||||
update_post_meta( $order_id, '_simplify_customer_id', $customer_id );
|
||||
|
||||
// Also store it on the subscriptions being purchased in the order
|
||||
foreach( wcs_get_subscriptions_for_order( $order_id ) as $subscription ) {
|
||||
update_post_meta( $subscription->id, '_simplify_customer_id', $customer_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the pre-order
|
||||
*
|
||||
|
@ -239,7 +258,7 @@ class WC_Addons_Gateway_Simplify_Commerce extends WC_Gateway_Simplify_Commerce {
|
|||
$order = wc_get_order( $order_id );
|
||||
|
||||
// Processing subscription
|
||||
if ( 'standard' == $this->mode && $this->order_contains_subscription( $order->id ) ) {
|
||||
if ( 'standard' == $this->mode && ( $this->order_contains_subscription( $order->id ) || ( function_exists( 'wcs_is_subscription' ) && wcs_is_subscription( $order_id ) ) ) ) {
|
||||
return $this->process_subscription( $order, $cart_token );
|
||||
|
||||
// Processing pre-order
|
||||
|
@ -272,10 +291,6 @@ class WC_Addons_Gateway_Simplify_Commerce extends WC_Gateway_Simplify_Commerce {
|
|||
return new WP_Error( 'simplify_error', __( 'Sorry, the minimum allowed order total is 0.50 to use this payment method.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
$order_items = $order->get_items();
|
||||
$order_item = array_shift( $order_items );
|
||||
$subscription_name = sprintf( __( '%s - Subscription for "%s"', 'woocommerce' ), esc_html( get_bloginfo( 'name', 'display' ) ), $order_item['name'] ) . ' ' . sprintf( __( '(Order #%s)', 'woocommerce' ), $order->get_order_number() );
|
||||
|
||||
$customer_id = get_post_meta( $order->id, '_simplify_customer_id', true );
|
||||
|
||||
if ( ! $customer_id ) {
|
||||
|
@ -287,7 +302,7 @@ class WC_Addons_Gateway_Simplify_Commerce extends WC_Gateway_Simplify_Commerce {
|
|||
$payment = Simplify_Payment::createPayment( array(
|
||||
'amount' => $amount * 100, // In cents
|
||||
'customer' => $customer_id,
|
||||
'description' => trim( substr( $subscription_name, 0, 1024 ) ),
|
||||
'description' => sprintf( __( '%s - Order #%s', 'woocommerce' ), esc_html( get_bloginfo( 'name', 'display' ) ), $order->get_order_number() ),
|
||||
'currency' => strtoupper( get_woocommerce_currency() ),
|
||||
'reference' => $order->id,
|
||||
'card.addressCity' => $order->billing_city,
|
||||
|
@ -333,48 +348,76 @@ class WC_Addons_Gateway_Simplify_Commerce extends WC_Gateway_Simplify_Commerce {
|
|||
* scheduled_subscription_payment function.
|
||||
*
|
||||
* @param float $amount_to_charge The amount to charge.
|
||||
* @param WC_Order $order The WC_Order object of the order which the subscription was purchased in.
|
||||
* @param int $product_id The ID of the subscription product for which this payment relates.
|
||||
* @param WC_Order $renewal_order A WC_Order object created to record the renewal payment.
|
||||
*/
|
||||
public function scheduled_subscription_payment( $amount_to_charge, $order, $product_id ) {
|
||||
$result = $this->process_subscription_payment( $order, $amount_to_charge );
|
||||
public function scheduled_subscription_payment( $amount_to_charge, $renewal_order ) {
|
||||
$result = $this->process_subscription_payment( $renewal_order, $amount_to_charge );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
WC_Subscriptions_Manager::process_subscription_payment_failure_on_order( $order, $product_id );
|
||||
} else {
|
||||
WC_Subscriptions_Manager::process_subscription_payments_on_order( $order );
|
||||
$renewal_order->update_status( 'failed', sprintf( __( 'Simplify Transaction Failed (%s)', 'woocommerce' ), $result->get_error_message() ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't transfer customer meta when creating a parent renewal order.
|
||||
*
|
||||
* @param string $order_meta_query MySQL query for pulling the metadata
|
||||
* @param int $original_order_id Post ID of the order being used to purchased the subscription being renewed
|
||||
* @param int $renewal_order_id Post ID of the order created for renewing the subscription
|
||||
* @param string $new_order_role The role the renewal order is taking, one of 'parent' or 'child'
|
||||
* @return string
|
||||
*/
|
||||
public function remove_renewal_order_meta( $order_meta_query, $original_order_id, $renewal_order_id, $new_order_role ) {
|
||||
if ( 'parent' == $new_order_role ) {
|
||||
$order_meta_query .= " AND `meta_key` NOT LIKE '_simplify_customer_id' ";
|
||||
}
|
||||
|
||||
return $order_meta_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the customer_id for a subscription after using Simplify to complete a payment to make up for
|
||||
* an automatic renewal payment which previously failed.
|
||||
*
|
||||
* @param WC_Order $original_order The original order in which the subscription was purchased.
|
||||
* @param WC_Subscription $subscription The subscription for which the failing payment method relates.
|
||||
* @param WC_Order $renewal_order The order which recorded the successful payment (to make up for the failed automatic payment).
|
||||
* @param string $subscription_key A subscription key of the form created by @see WC_Subscriptions_Manager::get_subscription_key()
|
||||
*/
|
||||
public function update_failing_payment_method( $original_order, $renewal_order, $subscription_key ) {
|
||||
$new_customer_id = get_post_meta( $renewal_order->id, '_simplify_customer_id', true );
|
||||
public function update_failing_payment_method( $subscription, $renewal_order ) {
|
||||
update_post_meta( $original_order->id, '_simplify_customer_id', get_post_meta( $renewal_order->id, '_simplify_customer_id', true ) );
|
||||
}
|
||||
|
||||
update_post_meta( $original_order->id, '_simplify_customer_id', $new_customer_id );
|
||||
/**
|
||||
* Include the payment meta data required to process automatic recurring payments so that store managers can
|
||||
* manually set up automatic recurring payments for a customer via the Edit Subscription screen in Subscriptions v2.0+.
|
||||
*
|
||||
* @since 2.4
|
||||
* @param array $payment_meta associative array of meta data required for automatic payments
|
||||
* @param WC_Subscription $subscription An instance of a subscription object
|
||||
* @return array
|
||||
*/
|
||||
public function add_subscription_payment_meta( $payment_meta, $subscription ) {
|
||||
|
||||
$payment_meta[ $this->id ] = array(
|
||||
'post_meta' => array(
|
||||
'_simplify_customer_id' => array(
|
||||
'value' => get_post_meta( $subscription->id, '_simplify_customer_id', true ),
|
||||
'label' => 'Simplify Customer ID',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $payment_meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the payment meta data required to process automatic recurring payments so that store managers can
|
||||
* manually set up automatic recurring payments for a customer via the Edit Subscription screen in Subscriptions 2.0+.
|
||||
*
|
||||
* @since 2.4
|
||||
* @param string $payment_method_id The ID of the payment method to validate
|
||||
* @param array $payment_meta associative array of meta data required for automatic payments
|
||||
* @return array
|
||||
*/
|
||||
public function validate_subscription_payment_meta( $payment_method_id, $payment_meta ) {
|
||||
if ( $this->id === $payment_method_id ) {
|
||||
if ( ! isset( $payment_meta['post_meta']['_simplify_customer_id']['value'] ) || empty( $payment_meta['post_meta']['_simplify_customer_id']['value'] ) ) {
|
||||
throw new Exception( 'A "_simplify_customer_id" value is required.' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't transfer customer meta to resubscribe orders.
|
||||
*
|
||||
* @access public
|
||||
* @param int $resubscribe_order The order created for the customer to resubscribe to the old expired/cancelled subscription
|
||||
* @return void
|
||||
*/
|
||||
public function delete_resubscribe_meta( $resubscribe_order ) {
|
||||
delete_post_meta( $resubscribe_order->id, '_simplify_customer_id' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,8 +31,11 @@ class WC_Gateway_Simplify_Commerce extends WC_Payment_Gateway {
|
|||
'subscription_reactivation',
|
||||
'subscription_suspension',
|
||||
'subscription_amount_changes',
|
||||
'subscription_payment_method_change',
|
||||
'subscription_payment_method_change', // Subscriptions 1.n compatibility
|
||||
'subscription_payment_method_change_customer',
|
||||
'subscription_payment_method_change_admin',
|
||||
'subscription_date_changes',
|
||||
'multiple_subscriptions',
|
||||
'default_credit_card_form',
|
||||
'refunds',
|
||||
'pre-orders'
|
||||
|
|
|
@ -100,7 +100,7 @@ if ( WC()->shipping->get_shipping_classes() ) {
|
|||
);
|
||||
}
|
||||
|
||||
if ( $this->get_option( 'options', false ) ) {
|
||||
if ( apply_filters( 'woocommerce_enable_deprecated_additional_flat_rates', $this->get_option( 'options', false ) ) ) {
|
||||
$settings[ 'additional_rates' ] = array(
|
||||
'title' => __( 'Additional Rates', 'woocommerce' ),
|
||||
'type' => 'title',
|
||||
|
|
|
@ -287,3 +287,19 @@ function wc_cart_totals_shipping_method_label( $method ) {
|
|||
|
||||
return apply_filters( 'woocommerce_cart_shipping_method_full_label', $label, $method );
|
||||
}
|
||||
|
||||
/**
|
||||
* Round discount
|
||||
*
|
||||
* @param float $value
|
||||
* @param int $precision
|
||||
* @return float
|
||||
*/
|
||||
function wc_cart_round_discount( $value, $precision ) {
|
||||
if ( version_compare( PHP_VERSION, '5.3.0', '>=' ) ) {
|
||||
return round( $value, $precision, WC_DISCOUNT_ROUNDING_MODE );
|
||||
} else {
|
||||
return round( $value, $precision );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -264,21 +264,20 @@ if ( ! function_exists( 'meta_is_product_attribute' ) ) {
|
|||
/**
|
||||
* Returns true when the passed meta name is a product attribute.
|
||||
* @param string $name of the attribute
|
||||
* @param mixed $value
|
||||
* @param string $value
|
||||
* @param int $product_id
|
||||
* @return bool
|
||||
*/
|
||||
function meta_is_product_attribute( $name, $value, $product_id ) {
|
||||
$product = wc_get_product( $product_id );
|
||||
|
||||
if ( $product->product_type != 'variable' ) {
|
||||
if ( $product && method_exists( $product, 'get_variation_attributes' ) ) {
|
||||
$variation_attributes = $product->get_variation_attributes();
|
||||
$attributes = $product->get_attributes();
|
||||
return ( in_array( $name, array_keys( $attributes ) ) && in_array( $value, $variation_attributes[ $attributes[ $name ]['name'] ] ) );
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
$variation_attributes = $product->get_variation_attributes();
|
||||
$attributes = $product->get_attributes();
|
||||
|
||||
return ( in_array( $name, array_keys( $attributes ) ) && in_array( $value, $variation_attributes[ $attributes[ $name ]['name'] ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -719,8 +719,9 @@ function wc_create_refund( $args = array() ) {
|
|||
|
||||
// Figure out if this is just a partial refund
|
||||
$max_remaining_refund = wc_format_decimal( $order->get_total() - $order->get_total_refunded() );
|
||||
$max_remaining_items = absint( $order->get_item_count() - $order->get_item_count_refunded() );
|
||||
|
||||
if ( $max_remaining_refund > 0 ) {
|
||||
if ( $max_remaining_refund > 0 || $max_remaining_items > 0 ) {
|
||||
do_action( 'woocommerce_order_partially_refunded', $args['order_id'], true, $refund_id );
|
||||
}
|
||||
|
||||
|
|
|
@ -613,3 +613,59 @@ function _wc_save_product_price( $product_id, $regular_price, $sale_price = '',
|
|||
update_post_meta( $product_id, '_sale_price_dates_to', '' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attibutes/data for an individual variation from the database and maintain it's integrity.
|
||||
* @since 2.4.0
|
||||
* @param int $variation_id
|
||||
* @return array
|
||||
*/
|
||||
function wc_get_product_variation_attributes( $variation_id ) {
|
||||
// Build variation data from meta
|
||||
$all_meta = get_post_meta( $variation_id );
|
||||
$parent_id = wp_get_post_parent_id( $variation_id );
|
||||
$parent_attributes = array_filter( (array) get_post_meta( $parent_id, '_product_attributes', true ) );
|
||||
$found_parent_attributes = array();
|
||||
$variation_attributes = array();
|
||||
|
||||
// Compare to parent variable product attributes and ensure they match
|
||||
foreach ( $parent_attributes as $attribute_name => $options ) {
|
||||
$attribute = 'attribute_' . sanitize_title( $attribute_name );
|
||||
$found_parent_attributes[] = $attribute;
|
||||
if ( ! array_key_exists( $attribute, $variation_attributes ) ) {
|
||||
$variation_attributes[ $attribute ] = ''; // Add it - 'any' will be asumed
|
||||
}
|
||||
}
|
||||
|
||||
// Get the variation attributes from meta
|
||||
foreach ( $all_meta as $name => $value ) {
|
||||
// Only look at valid attribute meta, and also compare variation level attributes and remove any which do not exist at parent level
|
||||
if ( 0 !== strpos( $name, 'attribute_' ) || ! in_array( $name, $found_parent_attributes ) ) {
|
||||
unset( $variation_attributes[ $name ] );
|
||||
continue;
|
||||
}
|
||||
/**
|
||||
* Pre 2.4 handling where 'slugs' were saved instead of the full text attribute.
|
||||
* Attempt to get full version of the text attribute from the parent.
|
||||
*/
|
||||
if ( sanitize_title( $value[0] ) === $value[0] && version_compare( get_post_meta( $parent_id, '_product_version', true ), '2.4.0', '<' ) ) {
|
||||
foreach ( $parent_attributes as $attribute ) {
|
||||
if ( $name !== 'attribute_' . sanitize_title( $attribute['name'] ) ) {
|
||||
continue;
|
||||
}
|
||||
$text_attributes = wc_get_text_attributes( $attribute['value'] );
|
||||
|
||||
foreach ( $text_attributes as $text_attribute ) {
|
||||
if ( sanitize_title( $text_attribute ) === $value[0] ) {
|
||||
$value[0] = $text_attribute;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$variation_attributes[ $name ] = $value[0];
|
||||
}
|
||||
|
||||
return $variation_attributes;
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
*
|
||||
* Functions for the templating system.
|
||||
*
|
||||
* @author WooThemes
|
||||
* @category Core
|
||||
* @package WooCommerce/Functions
|
||||
* @version 2.1.0
|
||||
* @author WooThemes
|
||||
* @category Core
|
||||
* @package WooCommerce/Functions
|
||||
* @version 2.4.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
|
@ -507,6 +507,15 @@ if ( ! function_exists( 'woocommerce_product_loop_end' ) ) {
|
|||
return ob_get_clean();
|
||||
}
|
||||
}
|
||||
if ( ! function_exists( 'woocommerce_template_loop_product_title' ) ) {
|
||||
|
||||
/**
|
||||
* Show the product title in the product loop. By default this is an H3
|
||||
*/
|
||||
function woocommerce_template_loop_product_title() {
|
||||
wc_get_template( 'loop/title.php' );
|
||||
}
|
||||
}
|
||||
if ( ! function_exists( 'woocommerce_taxonomy_archive_description' ) ) {
|
||||
|
||||
/**
|
||||
|
@ -1856,3 +1865,91 @@ if ( ! function_exists( 'woocommerce_output_auth_footer' ) ) {
|
|||
wc_get_template( 'auth/footer.php' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'woocommerce_single_variation' ) ) {
|
||||
|
||||
/**
|
||||
* Output placeholders for the single variation.
|
||||
*/
|
||||
function woocommerce_single_variation() {
|
||||
echo '<div class="single_variation"></div>';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'woocommerce_single_variation_add_to_cart_button' ) ) {
|
||||
|
||||
/**
|
||||
* Output the add to cart button for variations.
|
||||
*/
|
||||
function woocommerce_single_variation_add_to_cart_button() {
|
||||
global $product;
|
||||
?>
|
||||
<div class="variations_button">
|
||||
<?php woocommerce_quantity_input( array( 'input_value' => isset( $_POST['quantity'] ) ? wc_stock_amount( $_POST['quantity'] ) : 1 ) ); ?>
|
||||
<button type="submit" class="single_add_to_cart_button button alt"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></button>
|
||||
<input type="hidden" name="add-to-cart" value="<?php echo absint( $product->id ); ?>" />
|
||||
<input type="hidden" name="product_id" value="<?php echo absint( $product->id ); ?>" />
|
||||
<input type="hidden" name="variation_id" class="variation_id" value="" />
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'wc_dropdown_variation_attribute_options' ) ) {
|
||||
|
||||
/**
|
||||
* Output a list of variation attributes for use in the cart forms.
|
||||
*
|
||||
* @param array $args
|
||||
* @since 2.4.0
|
||||
*/
|
||||
function wc_dropdown_variation_attribute_options( $args = array() ) {
|
||||
$args = wp_parse_args( $args, array(
|
||||
'options' => false,
|
||||
'attribute' => false,
|
||||
'product' => false,
|
||||
'selected' => false,
|
||||
'name' => '',
|
||||
'id' => '',
|
||||
'show_option_none' => __( 'Choose an option', 'woocommerce' )
|
||||
) );
|
||||
|
||||
$options = $args['options'];
|
||||
$product = $args['product'];
|
||||
$attribute = $args['attribute'];
|
||||
$name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
|
||||
$id = $args['id'] ? $args['id'] : sanitize_title( $attribute );
|
||||
|
||||
if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
|
||||
$attributes = $product->get_variation_attributes();
|
||||
$options = $attributes[ $attribute ];
|
||||
}
|
||||
|
||||
echo '<select id="' . esc_attr( $id ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '">';
|
||||
|
||||
if ( $args['show_option_none'] ) {
|
||||
echo '<option value="">' . esc_html( $args['show_option_none'] ) . '</option>';
|
||||
}
|
||||
|
||||
if ( ! empty( $options ) ) {
|
||||
if ( $product && taxonomy_exists( $attribute ) ) {
|
||||
// Get terms if this is a taxonomy - ordered. We need the names too.
|
||||
$terms = wc_get_product_terms( $product->id, $attribute, array( 'fields' => 'all' ) );
|
||||
|
||||
foreach ( $terms as $term ) {
|
||||
if ( in_array( $term->slug, $options ) ) {
|
||||
echo '<option value="' . esc_attr( $term->slug ) . '" ' . selected( sanitize_title( $args['selected'] ), $term->slug, false ) . '>' . apply_filters( 'woocommerce_variation_option_name', $term->name ) . '</option>';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ( $options as $option ) {
|
||||
// This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
|
||||
$selected = sanitize_title( $args['selected'] ) === $args['selected'] ? selected( $args['selected'], sanitize_title( $option ), false ) : selected( $args['selected'], $option, false );
|
||||
echo '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ) . '</option>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo '</select>';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ add_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 )
|
|||
*/
|
||||
add_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
|
||||
add_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 10 );
|
||||
add_action( 'woocommerce_shop_loop_item_title', 'woocommerce_template_loop_product_title', 10 );
|
||||
add_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_price', 10 );
|
||||
add_action( 'woocommerce_after_shop_loop_item_title', 'woocommerce_template_loop_rating', 5 );
|
||||
|
||||
|
@ -148,6 +149,8 @@ add_action( 'woocommerce_simple_add_to_cart', 'woocommerce_simple_add_to_cart',
|
|||
add_action( 'woocommerce_grouped_add_to_cart', 'woocommerce_grouped_add_to_cart', 30 );
|
||||
add_action( 'woocommerce_variable_add_to_cart', 'woocommerce_variable_add_to_cart', 30 );
|
||||
add_action( 'woocommerce_external_add_to_cart', 'woocommerce_external_add_to_cart', 30 );
|
||||
add_action( 'woocommerce_single_variation', 'woocommerce_single_variation', 10 );
|
||||
add_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
|
||||
|
||||
/**
|
||||
* Pagination after shop loops
|
||||
|
|
|
@ -50,7 +50,7 @@ class WC_Widget_Cart extends WC_Widget {
|
|||
* @param array $instance
|
||||
*/
|
||||
public function widget( $args, $instance ) {
|
||||
if ( is_cart() || is_checkout() ) {
|
||||
if ( apply_filters( 'woocommerce_widget_cart_is_hidden', is_cart() || is_checkout() ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*
|
||||
* @author WooThemes
|
||||
* @package WooCommerce/Templates
|
||||
* @version 1.6.4
|
||||
* @version 2.4.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
|
@ -56,11 +56,14 @@ if ( 0 == $woocommerce_loop['loop'] % $woocommerce_loop['columns'] ) {
|
|||
* @hooked woocommerce_template_loop_product_thumbnail - 10
|
||||
*/
|
||||
do_action( 'woocommerce_before_shop_loop_item_title' );
|
||||
?>
|
||||
|
||||
<h3><?php the_title(); ?></h3>
|
||||
/**
|
||||
* woocommerce_shop_loop_item_title hook
|
||||
*
|
||||
* @hooked woocommerce_template_loop_product_title - 10
|
||||
*/
|
||||
do_action( 'woocommerce_shop_loop_item_title' );
|
||||
|
||||
<?php
|
||||
/**
|
||||
* woocommerce_after_shop_loop_item_title hook
|
||||
*
|
||||
|
|
|
@ -16,12 +16,12 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly ?>
|
|||
|
||||
<h2><a class="link" href="<?php echo admin_url( 'post.php?post=' . $order->id . '&action=edit' ); ?>"><?php printf( __( 'Order: %s', 'woocommerce'), $order->get_order_number() ); ?></a> (<?php printf( '<time datetime="%s">%s</time>', date_i18n( 'c', strtotime( $order->order_date ) ), date_i18n( wc_date_format(), strtotime( $order->order_date ) ) ); ?>)</h2>
|
||||
|
||||
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%;" border="1">
|
||||
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;" border="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -34,8 +34,8 @@ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly ?>
|
|||
foreach ( $totals as $total ) {
|
||||
$i++;
|
||||
?><tr>
|
||||
<th class="td" scope="row" colspan="2" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
|
||||
<td class="td" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
|
||||
<th class="td" scope="row" colspan="2" style="text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
|
||||
<td class="td" style="text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
|
||||
</tr><?php
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
|
||||
<h2><a class="link" href="<?php echo admin_url( 'post.php?post=' . $order->id . '&action=edit' ); ?>"><?php printf( __( 'Order #%s', 'woocommerce'), $order->get_order_number() ); ?></a> (<?php printf( '<time datetime="%s">%s</time>', date_i18n( 'c', strtotime( $order->order_date ) ), date_i18n( wc_date_format(), strtotime( $order->order_date ) ) ); ?>)</h2>
|
||||
|
||||
<table cellspacing="0" cellpadding="6" style="width: 100%;" border="1" class="td">
|
||||
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;" border="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -40,7 +40,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
$i++;
|
||||
?><tr>
|
||||
<th class="td" scope="col" colspan="2" style="font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
|
||||
<td class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
|
||||
<td class="td" scope="col" style="text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
|
||||
</tr><?php
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
|
||||
<h2><?php printf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ); ?></h2>
|
||||
|
||||
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%;" border="1">
|
||||
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;" border="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -39,8 +39,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
foreach ( $totals as $total ) {
|
||||
$i++;
|
||||
?><tr>
|
||||
<th class="td" scope="row" colspan="2" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
|
||||
<td class="td" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
|
||||
<th class="td" scope="row" colspan="2" style="text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
|
||||
<td class="td" style="text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
|
||||
</tr><?php
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,12 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
|
||||
<h2><?php printf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ); ?> (<?php printf( '<time datetime="%s">%s</time>', date_i18n( 'c', strtotime( $order->order_date ) ), date_i18n( wc_date_format(), strtotime( $order->order_date ) ) ); ?>)</h2>
|
||||
|
||||
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%;" border="1">
|
||||
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;" border="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -55,8 +55,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
foreach ( $totals as $total ) {
|
||||
$i++;
|
||||
?><tr>
|
||||
<th class="td" scope="row" colspan="2" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
|
||||
<td class="td" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
|
||||
<td class="td" colspan="2" style="text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px !important;'; ?>"><?php echo $total['label']; ?></td>
|
||||
<td class="td" style="text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px !important;'; ?>"><?php echo strip_tags( $total['value'] ); ?></td>
|
||||
</tr><?php
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,12 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
|
||||
<h2><?php printf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ); ?></h2>
|
||||
|
||||
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%;" border="1">
|
||||
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;" border="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -43,8 +43,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
foreach ( $totals as $total ) {
|
||||
$i++;
|
||||
?><tr>
|
||||
<th class="td" scope="row" colspan="2" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
|
||||
<td class="td" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
|
||||
<th class="td" scope="row" colspan="2" style="text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
|
||||
<td class="td" style="text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
|
||||
</tr><?php
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
|
||||
<h2><?php printf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ); ?></h2>
|
||||
|
||||
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%;" border="1">
|
||||
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;" border="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -39,8 +39,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
foreach ( $totals as $total ) {
|
||||
$i++;
|
||||
?><tr>
|
||||
<th class="td" scope="row" colspan="2" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
|
||||
<td class="td" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
|
||||
<th class="td" scope="row" colspan="2" style="text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
|
||||
<td class="td" style="text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
|
||||
</tr><?php
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
|
||||
<?php do_action( 'woocommerce_email_header', $email_heading ); ?>
|
||||
|
||||
<p><?php
|
||||
<p><?php
|
||||
if ( $partial_refund ) {
|
||||
printf( __( "Hi there. Your order on %s has been partially refunded.", 'woocommerce' ), get_option( 'blogname' ) );
|
||||
}
|
||||
|
@ -28,12 +28,12 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
|
||||
<h2><?php printf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ); ?></h2>
|
||||
|
||||
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%;" border="1">
|
||||
<table class="td" cellspacing="0" cellpadding="6" style="width: 100%; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;" border="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Product', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Quantity', 'woocommerce' ); ?></th>
|
||||
<th class="td" scope="col" style="text-align:left;"><?php _e( 'Price', 'woocommerce' ); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -56,8 +56,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
foreach ( $totals as $total ) {
|
||||
$i++;
|
||||
?><tr>
|
||||
<th class="td" scope="row" colspan="2" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
|
||||
<td class="td" style="text-align:left; font-family: 'Helvetica Neue', Helvetica, Roboto, Arial, sans-serif; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
|
||||
<th class="td" scope="row" colspan="2" style="text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['label']; ?></th>
|
||||
<td class="td" style="text-align:left; <?php if ( $i == 1 ) echo 'border-top-width: 4px;'; ?>"><?php echo $total['value']; ?></td>
|
||||
</tr><?php
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* Product loop title
|
||||
*
|
||||
* @author WooThemes
|
||||
* @package WooCommerce/Templates
|
||||
* @version 2.4.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
?>
|
||||
<h3><?php the_title(); ?></h3>
|
|
@ -17,7 +17,7 @@ if ( $downloads = WC()->customer->get_downloadable_products() ) : ?>
|
|||
|
||||
<?php do_action( 'woocommerce_before_available_downloads' ); ?>
|
||||
|
||||
<h2><?php echo apply_filters( 'woocommerce_my_account_my_downloads_title', __( 'Available downloads', 'woocommerce' ) ); ?></h2>
|
||||
<h2><?php echo apply_filters( 'woocommerce_my_account_my_downloads_title', __( 'Available Downloads', 'woocommerce' ) ); ?></h2>
|
||||
|
||||
<ul class="digital-downloads">
|
||||
<?php foreach ( $downloads as $download ) : ?>
|
||||
|
|
|
@ -6,63 +6,34 @@
|
|||
* @package WooCommerce/Templates
|
||||
* @version 2.4.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
global $product, $post;
|
||||
?>
|
||||
global $product;
|
||||
|
||||
<?php do_action( 'woocommerce_before_add_to_cart_form' ); ?>
|
||||
$attribute_keys = array_keys( $attributes );
|
||||
|
||||
<form class="variations_form cart" method="post" enctype='multipart/form-data' data-product_id="<?php echo $post->ID; ?>" data-product_variations="<?php echo esc_attr( json_encode( $available_variations ) ) ?>">
|
||||
do_action( 'woocommerce_before_add_to_cart_form' ); ?>
|
||||
|
||||
<form class="variations_form cart" method="post" enctype='multipart/form-data' data-product_id="<?php echo absint( $product->id ); ?>" data-product_variations="<?php echo esc_attr( json_encode( $available_variations ) ) ?>">
|
||||
<?php do_action( 'woocommerce_before_variations_form' ); ?>
|
||||
|
||||
<?php if ( ! empty( $available_variations ) || false === $available_variations ) : ?>
|
||||
<?php if ( empty( $available_variations ) && false !== $available_variations ) : ?>
|
||||
<p class="stock out-of-stock"><?php _e( 'This product is currently out of stock and unavailable.', 'woocommerce' ); ?></p>
|
||||
<?php else : ?>
|
||||
<table class="variations" cellspacing="0">
|
||||
<tbody>
|
||||
<?php $loop = 0; foreach ( $attributes as $name => $options ) : $loop++; ?>
|
||||
<?php foreach ( $attributes as $attribute_name => $options ) : ?>
|
||||
<tr>
|
||||
<td class="label"><label for="<?php echo sanitize_title( $name ); ?>"><?php echo wc_attribute_label( $name ); ?></label></td>
|
||||
<td class="value"><select id="<?php echo esc_attr( sanitize_title( $name ) ); ?>" name="attribute_<?php echo sanitize_title( $name ); ?>" data-attribute_name="attribute_<?php echo sanitize_title( $name ); ?>">
|
||||
<option value=""><?php echo __( 'Choose an option', 'woocommerce' ) ?>…</option>
|
||||
<td class="label"><label for="<?php echo sanitize_title( $attribute_name ); ?>"><?php echo wc_attribute_label( $attribute_name ); ?></label></td>
|
||||
<td class="value">
|
||||
<?php
|
||||
if ( is_array( $options ) ) {
|
||||
|
||||
if ( isset( $_REQUEST[ 'attribute_' . sanitize_title( $name ) ] ) ) {
|
||||
$selected_value = $_REQUEST[ 'attribute_' . sanitize_title( $name ) ];
|
||||
} elseif ( isset( $selected_attributes[ sanitize_title( $name ) ] ) ) {
|
||||
$selected_value = $selected_attributes[ sanitize_title( $name ) ];
|
||||
} else {
|
||||
$selected_value = '';
|
||||
}
|
||||
|
||||
// Get terms if this is a taxonomy - ordered
|
||||
if ( taxonomy_exists( $name ) ) {
|
||||
|
||||
$terms = wc_get_product_terms( $post->ID, $name, array( 'fields' => 'all' ) );
|
||||
|
||||
foreach ( $terms as $term ) {
|
||||
if ( ! in_array( $term->slug, $options ) ) {
|
||||
continue;
|
||||
}
|
||||
echo '<option value="' . esc_attr( $term->slug ) . '" ' . selected( sanitize_title( $selected_value ), sanitize_title( $term->slug ), false ) . '>' . apply_filters( 'woocommerce_variation_option_name', $term->name ) . '</option>';
|
||||
}
|
||||
|
||||
} else {
|
||||
foreach ( $options as $option ) {
|
||||
echo '<option value="' . esc_attr( $option ) . '" ' . selected( $selected_value, $option, false ) . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ) . '</option>';
|
||||
}
|
||||
}
|
||||
}
|
||||
$selected = isset( $_REQUEST[ 'attribute_' . sanitize_title( $attribute_name ) ] ) ? wc_clean( $_REQUEST[ 'attribute_' . sanitize_title( $attribute_name ) ] ) : $product->get_variation_default_attribute( $attribute_name );
|
||||
wc_dropdown_variation_attribute_options( array( 'options' => $options, 'attribute' => $attribute_name, 'product' => $product, 'selected' => $selected ) );
|
||||
echo end( $attribute_keys ) === $attribute_name ? '<a class="reset_variations" href="#">' . __( 'Clear selection', 'woocommerce' ) . '</a>' : '';
|
||||
?>
|
||||
</select> <?php
|
||||
if ( sizeof( $attributes ) === $loop ) {
|
||||
echo '<a class="reset_variations" href="#">' . __( 'Clear selection', 'woocommerce' ) . '</a>';
|
||||
}
|
||||
?></td>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach;?>
|
||||
</tbody>
|
||||
|
@ -71,34 +42,31 @@ global $product, $post;
|
|||
<?php do_action( 'woocommerce_before_add_to_cart_button' ); ?>
|
||||
|
||||
<div class="single_variation_wrap" style="display:none;">
|
||||
<?php do_action( 'woocommerce_before_single_variation' ); ?>
|
||||
<?php
|
||||
/**
|
||||
* woocommerce_before_single_variation Hook
|
||||
*/
|
||||
do_action( 'woocommerce_before_single_variation' );
|
||||
|
||||
<div class="single_variation"></div>
|
||||
/**
|
||||
* woocommerce_single_variation hook. Used to output the cart button and placeholder for variation data.
|
||||
* @since 2.4.0
|
||||
* @hooked woocommerce_single_variation - 10 Empty div for variation data.
|
||||
* @hooked woocommerce_single_variation_add_to_cart_button - 20 Qty and cart button.
|
||||
*/
|
||||
do_action( 'woocommerce_single_variation' );
|
||||
|
||||
<?php do_action( 'woocommerce_before_variations_button' ); ?>
|
||||
|
||||
<div class="variations_button">
|
||||
<?php woocommerce_quantity_input( array(
|
||||
'input_value' => ( isset( $_POST['quantity'] ) ? wc_stock_amount( $_POST['quantity'] ) : 1 )
|
||||
) ); ?>
|
||||
<button type="submit" class="single_add_to_cart_button button alt"><?php echo esc_html( $product->single_add_to_cart_text() ); ?></button>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="add-to-cart" value="<?php echo $product->id; ?>" />
|
||||
<input type="hidden" name="product_id" value="<?php echo esc_attr( $post->ID ); ?>" />
|
||||
<input type="hidden" name="variation_id" class="variation_id" value="" />
|
||||
|
||||
<?php do_action( 'woocommerce_after_single_variation' ); ?>
|
||||
/**
|
||||
* woocommerce_after_single_variation Hook
|
||||
*/
|
||||
do_action( 'woocommerce_after_single_variation' );
|
||||
?>
|
||||
</div>
|
||||
|
||||
<?php do_action( 'woocommerce_after_add_to_cart_button' ); ?>
|
||||
|
||||
<?php else : ?>
|
||||
|
||||
<p class="stock out-of-stock"><?php _e( 'This product is currently out of stock and unavailable.', 'woocommerce' ); ?></p>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
<?php do_action( 'woocommerce_after_variations_form' ); ?>
|
||||
</form>
|
||||
|
||||
<?php do_action( 'woocommerce_after_add_to_cart_form' ); ?>
|
||||
|
|
|
@ -93,8 +93,8 @@ class WC_Helper_Product {
|
|||
// Attributes
|
||||
update_post_meta( $product_id, '_default_attributes', array() );
|
||||
update_post_meta( $product_id, '_product_attributes', array(
|
||||
'pa_dummyattribute' => array(
|
||||
'name' => 'pa_dummyattribute',
|
||||
'pa_size' => array(
|
||||
'name' => 'pa_size',
|
||||
'value' => '',
|
||||
'position' => '1',
|
||||
'is_visible' => 0,
|
||||
|
@ -239,4 +239,4 @@ class WC_Helper_Product {
|
|||
$wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_id = $attribute_id" );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ class Main_Class extends \WC_Unit_Test_Case {
|
|||
$this->assertInstanceOf( 'WC_Product_Factory', $this->wc->product_factory );
|
||||
$this->assertInstanceOf( 'WC_Order_Factory', $this->wc->order_factory );
|
||||
$this->assertInstanceOf( 'WC_Countries', $this->wc->countries );
|
||||
$this->assertInstanceOf( 'WC_Integrations', $this->wc->integrations );
|
||||
$this->assertInstanceOf( 'WC_Mock_Session_Handler', $this->wc->session );
|
||||
$this->assertInstanceOf( 'WC_Cart', $this->wc->cart );
|
||||
$this->assertInstanceOf( 'WC_Customer', $this->wc->customer );
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Plugin Name: WooCommerce
|
||||
* Plugin URI: http://www.woothemes.com/woocommerce/
|
||||
* Description: An e-commerce toolkit that helps you sell anything. Beautifully.
|
||||
* Version: 2.4.0-beta-3
|
||||
* Version: 2.4.0-beta-4
|
||||
* Author: WooThemes
|
||||
* Author URI: http://woothemes.com
|
||||
* Requires at least: 4.1
|
||||
|
|
Loading…
Reference in New Issue