Merge branch 'master' into shipping-zones

# Conflicts:
#	assets/css/admin.css
#	includes/admin/class-wc-admin-assets.php
This commit is contained in:
Mike Jolley 2016-02-10 14:12:39 +00:00
commit fab8a871aa
52 changed files with 1888 additions and 3126 deletions

File diff suppressed because one or more lines are too long

View File

@ -11,7 +11,6 @@
@import "mixins";
@import "variables";
@import "animation";
@import "chosen";
@import "select2";
@import "fonts";
@ -1640,12 +1639,18 @@ ul.order_notes {
border-color: #efefef transparent;
}
}
li.customer-note {
.note_content {
background: #A7CEDC;
}
.note_content:after {
border-color: #A7CEDC transparent;
}
}
li.system-note {
.note_content {
background: #d7cad2;
}
.note_content:after {
border-color: #d7cad2 transparent;
}

File diff suppressed because one or more lines are too long

View File

@ -1,474 +0,0 @@
/* WooCommerce styles */
.woocommerce-checkout .form-row {
.chosen-container {
width: 100% !important;
}
.chosen-container-single .chosen-single {
height: 28px;
line-height: 29px;
}
.chosen-container-single .chosen-single div b {
background: url('../images/chosen-sprite.png') no-repeat 0 3px !important;
}
.chosen-container-active .chosen-single-with-drop div b {
background-position: -18px 4px !important;
}
.chosen-container-single .chosen-search input {
line-height: 13px;
width: 100% !important;
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}
.chosen-container .chosen-drop {
width: 100% !important;
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
.woocommerce-checkout .form-row {
.chosen-container-single .chosen-single div b {
background-image: url('../images/chosen-sprite@2x.png') !important;
background-position: 0 5px !important;
background-repeat: no-repeat !important;
background-size: 52px 37px !important;
}
.chosen-container-active .chosen-single-with-drop div b {
background-position: -18px 5px !important;
}
}
}
/* @group Base */
.chosen-container {
position: relative;
display: inline-block;
vertical-align: middle;
font-size: 13px;
zoom: 1;
*display: inline;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.chosen-container .chosen-drop {
position: absolute;
top: 100%;
left: -9999px;
z-index: 1010;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 100%;
border: 1px solid #aaa;
border-top: 0;
background: #fff;
box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
}
.chosen-container.chosen-with-drop .chosen-drop {
left: 0;
}
.chosen-container a {
cursor: pointer;
}
/* @end */
/* @group Single Chosen */
.chosen-container-single .chosen-single {
position: relative;
display: block;
overflow: hidden;
padding: 0 0 0 8px;
height: 26px;
border: 1px solid #aaa;
border-radius: 5px;
background-color: #fff;
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background-clip: padding-box;
box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
color: #444;
text-decoration: none;
white-space: nowrap;
line-height: 26px;
}
.chosen-container-single .chosen-default {
color: #999;
}
.chosen-container-single .chosen-single span {
display: block;
overflow: hidden;
margin-right: 26px;
text-overflow: ellipsis;
white-space: nowrap;
}
.chosen-container-single .chosen-single-with-deselect span {
margin-right: 38px;
}
.chosen-container-single .chosen-single abbr {
position: absolute;
top: 6px;
right: 26px;
display: block;
width: 12px;
height: 12px;
background: url('../images/chosen-sprite.png') -42px 1px no-repeat;
font-size: 1px;
}
.chosen-container-single .chosen-single abbr:hover {
background-position: -42px -10px;
}
.chosen-container-single.chosen-disabled .chosen-single abbr:hover {
background-position: -42px -10px;
}
.chosen-container-single .chosen-single div {
position: absolute;
top: 0;
right: 0;
display: block;
width: 18px;
height: 100%;
}
.chosen-container-single .chosen-single div b {
display: block;
width: 100%;
height: 100%;
background: url('../images/chosen-sprite.png') no-repeat 0px 2px;
}
.chosen-container-single .chosen-search {
position: relative;
z-index: 1010;
margin: 0;
padding: 3px 4px;
white-space: nowrap;
}
.chosen-container-single .chosen-search input[type="text"] {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin: 1px 0;
padding: 4px 20px 4px 5px;
width: 100%;
height: auto;
outline: 0;
border: 1px solid #aaa;
background: white url('../images/chosen-sprite.png') no-repeat 100% -20px;
background: url('../images/chosen-sprite.png') no-repeat 100% -20px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
background: url('../images/chosen-sprite.png') no-repeat 100% -20px, -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
background: url('../images/chosen-sprite.png') no-repeat 100% -20px, -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
background: url('../images/chosen-sprite.png') no-repeat 100% -20px, -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
background: url('../images/chosen-sprite.png') no-repeat 100% -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
font-size: 1em;
font-family: sans-serif;
line-height: normal;
border-radius: 0;
}
.chosen-container-single .chosen-drop {
margin-top: -1px;
border-radius: 0 0 4px 4px;
background-clip: padding-box;
}
.chosen-container-single.chosen-container-single-nosearch .chosen-search {
position: absolute;
left: -9999px;
}
/* @end */
/* @group Results */
.chosen-container .chosen-results {
position: relative;
overflow-x: hidden;
overflow-y: auto;
margin: 0 4px 4px 0;
padding: 0 0 0 4px;
max-height: 240px;
-webkit-overflow-scrolling: touch;
}
.chosen-container .chosen-results li {
display: none;
margin: 0;
padding: 5px 6px;
list-style: none;
line-height: 15px;
}
.chosen-container .chosen-results li.active-result {
display: list-item;
cursor: pointer;
}
.chosen-container .chosen-results li.disabled-result {
display: list-item;
color: #ccc;
cursor: default;
}
.chosen-container .chosen-results li.highlighted {
background-color: #3875d7;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
color: #fff;
}
.chosen-container .chosen-results li.no-results {
display: list-item;
background: #f4f4f4;
}
.chosen-container .chosen-results li.group-result {
display: list-item;
font-weight: bold;
cursor: default;
}
.chosen-container .chosen-results li.group-option {
padding-left: 15px;
}
.chosen-container .chosen-results li em {
font-style: normal;
text-decoration: underline;
}
/* @end */
/* @group Multi Chosen */
.chosen-container-multi .chosen-choices {
position: relative;
overflow: hidden;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
width: 100%;
height: auto !important;
height: 1%;
border: 1px solid #aaa;
background-color: #fff;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
cursor: text;
}
.chosen-container-multi .chosen-choices li {
float: left;
list-style: none;
}
.chosen-container-multi .chosen-choices li.search-field {
margin: 0;
padding: 0;
white-space: nowrap;
}
.chosen-container-multi .chosen-choices li.search-field input[type="text"] {
margin: 1px 0;
padding: 5px;
height: 15px;
outline: 0;
border: 0 !important;
background: transparent !important;
box-shadow: none;
color: #666;
font-size: 100%;
font-family: sans-serif;
line-height: normal;
border-radius: 0;
}
.chosen-container-multi .chosen-choices li.search-field .default {
color: #999;
}
.chosen-container-multi .chosen-choices li.search-choice {
position: relative;
margin: 3px 0 3px 5px;
padding: 3px 20px 3px 5px;
border: 1px solid #aaa;
border-radius: 3px;
background-color: #e4e4e4;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-clip: padding-box;
box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
color: #333;
line-height: 13px;
cursor: default;
}
.chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
position: absolute;
top: 4px;
right: 3px;
display: block;
width: 12px;
height: 12px;
background: url('../images/chosen-sprite.png') -42px 1px no-repeat;
font-size: 1px;
}
.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
background-position: -42px -10px;
}
.chosen-container-multi .chosen-choices li.search-choice-disabled {
padding-right: 5px;
border: 1px solid #ccc;
background-color: #e4e4e4;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
color: #666;
}
.chosen-container-multi .chosen-choices li.search-choice-focus {
background: #d4d4d4;
}
.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
background-position: -42px -10px;
}
.chosen-container-multi .chosen-results {
margin: 0;
padding: 0;
}
.chosen-container-multi .chosen-drop .result-selected {
display: list-item;
color: #ccc;
cursor: default;
}
/* @end */
/* @group Active */
.chosen-container-active .chosen-single {
border: 1px solid #5897fb;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}
.chosen-container-active.chosen-with-drop .chosen-single {
border: 1px solid #aaa;
-moz-border-radius-bottomright: 0;
border-bottom-right-radius: 0;
-moz-border-radius-bottomleft: 0;
border-bottom-left-radius: 0;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
box-shadow: 0 1px 0 #fff inset;
}
.chosen-container-active.chosen-with-drop .chosen-single div {
border-left: none;
background: transparent;
}
.chosen-container-active.chosen-with-drop .chosen-single div b {
background-position: -18px 2px;
}
.chosen-container-active .chosen-choices {
border: 1px solid #5897fb;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}
.chosen-container-active .chosen-choices li.search-field input[type="text"] {
color: #111 !important;
}
/* @end */
/* @group Disabled Support */
.chosen-disabled {
opacity: 0.5 !important;
cursor: default;
}
.chosen-disabled .chosen-single {
cursor: default;
}
.chosen-disabled .chosen-choices .search-choice .search-choice-close {
cursor: default;
}
/* @end */
/* @group Right to Left */
.chosen-rtl {
text-align: right;
}
.chosen-rtl .chosen-single {
overflow: visible;
padding: 0 8px 0 0;
}
.chosen-rtl .chosen-single span {
margin-right: 0;
margin-left: 26px;
direction: rtl;
}
.chosen-rtl .chosen-single-with-deselect span {
margin-left: 38px;
}
.chosen-rtl .chosen-single div {
right: auto;
left: 3px;
}
.chosen-rtl .chosen-single abbr {
right: auto;
left: 26px;
}
.chosen-rtl .chosen-choices li {
float: right;
}
.chosen-rtl .chosen-choices li.search-field input[type="text"] {
direction: rtl;
}
.chosen-rtl .chosen-choices li.search-choice {
margin: 3px 5px 3px 0;
padding: 3px 5px 3px 19px;
}
.chosen-rtl .chosen-choices li.search-choice .search-choice-close {
right: auto;
left: 4px;
}
.chosen-rtl.chosen-container-single-nosearch .chosen-search,
.chosen-rtl .chosen-drop {
left: 9999px;
}
.chosen-rtl.chosen-container-single .chosen-results {
margin: 0 0 4px 4px;
padding: 0 4px 0 0;
}
.chosen-rtl .chosen-results li.group-option {
padding-right: 15px;
padding-left: 0;
}
.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
border-right: none;
}
.chosen-rtl .chosen-search input[type="text"] {
padding: 4px 5px 4px 20px;
background: white url('../images/chosen-sprite.png') no-repeat -30px -20px;
background: url('../images/chosen-sprite.png') no-repeat -30px -20px, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
background: url('../images/chosen-sprite.png') no-repeat -30px -20px, -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
background: url('../images/chosen-sprite.png') no-repeat -30px -20px, -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
background: url('../images/chosen-sprite.png') no-repeat -30px -20px, -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
background: url('../images/chosen-sprite.png') no-repeat -30px -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
direction: rtl;
}
.chosen-rtl.chosen-container-single .chosen-single div b {
background-position: 6px 2px;
}
.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
background-position: -12px 2px;
}
/* @end */
/* @group Retina compatibility */
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
.chosen-rtl .chosen-search input[type="text"],
.chosen-container-single .chosen-single abbr,
.chosen-container-single .chosen-single div b,
.chosen-container-single .chosen-search input[type="text"],
.chosen-container-multi .chosen-choices .search-choice .search-choice-close,
.chosen-container .chosen-results-scroll-down span,
.chosen-container .chosen-results-scroll-up span {
background-image: url('../images/chosen-sprite@2x.png') !important;
background-size: 52px 37px !important;
background-repeat: no-repeat !important;
}
}
/* @end */

File diff suppressed because one or more lines are too long

View File

@ -1509,6 +1509,43 @@ p.demo_store {
right: -1px;
}
}
/**
* Rating Filter Widget
*/
.widget_rating_filter {
ul {
margin: 0;
padding: 0;
border: 0;
list-style: none outside;
li {
@include clearfix();
padding: 0 0 1px;
list-style: none;
a {
padding: 1px 0;
text-decoration: none;
}
.star-rating {
float: none;
display: inline-block;
}
}
li.chosen {
a {
&:before {
@include iconbefore( "\e013" );
color: $red;
}
}
}
}
}
}
/**

View File

@ -1,81 +0,0 @@
// Generated by CoffeeScript 1.3.1
(function($) {
return $.fn.ajaxChosen = function(settings, callback) {
var chosenXhr, defaultOptions, options, select;
if (settings == null) {
settings = {};
}
if (callback == null) {
callback = function() {};
}
defaultOptions = {
minTermLength: 3,
afterTypeDelay: 500,
jsonTermKey: "term"
};
select = this;
chosenXhr = null;
options = $.extend({}, defaultOptions, settings);
this.chosen();
return this.each(function() {
return $(this).next('.chosen-container').find(".search-field > input, .chosen-search > input").bind('keyup', function() {
var field, msg, success, val;
val = $.trim($(this).attr('value'));
msg = val.length < options.minTermLength ? "Keep typing..." : "Looking for '" + val + "'";
select.next('.chosen-container').find('.no-results').text(msg);
if (val === $(this).data('prevVal')) {
return false;
}
$(this).data('prevVal', val);
if (this.timer) {
clearTimeout(this.timer);
}
if (val.length < options.minTermLength) {
return false;
}
field = $(this);
if (!(options.data != null)) {
options.data = {};
}
options.data[options.jsonTermKey] = val;
if (options.dataCallback != null) {
options.data = options.dataCallback(options.data);
}
success = options.success;
options.success = function(data) {
var items, selected_values;
if (!(data != null)) {
return;
}
selected_values = [];
select.find('option').each(function() {
if (!$(this).is(":selected")) {
return $(this).remove();
} else {
return selected_values.push($(this).val() + "-" + $(this).text());
}
});
items = callback(data);
$.each(items, function(value, text) {
if ($.inArray(value + "-" + text, selected_values) === -1) {
return $("<option />").attr('value', value).html(text).appendTo(select);
}
});
select.trigger("chosen:updated");
if (success != null) {
success(data);
}
field.attr('value', val);
return field.css('width', 'auto');
};
return this.timer = setTimeout(function() {
if (chosenXhr) {
chosenXhr.abort();
}
return chosenXhr = $.ajax(options);
}, options.afterTypeDelay);
});
});
};
})(jQuery);

View File

@ -1,2 +0,0 @@
// Generated by CoffeeScript 1.3.1
(function(e){return e.fn.ajaxChosen=function(t,n){var r,i,s,o;t==null&&(t={});n==null&&(n=function(){});i={minTermLength:3,afterTypeDelay:500,jsonTermKey:"term"};o=this;r=null;s=e.extend({},i,t);this.chosen();return this.each(function(){return e(this).next(".chosen-container").find(".search-field > input, .chosen-search > input").bind("keyup",function(){var t,i,u,a;a=e.trim(e(this).attr("value"));i=a.length<s.minTermLength?"Keep typing...":"Looking for '"+a+"'";o.next(".chosen-container").find(".no-results").text(i);if(a===e(this).data("prevVal"))return!1;e(this).data("prevVal",a);this.timer&&clearTimeout(this.timer);if(a.length<s.minTermLength)return!1;t=e(this);s.data==null&&(s.data={});s.data[s.jsonTermKey]=a;s.dataCallback!=null&&(s.data=s.dataCallback(s.data));u=s.success;s.success=function(r){var i,s;if(r==null)return;s=[];o.find("option").each(function(){return e(this).is(":selected")?s.push(e(this).val()+"-"+e(this).text()):e(this).remove()});i=n(r);e.each(i,function(t,n){if(e.inArray(t+"-"+n,s)===-1)return e("<option />").attr("value",t).html(n).appendTo(o)});o.trigger("chosen:updated");u!=null&&u(r);t.attr("value",a);return t.css("width","auto")};return this.timer=setTimeout(function(){r&&r.abort();return r=e.ajax(s)},s.afterTypeDelay)})})}})(jQuery);

View File

@ -1,6 +0,0 @@
jQuery(function($) {
// Fix Chosen for RTL
$('.chosen_select, .chosen_select_nostd, .product_attributes select.multiselect, select.country_select, select.state_select, select#dropdown_shop_coupon_type, select[name=m]').addClass('chosen-rtl');
});

View File

@ -1 +0,0 @@
jQuery(function(e){e(".chosen_select, .chosen_select_nostd, .product_attributes select.multiselect, select.country_select, select.state_select, select#dropdown_shop_coupon_type, select[name=m]").addClass("chosen-rtl")});

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -38,16 +38,30 @@
// When the variation is hidden
.on( 'hide_variation', function( event ) {
event.preventDefault();
$form.find( '.single_add_to_cart_button' ).attr( 'disabled', 'disabled' ).attr( 'title', wc_add_to_cart_variation_params.i18n_make_a_selection_text );
$form.find( '.single_add_to_cart_button' ).removeClass( 'wc-variation-is-unavailable' ).addClass( 'disabled wc-variation-selection-needed' );
} )
// When the variation is revealed
.on( 'show_variation', function( event, variation, purchasable ) {
event.preventDefault();
if ( purchasable ) {
$form.find( '.single_add_to_cart_button' ).removeAttr( 'disabled' ).removeAttr( 'title' );
$form.find( '.single_add_to_cart_button' ).removeClass( 'disabled wc-variation-selection-needed wc-variation-is-unavailable' );
} else {
$form.find( '.single_add_to_cart_button' ).attr( 'disabled', 'disabled' ).attr( 'title', wc_add_to_cart_variation_params.i18n_unavailable_text );
$form.find( '.single_add_to_cart_button' ).removeClass( 'wc-variation-selection-needed' ).addClass( 'disabled wc-variation-is-unavailable' );
}
} )
.on( 'click', '.single_add_to_cart_button', function( event ) {
var $this = $( this );
if ( $this.is('.disabled') ) {
event.preventDefault();
if ( $this.is('.wc-variation-is-unavailable') ) {
window.alert( wc_add_to_cart_variation_params.i18n_unavailable_text );
} else if ( $this.is('.wc-variation-selection-needed') ) {
window.alert( wc_add_to_cart_variation_params.i18n_make_a_selection_text );
}
}
} )

File diff suppressed because one or more lines are too long

View File

@ -82,9 +82,14 @@ jQuery( function( $ ) {
states = $.parseJSON( states_json );
$( document.body ).on( 'change', 'select.country_to_state, input.country_to_state', function() {
// Grab wrapping element to target only stateboxes in same 'group'
var $wrapper = $( this ).closest('.woocommerce-billing-fields, .woocommerce-shipping-fields, .woocommerce-shipping-calculator');
if ( ! $wrapper.size() ) {
$wrapper = $( this ).closest('.form-row').parent();
}
var country = $( this ).val(),
$wrapper = $( this ).closest('.form-row').parent(), // Grab wrapping form-row parent to target stateboxes in same 'group'
$statebox = $wrapper.find( '#billing_state, #shipping_state, #calc_shipping_state' ),
$parent = $statebox.parent(),
input_name = $statebox.attr( 'name' ),

View File

@ -1 +1 @@
jQuery(function(a){function b(){var a={formatMatches:function(a){return 1===a?wc_country_select_params.i18n_matches_1:wc_country_select_params.i18n_matches_n.replace("%qty%",a)},formatNoMatches:function(){return wc_country_select_params.i18n_no_matches},formatAjaxError:function(){return wc_country_select_params.i18n_ajax_error},formatInputTooShort:function(a,b){var c=b-a.length;return 1===c?wc_country_select_params.i18n_input_too_short_1:wc_country_select_params.i18n_input_too_short_n.replace("%qty%",c)},formatInputTooLong:function(a,b){var c=a.length-b;return 1===c?wc_country_select_params.i18n_input_too_long_1:wc_country_select_params.i18n_input_too_long_n.replace("%qty%",c)},formatSelectionTooBig:function(a){return 1===a?wc_country_select_params.i18n_selection_too_long_1:wc_country_select_params.i18n_selection_too_long_n.replace("%qty%",a)},formatLoadMore:function(){return wc_country_select_params.i18n_load_more},formatSearching:function(){return wc_country_select_params.i18n_searching}};return a}if("undefined"==typeof wc_country_select_params)return!1;if(a().select2){var c=function(){a("select.country_select:visible, select.state_select:visible").each(function(){var c=a.extend({placeholderOption:"first",width:"100%"},b());a(this).select2(c)})};c(),a(document.body).bind("country_to_state_changed",function(){c()})}var d=wc_country_select_params.countries.replace(/&quot;/g,'"'),e=a.parseJSON(d);a(document.body).on("change","select.country_to_state, input.country_to_state",function(){var b=a(this).val(),c=a(this).closest(".form-row").parent(),d=c.find("#billing_state, #shipping_state, #calc_shipping_state"),f=d.parent(),g=d.attr("name"),h=d.attr("id"),i=d.val(),j=d.attr("placeholder")||d.attr("data-placeholder")||"";if(e[b])if(a.isEmptyObject(e[b]))d.parent().hide().find(".select2-container").remove(),d.replaceWith('<input type="hidden" class="hidden" name="'+g+'" id="'+h+'" value="" placeholder="'+j+'" />'),a(document.body).trigger("country_to_state_changed",[b,c]);else{var k="",l=e[b];for(var m in l)l.hasOwnProperty(m)&&(k=k+'<option value="'+m+'">'+l[m]+"</option>");d.parent().show(),d.is("input")&&(d.replaceWith('<select name="'+g+'" id="'+h+'" class="state_select" data-placeholder="'+j+'"></select>'),d=c.find("#billing_state, #shipping_state, #calc_shipping_state")),d.html('<option value="">'+wc_country_select_params.i18n_select_state_text+"</option>"+k),d.val(i).change(),a(document.body).trigger("country_to_state_changed",[b,c])}else d.is("select")?(f.show().find(".select2-container").remove(),d.replaceWith('<input type="text" class="input-text" name="'+g+'" id="'+h+'" placeholder="'+j+'" />'),a(document.body).trigger("country_to_state_changed",[b,c])):d.is(".hidden")&&(f.show().find(".select2-container").remove(),d.replaceWith('<input type="text" class="input-text" name="'+g+'" id="'+h+'" placeholder="'+j+'" />'),a(document.body).trigger("country_to_state_changed",[b,c]));a(document.body).trigger("country_to_state_changing",[b,c])}),a(function(){a(":input.country_to_state").change()})});
jQuery(function(a){function b(){var a={formatMatches:function(a){return 1===a?wc_country_select_params.i18n_matches_1:wc_country_select_params.i18n_matches_n.replace("%qty%",a)},formatNoMatches:function(){return wc_country_select_params.i18n_no_matches},formatAjaxError:function(){return wc_country_select_params.i18n_ajax_error},formatInputTooShort:function(a,b){var c=b-a.length;return 1===c?wc_country_select_params.i18n_input_too_short_1:wc_country_select_params.i18n_input_too_short_n.replace("%qty%",c)},formatInputTooLong:function(a,b){var c=a.length-b;return 1===c?wc_country_select_params.i18n_input_too_long_1:wc_country_select_params.i18n_input_too_long_n.replace("%qty%",c)},formatSelectionTooBig:function(a){return 1===a?wc_country_select_params.i18n_selection_too_long_1:wc_country_select_params.i18n_selection_too_long_n.replace("%qty%",a)},formatLoadMore:function(){return wc_country_select_params.i18n_load_more},formatSearching:function(){return wc_country_select_params.i18n_searching}};return a}if("undefined"==typeof wc_country_select_params)return!1;if(a().select2){var c=function(){a("select.country_select:visible, select.state_select:visible").each(function(){var c=a.extend({placeholderOption:"first",width:"100%"},b());a(this).select2(c)})};c(),a(document.body).bind("country_to_state_changed",function(){c()})}var d=wc_country_select_params.countries.replace(/&quot;/g,'"'),e=a.parseJSON(d);a(document.body).on("change","select.country_to_state, input.country_to_state",function(){var b=a(this).closest(".woocommerce-billing-fields, .woocommerce-shipping-fields, .woocommerce-shipping-calculator");b.size()||(b=a(this).closest(".form-row").parent());var c=a(this).val(),d=b.find("#billing_state, #shipping_state, #calc_shipping_state"),f=d.parent(),g=d.attr("name"),h=d.attr("id"),i=d.val(),j=d.attr("placeholder")||d.attr("data-placeholder")||"";if(e[c])if(a.isEmptyObject(e[c]))d.parent().hide().find(".select2-container").remove(),d.replaceWith('<input type="hidden" class="hidden" name="'+g+'" id="'+h+'" value="" placeholder="'+j+'" />'),a(document.body).trigger("country_to_state_changed",[c,b]);else{var k="",l=e[c];for(var m in l)l.hasOwnProperty(m)&&(k=k+'<option value="'+m+'">'+l[m]+"</option>");d.parent().show(),d.is("input")&&(d.replaceWith('<select name="'+g+'" id="'+h+'" class="state_select" data-placeholder="'+j+'"></select>'),d=b.find("#billing_state, #shipping_state, #calc_shipping_state")),d.html('<option value="">'+wc_country_select_params.i18n_select_state_text+"</option>"+k),d.val(i).change(),a(document.body).trigger("country_to_state_changed",[c,b])}else d.is("select")?(f.show().find(".select2-container").remove(),d.replaceWith('<input type="text" class="input-text" name="'+g+'" id="'+h+'" placeholder="'+j+'" />'),a(document.body).trigger("country_to_state_changed",[c,b])):d.is(".hidden")&&(f.show().find(".select2-container").remove(),d.replaceWith('<input type="text" class="input-text" name="'+g+'" id="'+h+'" placeholder="'+j+'" />'),a(document.body).trigger("country_to_state_changed",[c,b]));a(document.body).trigger("country_to_state_changing",[c,b])}),a(function(){a(":input.country_to_state").change()})});

File diff suppressed because it is too large Load Diff

View File

@ -49,7 +49,6 @@ abstract class WC_Widget extends WP_Widget {
* Constructor.
*/
public function __construct() {
$widget_ops = array(
'classname' => $this->widget_cssclass,
'description' => $this->widget_description

View File

@ -106,12 +106,6 @@ class WC_Admin_Assets {
wp_register_script( 'wc-shipping-zones', WC()->plugin_url() . '/assets/js/admin/wc-shipping-zones' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-ui-sortable', 'wc-enhanced-select', 'wc-backbone-modal' ), WC_VERSION );
wp_register_script( 'wc-shipping-zone-methods', WC()->plugin_url() . '/assets/js/admin/wc-shipping-zone-methods' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone', 'jquery-ui-sortable' ), WC_VERSION );
wp_register_script( 'wc-shipping-classes', WC()->plugin_url() . '/assets/js/admin/wc-shipping-classes' . $suffix . '.js', array( 'jquery', 'wp-util', 'underscore', 'backbone' ), WC_VERSION );
// Chosen is @deprecated (2.3) in favour of select2, but is registered for backwards compat
wp_register_script( 'ajax-chosen', WC()->plugin_url() . '/assets/js/chosen/ajax-chosen.jquery' . $suffix . '.js', array( 'jquery', 'chosen' ), WC_VERSION );
wp_register_script( 'chosen', WC()->plugin_url() . '/assets/js/chosen/chosen.jquery' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
// Select2 is the replacement for chosen
wp_register_script( 'select2', WC()->plugin_url() . '/assets/js/select2/select2' . $suffix . '.js', array( 'jquery' ), '3.5.4' );
wp_register_script( 'wc-enhanced-select', WC()->plugin_url() . '/assets/js/admin/wc-enhanced-select' . $suffix . '.js', array( 'jquery', 'select2' ), WC_VERSION );
wp_localize_script( 'wc-enhanced-select', 'wc_enhanced_select_params', array(

View File

@ -47,21 +47,15 @@ class WC_Admin_Dashboard {
global $wpdb;
include_once( 'reports/class-wc-admin-report.php' );
include_once( 'reports/class-wc-report-sales-by-date.php' );
$reports = new WC_Admin_Report();
// Sales
$query = array();
$query['fields'] = "SELECT SUM( postmeta.meta_value ) FROM {$wpdb->posts} as posts";
$query['join'] = "INNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id LEFT JOIN {$wpdb->posts} AS parent ON posts.post_parent = parent.ID";
$query['where'] = "WHERE posts.post_type IN ( '" . implode( "','", array_merge( wc_get_order_types( 'sales-reports' ), array( 'shop_order_refund' ) ) ) . "' ) ";
$query['where'] .= "AND posts.post_status IN ( 'wc-" . implode( "','wc-", apply_filters( 'woocommerce_reports_order_statuses', array( 'completed', 'processing', 'on-hold' ) ) ) . "' ) ";
$query['where'] .= "AND ( parent.post_status IN ( 'wc-" . implode( "','wc-", apply_filters( 'woocommerce_reports_order_statuses', array( 'completed', 'processing', 'on-hold' ) ) ) . "' ) OR parent.ID IS NULL ) ";
$query['where'] .= "AND postmeta.meta_key = '_order_total' ";
$query['where'] .= "AND posts.post_date >= '" . date( 'Y-m-01', current_time( 'timestamp' ) ) . "' ";
$query['where'] .= "AND posts.post_date <= '" . date( 'Y-m-d H:i:s', current_time( 'timestamp' ) ) . "' ";
$sales = $wpdb->get_var( implode( ' ', apply_filters( 'woocommerce_dashboard_status_widget_sales_query', $query ) ) );
$reports = new WC_Admin_Report();
$sales_by_date = new WC_Report_Sales_By_Date();
$sales_by_date->start_date = strtotime( date( 'Y-m-01', current_time( 'timestamp' ) ) );
$sales_by_date->end_date = current_time( 'timestamp' );
$sales_by_date->chart_groupby = 'day';
$sales_by_date->group_by_query = 'YEAR(posts.post_date), MONTH(posts.post_date), DAY(posts.post_date)';
$report_data = $sales_by_date->get_report_data();
// Get top seller
$query = array();
@ -132,7 +126,7 @@ class WC_Admin_Dashboard {
<li class="sales-this-month">
<a href="<?php echo admin_url( 'admin.php?page=wc-reports&tab=orders&range=month' ); ?>">
<?php echo $reports->sales_sparkline( '', max( 7, date( 'd', current_time( 'timestamp' ) ) ) ); ?>
<?php printf( __( "<strong>%s</strong> sales this month", 'woocommerce' ), wc_price( $sales ) ); ?>
<?php printf( __( "<strong>%s</strong> net sales this month", 'woocommerce' ), wc_price( $report_data->net_sales ) ); ?>
</a>
</li>
<?php if ( $top_seller && $top_seller->qty ) : ?>

View File

@ -127,18 +127,10 @@ class WC_Admin_Meta_Boxes {
add_meta_box( 'woocommerce-order-notes', sprintf( __( '%s Notes', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Notes::output', $type, 'side', 'default' );
add_meta_box( 'woocommerce-order-downloads', __( 'Downloadable Product Permissions', 'woocommerce' ) . wc_help_tip( __( 'Note: Permissions for order items will automatically be granted when the order status changes to processing/completed.', 'woocommerce' ) ), 'WC_Meta_Box_Order_Downloads::output', $type, 'normal', 'default' );
add_meta_box( 'woocommerce-order-actions', sprintf( __( '%s Actions', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Actions::output', $type, 'side', 'high' );
remove_meta_box( 'submitdiv', $type, 'side' );
}
// Coupons
add_meta_box( 'woocommerce-coupon-data', __( 'Coupon Data', 'woocommerce' ), 'WC_Meta_Box_Coupon_Data::output', 'shop_coupon', 'normal', 'high' );
// Reviews
if ( $screen && 'comment' === $screen->id && isset( $_GET['c'] ) ) {
if ( get_comment_meta( intval( $_GET['c'] ), 'rating', true ) ) {
add_meta_box( 'woocommerce-rating', __( 'Rating', 'woocommerce' ), 'WC_Meta_Box_Order_Reviews::output', 'comment', 'normal', 'high' );
}
}
}
/**
@ -148,8 +140,9 @@ class WC_Admin_Meta_Boxes {
remove_meta_box( 'postexcerpt', 'product', 'normal' );
remove_meta_box( 'product_shipping_classdiv', 'product', 'side' );
remove_meta_box( 'pageparentdiv', 'product', 'side' );
remove_meta_box( 'commentstatusdiv', 'product', 'normal' );
remove_meta_box( 'commentsdiv', 'product', 'normal' );
remove_meta_box( 'commentstatusdiv', 'product', 'side' );
remove_meta_box( 'commentstatusdiv', 'product', 'normal' );
remove_meta_box( 'woothemes-settings', 'shop_coupon', 'normal' );
remove_meta_box( 'commentstatusdiv', 'shop_coupon', 'normal' );
remove_meta_box( 'slugdiv', 'shop_coupon', 'normal' );
@ -159,6 +152,7 @@ class WC_Admin_Meta_Boxes {
remove_meta_box( 'woothemes-settings', $type, 'normal' );
remove_meta_box( 'commentstatusdiv', $type, 'normal' );
remove_meta_box( 'slugdiv', $type, 'normal' );
remove_meta_box( 'submitdiv', $type, 'side' );
}
}

View File

@ -96,7 +96,7 @@ class WC_Admin_Permalink_Settings {
echo wpautop( __( 'These settings control the permalinks used specifically for products.', 'woocommerce' ) );
$permalinks = get_option( 'woocommerce_permalinks' );
$product_permalink = $permalinks['product_base'];
$product_permalink = isset( $permalinks['product_base'] ) ? $permalinks['product_base'] : '';
// Get shop page
$shop_page_id = wc_get_page_id( 'shop' );

View File

@ -417,7 +417,7 @@ class WC_Admin_Post_Types {
* Since WordPress 4.3 we don't have to build the row actions.
*
* @param WP_Post $post
* @param string $title
* @param string $title
*/
private function _render_product_row_actions( $post, $title ) {
global $wp_version;
@ -550,7 +550,7 @@ class WC_Admin_Post_Types {
* Since WordPress 4.3 we don't have to build the row actions.
*
* @param WP_Post $post
* @param string $title
* @param string $title
*/
private function _render_shop_coupon_row_actions( $post, $title ) {
global $wp_version;
@ -598,7 +598,7 @@ class WC_Admin_Post_Types {
/**
* Output custom columns for coupons.
* @param string $column
* @param string $column
*/
public function render_shop_order_columns( $column ) {
global $post, $woocommerce, $the_order;
@ -809,7 +809,7 @@ class WC_Admin_Post_Types {
/**
* Make columns sortable - https://gist.github.com/906872.
*
* @param array $columns
* @param array $columns
* @return array
*/
public function product_sortable_columns( $columns ) {
@ -825,7 +825,7 @@ class WC_Admin_Post_Types {
/**
* Make columns sortable - https://gist.github.com/906872.
*
* @param array $columns
* @param array $columns
* @return array
*/
public function shop_coupon_sortable_columns( $columns ) {
@ -835,7 +835,7 @@ class WC_Admin_Post_Types {
/**
* Make columns sortable - https://gist.github.com/906872.
*
* @param array $columns
* @param array $columns
* @return array
*/
public function shop_order_sortable_columns( $columns ) {
@ -903,13 +903,7 @@ class WC_Admin_Post_Types {
return array_merge( array( 'id' => 'ID: ' . $post->ID ), $actions );
}
if ( 'shop_order' === $post->post_type ) {
if ( isset( $actions['inline hide-if-no-js'] ) ) {
unset( $actions['inline hide-if-no-js'] );
}
}
if ( 'shop_coupon' === $post->post_type ) {
if ( in_array( $post->post_type, array( 'shop_order', 'shop_coupon' ) ) ) {
if ( isset( $actions['inline hide-if-no-js'] ) ) {
unset( $actions['inline hide-if-no-js'] );
}
@ -923,13 +917,13 @@ class WC_Admin_Post_Types {
*
* Based on Simple Page Ordering by 10up (http://wordpress.org/extend/plugins/simple-page-ordering/).
*
* @param array $views
* @param array $views
* @return array
*/
public function product_sorting_link( $views ) {
global $post_type, $wp_query;
if ( ! current_user_can('edit_others_pages') ) {
if ( ! current_user_can( 'edit_others_pages' ) ) {
return $views;
}
@ -1985,8 +1979,8 @@ class WC_Admin_Post_Types {
$user_id = get_post_meta( $id, '_customer_user', true );
if ( $user_id > 0 ) {
update_user_meta( $user_id, '_order_count', '' );
update_user_meta( $user_id, '_money_spent', '' );
delete_user_meta( $user_id, '_money_spent' );
delete_user_meta( $user_id, '_order_count' );
}
$refunds = $wpdb->get_results( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type = 'shop_order_refund' AND post_parent = %d", $id ) );
@ -2020,8 +2014,8 @@ class WC_Admin_Post_Types {
$user_id = get_post_meta( $id, '_customer_user', true );
if ( $user_id > 0 ) {
update_user_meta( $user_id, '_order_count', '' );
update_user_meta( $user_id, '_money_spent', '' );
delete_user_meta( $user_id, '_money_spent' );
delete_user_meta( $user_id, '_order_count' );
}
$refunds = $wpdb->get_results( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_type = 'shop_order_refund' AND post_parent = %d", $id ) );

View File

@ -301,24 +301,25 @@ class WC_Admin_Status {
/**
* Get latest version of a theme by slug.
* @param object $theme WP_Theme object
* @return string Version number if found
* @param object $theme WP_Theme object.
* @return string Version number if found.
*/
public static function get_latest_theme_version( $theme ) {
$api = themes_api( 'theme_information', array(
'slug' => $theme->get_stylesheet(),
'fields' => array(
'sections' => false,
'tags' => false
) ) );
'sections' => false,
'tags' => false,
)
) );
$update_theme_version = 0;
// Check .org for updates
if ( $api && ! is_wp_error( $api ) ) {
// Check .org for updates.
if ( is_object( $api ) && ! is_wp_error( $api ) ) {
$update_theme_version = $api->version;
// Check WooThemes Theme Version
// Check WooThemes Theme Version.
} elseif ( strstr( $theme->{'Author URI'}, 'woothemes' ) ) {
$theme_dir = substr( strtolower( str_replace( ' ','', $theme->Name ) ), 0, 45 );

View File

@ -45,9 +45,10 @@ class WC_Meta_Box_Order_Notes {
foreach( $notes as $note ) {
$note_classes = get_comment_meta( $note->comment_ID, 'is_customer_note', true ) ? array( 'customer-note', 'note' ) : array( 'note' );
$note_classes = apply_filters( 'woocommerce_order_note_class', $note_classes, $note );
$note_classes = array( 'note' );
$note_classes[] = get_comment_meta( $note->comment_ID, 'is_customer_note', true ) ? 'customer-note' : '';
$note_classes[] = $note->comment_author === __( 'WooCommerce', 'woocommerce' ) ? 'system-note' : '';
$note_classes = apply_filters( 'woocommerce_order_note_class', array_filter( $note_classes ), $note );
?>
<li rel="<?php echo absint( $note->comment_ID ) ; ?>" class="<?php echo esc_attr( implode( ' ', $note_classes ) ); ?>">
<div class="note_content">

View File

@ -1,62 +0,0 @@
<?php
/**
* Order Reviews
*
* Functions for displaying the order reviews data meta box.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Meta Boxes
* @version 2.1.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* WC_Meta_Box_Order_Reviews Class.
*/
class WC_Meta_Box_Order_Reviews {
/**
* Output the metabox.
*
* @param WP_Comment $comment
*/
public static function output( $comment ) {
wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
$current = get_comment_meta( $comment->comment_ID, 'rating', true );
?>
<select name="rating" id="rating">
<?php for ( $rating = 0; $rating <= 5; $rating++ ) {
echo sprintf( '<option value="%1$s"%2$s>%1$s</option>', $rating, selected( $current, $rating, false ) );
} ?>
</select>
<?php
}
/**
* Save meta box data.
*
* @param string $location
* @param int $comment_id
*/
public static function save( $location, $comment_id ) {
// Not allowed, return regular value without updating meta
if ( empty( $_POST['woocommerce_meta_nonce'] ) || ( ! wp_verify_nonce( $_POST['woocommerce_meta_nonce'], 'woocommerce_save_data' ) && ! isset( $_POST['rating'] ) ) ) {
return $location;
}
// Update meta
update_comment_meta(
$comment_id,
'rating',
intval( $_POST['rating'] )
);
// Return regular value after updating
return $location;
}
}

View File

@ -135,19 +135,6 @@ class WC_Meta_Box_Product_Data {
</ul>
<div id="general_product_data" class="panel woocommerce_options_panel"><?php
echo '<div class="options_group hide_if_grouped">';
// SKU
if ( wc_product_sku_enabled() ) {
woocommerce_wp_text_input( array( 'id' => '_sku', 'label' => '<abbr title="'. __( 'Stock Keeping Unit', 'woocommerce' ) .'">' . __( 'SKU', 'woocommerce' ) . '</abbr>', 'desc_tip' => 'true', 'description' => __( 'SKU refers to a Stock-keeping unit, a unique identifier for each distinct product and service that can be purchased.', 'woocommerce' ) ) );
} else {
echo '<input type="hidden" name="_sku" value="' . esc_attr( get_post_meta( $thepostid, '_sku', true ) ) . '" />';
}
do_action( 'woocommerce_product_options_sku' );
echo '</div>';
echo '<div class="options_group show_if_external">';
// External URL
@ -299,7 +286,16 @@ class WC_Meta_Box_Product_Data {
echo '<div class="options_group">';
if ( 'yes' == get_option( 'woocommerce_manage_stock' ) ) {
// SKU
if ( wc_product_sku_enabled() ) {
woocommerce_wp_text_input( array( 'id' => '_sku', 'label' => '<abbr title="'. __( 'Stock Keeping Unit', 'woocommerce' ) .'">' . __( 'SKU', 'woocommerce' ) . '</abbr>', 'desc_tip' => 'true', 'description' => __( 'SKU refers to a Stock-keeping unit, a unique identifier for each distinct product and service that can be purchased.', 'woocommerce' ) ) );
} else {
echo '<input type="hidden" name="_sku" value="' . esc_attr( get_post_meta( $thepostid, '_sku', true ) ) . '" />';
}
do_action( 'woocommerce_product_options_sku' );
if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) {
// manage stock
woocommerce_wp_checkbox( array( 'id' => '_manage_stock', 'wrapper_class' => 'show_if_simple show_if_variable', 'label' => __( 'Manage stock?', 'woocommerce' ), 'description' => __( 'Enable stock management at product level', 'woocommerce' ) ) );

View File

@ -505,7 +505,7 @@ class WC_Admin_Report {
$this->end_date = strtotime( 'midnight', strtotime( sanitize_text_field( $_GET['end_date'] ) ) );
if ( ! $this->end_date ) {
$this->end_date = current_time('timestamp');
$this->end_date = current_time( 'timestamp' );
}
$interval = 0;

View File

@ -132,6 +132,7 @@ class WC_Emails {
$this->emails['WC_Email_New_Order'] = include( 'emails/class-wc-email-new-order.php' );
$this->emails['WC_Email_Cancelled_Order'] = include( 'emails/class-wc-email-cancelled-order.php' );
$this->emails['WC_Email_Failed_Order'] = include( 'emails/class-wc-email-failed-order.php' );
$this->emails['WC_Email_Customer_On_Hold_Order'] = include( 'emails/class-wc-email-customer-on-hold-order.php' );
$this->emails['WC_Email_Customer_Processing_Order'] = include( 'emails/class-wc-email-customer-processing-order.php' );
$this->emails['WC_Email_Customer_Completed_Order'] = include( 'emails/class-wc-email-customer-completed-order.php' );
$this->emails['WC_Email_Customer_Refunded_Order'] = include( 'emails/class-wc-email-customer-refunded-order.php' );
@ -344,7 +345,7 @@ class WC_Emails {
'value' => wptexturize( $order->customer_note )
);
}
if ( $order->billing_email ) {
$fields['billing_email'] = array(
'label' => __( 'Email', 'woocommerce' ),

View File

@ -275,6 +275,8 @@ class WC_Form_Handler {
if ( $order->id == $order_id && $order->order_key == $order_key && $order->needs_payment() ) {
do_action( 'woocommerce_before_pay_action', $order );
// Set customer location to order location
if ( $order->billing_country ) {
WC()->customer->set_country( $order->billing_country );
@ -337,6 +339,9 @@ class WC_Form_Handler {
wp_safe_redirect( $order->get_checkout_order_received_url() );
exit;
}
do_action( 'woocommerce_after_pay_action', $order );
}
}

View File

@ -157,11 +157,8 @@ class WC_Frontend_Scripts {
$assets_path = str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/';
$frontend_script_path = $assets_path . 'js/frontend/';
// Chosen is @deprecated as of 2.3 in favour of 2.3. Here for backwards compatibility.
self::register_script( 'chosen', $assets_path . 'js/chosen/chosen.jquery' . $suffix . '.js', array( 'jquery' ), '1.0.0' );
self::register_script( 'select2', $assets_path . 'js/select2/select2' . $suffix . '.js', array( 'jquery' ), '3.5.4' );
// Register any scripts for later use, or used as dependencies
self::register_script( 'select2', $assets_path . 'js/select2/select2' . $suffix . '.js', array( 'jquery' ), '3.5.4' );
self::register_script( 'jquery-blockui', $assets_path . 'js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.70' );
self::register_script( 'jquery-payment', $assets_path . 'js/jquery-payment/jquery.payment' . $suffix . '.js', array( 'jquery' ), '1.2.4' );
self::register_script( 'jquery-cookie', $assets_path . 'js/jquery-cookie/jquery.cookie' . $suffix . '.js', array( 'jquery' ), '1.4.1' );
@ -317,7 +314,7 @@ class WC_Frontend_Scripts {
return array(
'i18n_no_matching_variations_text' => esc_attr__( 'Sorry, no products matched your selection. Please choose a different combination.', 'woocommerce' ),
'i18n_make_a_selection_text' => esc_attr__( 'Select product options before adding this product to your cart.', 'woocommerce' ),
'i18n_make_a_selection_text' => esc_attr__( 'Please select some product options before adding this product to your cart.', 'woocommerce' ),
'i18n_unavailable_text' => esc_attr__( 'Sorry, this product is unavailable. Please choose a different combination.', 'woocommerce' )
);
break;

View File

@ -53,6 +53,7 @@ class WC_Query {
add_action( 'init', array( $this, 'add_endpoints' ) );
add_action( 'init', array( $this, 'layered_nav_init' ) );
add_action( 'init', array( $this, 'price_filter_init' ) );
add_action( 'init', array( $this, 'rating_filter_init' ) );
if ( ! is_admin() ) {
add_action( 'wp_loaded', array( $this, 'get_errors' ), 20 );
@ -693,36 +694,32 @@ class WC_Query {
* Layered Nav Init.
*/
public function layered_nav_init( ) {
if ( apply_filters( 'woocommerce_is_layered_nav_active', is_active_widget( false, false, 'woocommerce_layered_nav', true ) ) && ! is_admin() ) {
global $_chosen_attributes;
$_chosen_attributes = array();
$attribute_taxonomies = wc_get_attribute_taxonomies();
if ( $attribute_taxonomies ) {
if ( $attribute_taxonomies = wc_get_attribute_taxonomies() ) {
foreach ( $attribute_taxonomies as $tax ) {
$attribute = wc_sanitize_taxonomy_name( $tax->attribute_name );
$taxonomy = wc_attribute_taxonomy_name( $attribute );
$name = 'filter_' . $attribute;
$filter_terms = ! empty( $_GET[ 'filter_' . $attribute ] ) ? explode( ',', wc_clean( $_GET[ 'filter_' . $attribute ] ) ) : array();
$query_type = ! empty( $_GET[ 'query_type_' . $attribute ] ) && in_array( $_GET[ 'query_type_' . $attribute ], array( 'and', 'or' ) ) ? wc_clean( $_GET[ 'query_type_' . $attribute ] ) : '';
$attribute = wc_sanitize_taxonomy_name( $tax->attribute_name );
$taxonomy = wc_attribute_taxonomy_name( $attribute );
$name = 'filter_' . $attribute;
$query_type_name = 'query_type_' . $attribute;
if ( ! empty( $_GET[ $name ] ) && taxonomy_exists( $taxonomy ) ) {
$_chosen_attributes[ $taxonomy ]['terms'] = explode( ',', $_GET[ $name ] );
if ( empty( $_GET[ $query_type_name ] ) || ! in_array( strtolower( $_GET[ $query_type_name ] ), array( 'and', 'or' ) ) )
$_chosen_attributes[ $taxonomy ]['query_type'] = apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' );
else
$_chosen_attributes[ $taxonomy ]['query_type'] = strtolower( $_GET[ $query_type_name ] );
if ( ! $query_type ) {
$query_type = apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' );
}
if ( ! empty( $filter_terms ) && taxonomy_exists( $taxonomy ) ) {
$_chosen_attributes[ $taxonomy ]['terms'] = array_map( 'sanitize_title', $filter_terms ); // Ensures correct encoding
$_chosen_attributes[ $taxonomy ]['query_type'] = $query_type;
}
}
}
add_filter('loop_shop_post_in', array( $this, 'layered_nav_query' ) );
add_filter( 'loop_shop_post_in', array( $this, 'layered_nav_query' ) );
}
}
@ -763,7 +760,7 @@ class WC_Query {
array(
'taxonomy' => $attribute,
'terms' => $value,
'field' => 'term_id'
'field' => 'slug'
)
)
);
@ -923,6 +920,58 @@ class WC_Query {
return (array) $filtered_posts;
}
/**
* Rating filter Init.
*/
public function rating_filter_init() {
if ( apply_filters( 'woocommerce_is_rating_filter_active', is_active_widget( false, false, 'woocommerce_rating_filter', true ) ) && ! is_admin() ) {
add_filter( 'loop_shop_post_in', array( $this, 'rating_filter' ) );
}
}
/**
* Rating Filter post filter.
*
* @param array $filtered_posts
* @return array
*/
public function rating_filter( $filtered_posts = array() ) {
global $wpdb;
if( isset( $_GET['min_rating'] ) ) {
$matched_products = array();
$min = isset( $_GET['min_rating'] ) ? floatval( $_GET['min_rating'] ) : 0;
$matched_products_query = apply_filters( 'woocommerce_rating_filter_results', $wpdb->get_results( $wpdb->prepare( "
SELECT comment_post_ID, ROUND( AVG( meta_value ), 2 ) as average_rating FROM {$wpdb->commentmeta}
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
WHERE meta_key = 'rating'
AND comment_approved = '1'
AND meta_value > 0
GROUP BY comment_post_ID
HAVING ROUND( AVG( meta_value ), 2 ) >= %d
", $min ), OBJECT_K ), $min );
if ( $matched_products_query ) {
foreach ( $matched_products_query as $commentmeta ) {
$matched_products[] = $commentmeta->comment_post_ID;
}
}
$matched_products = array_unique( $matched_products );
// Filter the id's
if ( 0 === sizeof( $filtered_posts ) ) {
$filtered_posts = $matched_products;
} else {
$filtered_posts = array_intersect( $filtered_posts, $matched_products );
}
$filtered_posts[] = 0;
}
return (array) $filtered_posts;
}
}
endif;

View File

@ -936,8 +936,10 @@ class WC_Tax {
$rates = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}woocommerce_tax_rates` WHERE `tax_rate_class` = %s ORDER BY `tax_rate_order`;", sanitize_title( $tax_class ) ) );
$locations = $wpdb->get_results( "SELECT * FROM `{$wpdb->prefix}woocommerce_tax_rate_locations`" );
// Set the rates keys equal to their ids.
$rates = array_combine( wp_list_pluck( $rates, 'tax_rate_id' ), $rates );
if ( ! empty( $rates ) ) {
// Set the rates keys equal to their ids.
$rates = array_combine( wp_list_pluck( $rates, 'tax_rate_id' ), $rates );
}
// Drop the locations into the rates array.
foreach ( $locations as $location ) {

View File

@ -70,6 +70,10 @@ class WC_Validation {
case 'US' :
$valid = (bool) preg_match( '/^([0-9]{5})(-[0-9]{4})?$/i', $postcode );
break;
case 'CA' :
// CA Postal codes cannot contain D,F,I,O,Q,U and cannot start with W or Z. https://en.wikipedia.org/wiki/Postal_codes_in_Canada#Number_of_possible_postal_codes
$valid = (bool) preg_match( '/^([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])([\ ])?(\d[ABCEGHJKLMNPRSTVWXYZ]\d)$/i', $postcode );
break;
default :
$valid = true;

View File

@ -0,0 +1,102 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( ! class_exists( 'WC_Email_Customer_Processing_Order' ) ) :
/**
* Customer On-hold Order Email.
*
* An email sent to the customer when a new order is on-hold for.
*
* @class WC_Email_Customer_On_Hold_Order
* @version 2.0.0
* @package WooCommerce/Classes/Emails
* @author WooThemes
* @extends WC_Email
*/
class WC_Email_Customer_On_Hold_Order extends WC_Email {
/**
* Constructor.
*/
function __construct() {
$this->id = 'customer_on_hold_order';
$this->customer_email = true;
$this->title = __( 'Order on-hold', 'woocommerce' );
$this->description = __( 'This is an order notification sent to customers containing order details after an order is placed on-hold.', 'woocommerce' );
$this->heading = __( 'Thank you for your order', 'woocommerce' );
$this->subject = __( 'Your {site_title} order receipt from {order_date}', 'woocommerce' );
$this->template_html = 'emails/customer-on-hold-order.php';
$this->template_plain = 'emails/plain/customer-on-hold-order.php';
// Triggers for this email
add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'trigger' ) );
// Call parent constructor
parent::__construct();
}
/**
* Trigger.
*
* @param int $order_id
*/
function trigger( $order_id ) {
if ( $order_id ) {
$this->object = wc_get_order( $order_id );
$this->recipient = $this->object->billing_email;
$this->find['order-date'] = '{order_date}';
$this->find['order-number'] = '{order_number}';
$this->replace['order-date'] = date_i18n( wc_date_format(), strtotime( $this->object->order_date ) );
$this->replace['order-number'] = $this->object->get_order_number();
}
if ( ! $this->is_enabled() || ! $this->get_recipient() ) {
return;
}
$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
}
/**
* Get content html.
*
* @access public
* @return string
*/
function get_content_html() {
return wc_get_template_html( $this->template_html, array(
'order' => $this->object,
'email_heading' => $this->get_heading(),
'sent_to_admin' => false,
'plain_text' => false,
'email' => $this
) );
}
/**
* Get content plain.
*
* @access public
* @return string
*/
function get_content_plain() {
return wc_get_template_html( $this->template_plain, array(
'order' => $this->object,
'email_heading' => $this->get_heading(),
'sent_to_admin' => false,
'plain_text' => true,
'email' => $this
) );
}
}
endif;
return new WC_Email_Customer_On_Hold_Order();

View File

@ -9,7 +9,7 @@ if ( ! class_exists( 'WC_Email_Customer_Processing_Order' ) ) :
/**
* Customer Processing Order Email.
*
* An email sent to the customer when a new order is received/paid for.
* An email sent to the customer when a new order is paid for.
*
* @class WC_Email_Customer_Processing_Order
* @version 2.0.0
@ -26,7 +26,7 @@ class WC_Email_Customer_Processing_Order extends WC_Email {
$this->id = 'customer_processing_order';
$this->customer_email = true;
$this->title = __( 'Processing order', 'woocommerce' );
$this->description = __( 'This is an order notification sent to customers containing their order details after payment.', 'woocommerce' );
$this->description = __( 'This is an order notification sent to customers containing order details after payment.', 'woocommerce' );
$this->heading = __( 'Thank you for your order', 'woocommerce' );
$this->subject = __( 'Your {site_title} order receipt from {order_date}', 'woocommerce' );
$this->template_html = 'emails/customer-processing-order.php';
@ -34,7 +34,6 @@ class WC_Email_Customer_Processing_Order extends WC_Email {
// Triggers for this email
add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'trigger' ) );
// Call parent constructor
parent::__construct();

View File

@ -60,12 +60,13 @@ class WC_Email_Customer_Refunded_Order extends WC_Email {
$this->heading_full = $this->get_option( 'heading_full', __( 'Your order has been fully refunded', 'woocommerce' ) );
$this->heading_partial = $this->get_option( 'heading_partial', __( 'Your order has been partially refunded', 'woocommerce' ) );
$this->template_html = 'emails/customer-refunded-order.php';
$this->template_plain = 'emails/plain/customer-refunded-order.php';
if ( $partial_refund ) {
$this->id = 'customer_partially_refunded_order';
$this->title = __( 'Partially Refunded order', 'woocommerce' );
$this->description = __( 'Order partially refunded emails are sent to customers when their orders are partially refunded.', 'woocommerce' );
$this->template_html = 'emails/customer-refunded-order.php';
$this->template_plain = 'emails/plain/customer-refunded-order.php';
$this->heading = $this->heading_partial;
$this->subject = $this->subject_partial;
}
@ -73,8 +74,6 @@ class WC_Email_Customer_Refunded_Order extends WC_Email {
$this->id = 'customer_refunded_order';
$this->title = __( 'Refunded order', 'woocommerce' );
$this->description = __( 'Order refunded emails are sent to customers when their orders are marked refunded.', 'woocommerce' );
$this->template_html = 'emails/customer-refunded-order.php';
$this->template_plain = 'emails/plain/customer-refunded-order.php';
$this->heading = $this->heading_full;
$this->subject = $this->subject_full;
}

View File

@ -161,13 +161,22 @@ class WC_Gateway_Paypal_Request {
*/
if ( ( ! wc_tax_enabled() || ! wc_prices_include_tax() ) && $this->prepare_line_items( $order ) ) {
$line_item_args = $this->get_line_items();
$line_item_args = array();
$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'] = $this->number_format( $this->round( $order->get_total_discount(), $order ), $order );
}
// Add shipping costs. Paypal ignores anything over 5 digits (999.99 is the max).
if ( $order->get_total_shipping() > 0 && $order->get_total_shipping() < 999.99 ) {
$line_item_args['shipping_1'] = $this->number_format( $order->get_total_shipping(), $order );
} elseif ( $order->get_total_shipping() > 0 ) {
$this->add_line_item( sprintf( __( 'Shipping via %s', 'woocommerce' ), $order->get_shipping_method() ), 1, $this->number_format( $order->get_total_shipping(), $order ) );
}
$line_item_args = array_merge( $line_item_args, $this->get_line_items() );
/**
* Send order as a single item.
*
@ -177,11 +186,18 @@ class WC_Gateway_Paypal_Request {
$this->delete_line_items();
$line_item_args = array();
$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();
// Add shipping costs. Paypal ignores anything over 5 digits (999.99 is the max).
if ( $order->get_total_shipping() > 0 && $order->get_total_shipping() < 999.99 ) {
$line_item_args['shipping_1'] = $this->number_format( $order->get_total_shipping() + $order->get_shipping_tax(), $order );
} elseif ( $order->get_total_shipping() > 0 ) {
$this->add_line_item( sprintf( __( 'Shipping via %s', 'woocommerce' ), $order->get_shipping_method() ), 1, $this->number_format( $order->get_total_shipping() + $order->get_shipping_tax(), $order ) );
}
$line_item_args = array_merge( $line_item_args, $this->get_line_items() );
}
return $line_item_args;
@ -260,11 +276,6 @@ 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, $this->round( $order->get_total_shipping(), $order ) ) ) {
return false;
}
// Check for mismatched totals.
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;

View File

@ -68,7 +68,7 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
'options' => array(
'' => __( 'N/A', 'woocommerce' ),
'coupon' => __( 'A valid free shipping coupon', 'woocommerce' ),
'min_amount' => __( 'A minimum order amount (defined below)', 'woocommerce' ),
'min_amount' => __( 'A minimum order amount', 'woocommerce' ),
'either' => __( 'A minimum order amount OR a coupon', 'woocommerce' ),
'both' => __( 'A minimum order amount AND a coupon', 'woocommerce' ),
)
@ -82,6 +82,18 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
'desc_tip' => true
)
);
wc_enqueue_js( "
jQuery( function( $ ) {
$('#woocommerce_free_shipping_requires').change(function(){
if ( $(this).val() === 'coupon' || $(this).val() === '' ) {
$('#woocommerce_free_shipping_min_amount').closest('tr').hide();
} else {
$('#woocommerce_free_shipping_min_amount').closest('tr').show();
}
}).change();
});
" );
}
/**

View File

@ -86,7 +86,7 @@ if ( ! function_exists( 'is_cart' ) ) {
* @return bool
*/
function is_cart() {
return is_page( wc_get_page_id( 'cart' ) ) || defined( 'WOOCOMMERCE_CART' );
return is_page( wc_get_page_id( 'cart' ) ) || defined( 'WOOCOMMERCE_CART' ) || wc_post_content_has_shortcode( 'woocommerce_cart' );
}
}
@ -97,7 +97,7 @@ if ( ! function_exists( 'is_checkout' ) ) {
* @return bool
*/
function is_checkout() {
return is_page( wc_get_page_id( 'checkout' ) ) || apply_filters( 'woocommerce_is_checkout', false );
return is_page( wc_get_page_id( 'checkout' ) ) || wc_post_content_has_shortcode( 'woocommerce_checkout' ) || apply_filters( 'woocommerce_is_checkout', false );
}
}
@ -153,7 +153,7 @@ if ( ! function_exists( 'is_account_page' ) ) {
* @return bool
*/
function is_account_page() {
return is_page( wc_get_page_id( 'myaccount' ) ) || apply_filters( 'woocommerce_is_account_page', false );
return is_page( wc_get_page_id( 'myaccount' ) ) || wc_post_content_has_shortcode( 'woocommerce_my_account' ) || apply_filters( 'woocommerce_is_account_page', false );
}
}
@ -362,7 +362,6 @@ function wc_is_webhook_valid_topic( $topic ) {
return false;
}
/**
* Simple check for validating a URL, it must start with http:// or https://.
* and pass FILTER_VALIDATE_URL validation.
@ -403,3 +402,15 @@ function wc_site_is_https() {
function wc_checkout_is_https() {
return wc_site_is_https() || 'yes' === get_option( 'woocommerce_force_ssl_checkout' ) || class_exists( 'WordPressHTTPS' ) || strstr( wc_get_page_permalink( 'checkout' ), 'https:' );
}
/**
* Checks whether the content passed contains a specific short code.
*
* @param string $tag Shortcode tag to check.
* @return bool
*/
function wc_post_content_has_shortcode( $tag = '' ) {
global $post;
return is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, $tag );
}

View File

@ -579,6 +579,12 @@ function wc_delete_shop_order_transients( $post_id = 0 ) {
delete_transient( $transient );
}
// Clear money spent for user associated with order
if ( $post_id && ( $user_id = get_post_meta( $post_id, '_customer_user', true ) ) ) {
delete_user_meta( $user_id, '_money_spent' );
delete_user_meta( $user_id, '_order_count' );
}
// Increments the transient version to invalidate cache
WC_Cache_Helper::get_transient_version( 'orders', true );

View File

@ -558,7 +558,7 @@ function woocommerce_template_loop_product_link_close() {
* Insert the opening anchor tag for categories in the loop.
*/
function woocommerce_template_loop_category_link_open( $category ) {
echo '<a href="' . get_term_link( $category->slug, 'product_cat' ) . '">';
echo '<a href="' . get_term_link( $category, 'product_cat' ) . '">';
}
/**
* Insert the opening anchor tag for categories in the loop.

View File

@ -24,6 +24,7 @@ include_once( 'widgets/class-wc-widget-product-categories.php' );
include_once( 'widgets/class-wc-widget-product-search.php' );
include_once( 'widgets/class-wc-widget-product-tag-cloud.php' );
include_once( 'widgets/class-wc-widget-products.php' );
include_once( 'widgets/class-wc-widget-rating-filter.php' );
include_once( 'widgets/class-wc-widget-recent-reviews.php' );
include_once( 'widgets/class-wc-widget-recently-viewed.php' );
include_once( 'widgets/class-wc-widget-top-rated-products.php' );
@ -42,6 +43,7 @@ function wc_register_widgets() {
register_widget( 'WC_Widget_Product_Search' );
register_widget( 'WC_Widget_Product_Tag_Cloud' );
register_widget( 'WC_Widget_Products' );
register_widget( 'WC_Widget_Rating_Filter' );
register_widget( 'WC_Widget_Recent_Reviews' );
register_widget( 'WC_Widget_Recently_Viewed' );
register_widget( 'WC_Widget_Top_Rated_Products' );

View File

@ -50,10 +50,13 @@ class WC_Widget_Layered_Nav_Filters extends WC_Widget {
}
// Price
$min_price = isset( $_GET['min_price'] ) ? esc_attr( $_GET['min_price'] ) : 0;
$max_price = isset( $_GET['max_price'] ) ? esc_attr( $_GET['max_price'] ) : 0;
$min_price = isset( $_GET['min_price'] ) ? wc_clean( $_GET['min_price'] ) : 0;
$max_price = isset( $_GET['max_price'] ) ? wc_clean( $_GET['max_price'] ) : 0;
if ( 0 < count( $_chosen_attributes ) || 0 < $min_price || 0 < $max_price ) {
// Rating
$min_rating = isset( $_GET['min_rating'] ) ? wc_clean( $_GET['min_rating'] ) : 0;
if ( 0 < count( $_chosen_attributes ) || 0 < $min_price || 0 < $max_price || 0 < $min_rating ) {
$this->widget_start( $args, $instance );
@ -62,26 +65,23 @@ class WC_Widget_Layered_Nav_Filters extends WC_Widget {
// Attributes
if ( ! is_null( $_chosen_attributes ) ) {
foreach ( $_chosen_attributes as $taxonomy => $data ) {
foreach ( $data['terms'] as $term_id ) {
$term = get_term( $term_id, $taxonomy );
if ( ! isset( $term->name ) ) {
foreach ( $data['terms'] as $term_slug ) {
if ( ! $term = get_term_by( 'slug', $term_slug, $taxonomy ) ) {
continue;
}
$taxonomy_filter = str_replace( 'pa_', '', $taxonomy );
$current_filter = ! empty( $_GET[ 'filter_' . $taxonomy_filter ] ) ? $_GET[ 'filter_' . $taxonomy_filter ] : '';
$new_filter = array_map( 'absint', explode( ',', $current_filter ) );
$new_filter = array_diff( $new_filter, array( $term_id ) );
$filter_name = 'filter_' . sanitize_title( str_replace( 'pa_', '', $taxonomy ) );
$current_filter = isset( $_GET[ $filter_name ] ) ? explode( ',', wc_clean( $_GET[ $filter_name ] ) ) : array();
$current_filter = array_map( 'sanitize_title', $current_filter );
$new_filter = array_diff( $current_filter, array( $term_slug ) );
$link = remove_query_arg( array( 'add-to-cart', 'filter_' . $taxonomy_filter ) );
$link = remove_query_arg( array( 'add-to-cart', $filter_name ) );
if ( sizeof( $new_filter ) > 0 ) {
$link = add_query_arg( 'filter_' . $taxonomy_filter, implode( ',', $new_filter ), $link );
$link = add_query_arg( $filter_name, implode( ',', $new_filter ), $link );
}
echo '<li class="chosen"><a title="' . esc_attr__( 'Remove filter', 'woocommerce' ) . '" href="' . esc_url( $link ) . '">' . $term->name . '</a></li>';
echo '<li class="chosen"><a title="' . esc_attr__( 'Remove filter', 'woocommerce' ) . '" href="' . esc_url( $link ) . '">' . esc_html( $term->name ) . '</a></li>';
}
}
}
@ -96,6 +96,11 @@ class WC_Widget_Layered_Nav_Filters extends WC_Widget {
echo '<li class="chosen"><a title="' . esc_attr__( 'Remove filter', 'woocommerce' ) . '" href="' . esc_url( $link ) . '">' . __( 'Max', 'woocommerce' ) . ' ' . wc_price( $max_price ) . '</a></li>';
}
if ( $min_rating ) {
$link = remove_query_arg( 'min_rating' );
echo '<li class="chosen"><a title="' . esc_attr__( 'Remove filter', 'woocommerce' ) . '" href="' . esc_url( $link ) . '">' . sprintf( __( 'Rated %s and above', 'woocommerce' ), $min_rating ) . '</a></li>';
}
echo '</ul>';
$this->widget_end( $args );

View File

@ -10,7 +10,7 @@ if ( ! defined( 'ABSPATH' ) ) {
* @author WooThemes
* @category Widgets
* @package WooCommerce/Widgets
* @version 2.3.0
* @version 2.6.0
* @extends WC_Widget
*/
class WC_Widget_Layered_Nav extends WC_Widget {
@ -23,7 +23,6 @@ class WC_Widget_Layered_Nav extends WC_Widget {
$this->widget_description = __( 'Shows a custom attribute in a widget which lets you narrow down the list of products when viewing product categories.', 'woocommerce' );
$this->widget_id = 'woocommerce_layered_nav';
$this->widget_name = __( 'WooCommerce Layered Nav', 'woocommerce' );
parent::__construct();
}
@ -39,7 +38,6 @@ class WC_Widget_Layered_Nav extends WC_Widget {
*/
public function update( $new_instance, $old_instance ) {
$this->init_settings();
return parent::update( $new_instance, $old_instance );
}
@ -52,7 +50,6 @@ class WC_Widget_Layered_Nav extends WC_Widget {
*/
public function form( $instance ) {
$this->init_settings();
parent::form( $instance );
}
@ -119,8 +116,6 @@ class WC_Widget_Layered_Nav extends WC_Widget {
return;
}
$current_term = is_tax() ? get_queried_object()->term_id : '';
$current_tax = is_tax() ? get_queried_object()->taxonomy : '';
$taxonomy = isset( $instance['attribute'] ) ? wc_attribute_taxonomy_name( $instance['attribute'] ) : $this->settings['attribute']['std'];
$query_type = isset( $instance['query_type'] ) ? $instance['query_type'] : $this->settings['query_type']['std'];
$display_type = isset( $instance['display_type'] ) ? $instance['display_type'] : $this->settings['display_type']['std'];
@ -150,242 +145,268 @@ class WC_Widget_Layered_Nav extends WC_Widget {
$terms = get_terms( $taxonomy, $get_terms_args );
if ( 0 < count( $terms ) ) {
if ( 0 === sizeof( $terms ) ) {
return;
}
ob_start();
ob_start();
$found = false;
$this->widget_start( $args, $instance );
$this->widget_start( $args, $instance );
if ( 'dropdown' === $display_type ) {
$found = $this->layered_nav_dropdown( $terms, $taxonomy, $query_type );
} else {
$found = $this->layered_nav_list( $terms, $taxonomy, $query_type );
}
// Force found when option is selected - do not force found on taxonomy attributes
if ( ! is_tax() && is_array( $_chosen_attributes ) && array_key_exists( $taxonomy, $_chosen_attributes ) ) {
$found = true;
}
$this->widget_end( $args );
if ( 'dropdown' == $display_type ) {
// Force found when option is selected - do not force found on taxonomy attributes
if ( ! is_tax() && is_array( $_chosen_attributes ) && array_key_exists( $taxonomy, $_chosen_attributes ) ) {
$found = true;
}
// skip when viewing the taxonomy
if ( $current_tax && $taxonomy == $current_tax ) {
if ( ! $found ) {
ob_end_clean();
} else {
echo ob_get_clean();
}
}
$found = false;
/**
* Return the currently viewed taxonomy name.
* @return string
*/
protected function get_current_taxonomy() {
return is_tax() ? get_queried_object()->taxonomy : '';
}
} else {
/**
* Return the currently viewed term ID.
* @return int
*/
protected function get_current_term_id() {
return absint( is_tax() ? get_queried_object()->term_id : 0 );
}
$taxonomy_filter = str_replace( 'pa_', '', $taxonomy );
/**
* Return the currently viewed term slug.
* @return int
*/
protected function get_current_term_slug() {
return absint( is_tax() ? get_queried_object()->slug : 0 );
}
$found = false;
/**
* Show dropdown layered nav.
* @param array $terms
* @param string $taxonomy
* @param string $query_type
* @return bool Will nav display?
*/
protected function layered_nav_dropdown( $terms, $taxonomy, $query_type ) {
global $_chosen_attributes;
echo '<select class="dropdown_layered_nav_' . $taxonomy_filter . '">';
$found = false;
echo '<option value="">' . sprintf( __( 'Any %s', 'woocommerce' ), wc_attribute_label( $taxonomy ) ) . '</option>';
if ( $taxonomy !== $this->get_current_taxonomy() ) {
$taxonomy_filter_name = str_replace( 'pa_', '', $taxonomy );
foreach ( $terms as $term ) {
echo '<select class="dropdown_layered_nav_' . esc_attr( $taxonomy_filter_name ) . '">';
echo '<option value="">' . sprintf( __( 'Any %s', 'woocommerce' ), wc_attribute_label( $taxonomy ) ) . '</option>';
// If on a term page, skip that term in widget list
if ( $term->term_id == $current_term ) {
continue;
}
// Get count based on current view
$_products_in_term = wc_get_term_product_ids( $term->term_id, $taxonomy );
$option_is_set = ( isset( $_chosen_attributes[ $taxonomy ] ) && in_array( $term->term_id, $_chosen_attributes[ $taxonomy ]['terms'] ) );
// If this is an AND query, only show options with count > 0
if ( 'and' == $query_type ) {
$count = sizeof( array_intersect( $_products_in_term, WC()->query->filtered_product_ids ) );
if ( 0 < $count ) {
$found = true;
}
if ( 0 == $count && ! $option_is_set ) {
continue;
}
// If this is an OR query, show all options so search can be expanded
} else {
$count = sizeof( array_intersect( $_products_in_term, WC()->query->unfiltered_product_ids ) );
if ( 0 < $count ) {
$found = true;
}
}
echo '<option value="' . esc_attr( $term->term_id ) . '" ' . selected( isset( $_GET[ 'filter_' . $taxonomy_filter ] ) ? $_GET[ 'filter_' . $taxonomy_filter ] : '' , $term->term_id, false ) . '>' . esc_html( $term->name ) . '</option>';
}
echo '</select>';
wc_enqueue_js( "
jQuery( '.dropdown_layered_nav_$taxonomy_filter' ).change( function() {
var term_id = parseInt( jQuery( this ).val(), 10 );
location.href = '" . preg_replace( '%\/page\/[0-9]+%', '', str_replace( array( '&amp;', '%2C' ), array( '&', ',' ), esc_js( add_query_arg( 'filtering', '1', remove_query_arg( array( 'page', 'filter_' . $taxonomy_filter ) ) ) ) ) ) . "&filter_$taxonomy_filter=' + ( isNaN( term_id ) ? '' : term_id );
});
" );
foreach ( $terms as $term ) {
// If on a term page, skip that term in widget list
if ( $term->term_id === $this->get_current_term_id() ) {
continue;
}
} else {
// Get count based on current view
$_products_in_term = wc_get_term_product_ids( $term->term_id, $taxonomy );
$current_values = isset( $_chosen_attributes[ $taxonomy ]['terms'] ) ? $_chosen_attributes[ $taxonomy ]['terms'] : array();
$option_is_set = in_array( $term->slug, $current_values );
// List display
echo '<ul>';
// If this is an AND query, only show options with count > 0
if ( 'and' === $query_type ) {
$count = sizeof( array_intersect( $_products_in_term, WC()->query->filtered_product_ids ) );
foreach ( $terms as $term ) {
if ( 0 < $count ) {
$found = true;
}
// Get count based on current view - uses transients
$_products_in_term = wc_get_term_product_ids( $term->term_id, $taxonomy );
$option_is_set = ( isset( $_chosen_attributes[ $taxonomy ] ) && in_array( $term->term_id, $_chosen_attributes[ $taxonomy ]['terms'] ) );
// skip the term for the current archive
if ( $current_term == $term->term_id ) {
if ( 0 === $count && ! $option_is_set ) {
continue;
}
// If this is an AND query, only show options with count > 0
if ( 'and' == $query_type ) {
// If this is an OR query, show all options so search can be expanded
} else {
$count = sizeof( array_intersect( $_products_in_term, WC()->query->unfiltered_product_ids ) );
$count = sizeof( array_intersect( $_products_in_term, WC()->query->filtered_product_ids ) );
if ( 0 < $count && $current_term !== $term->term_id ) {
$found = true;
}
if ( 0 == $count && ! $option_is_set ) {
continue;
}
// If this is an OR query, show all options so search can be expanded
} else {
$count = sizeof( array_intersect( $_products_in_term, WC()->query->unfiltered_product_ids ) );
if ( 0 < $count ) {
$found = true;
}
if ( 0 < $count ) {
$found = true;
}
$arg = 'filter_' . sanitize_title( $instance['attribute'] );
$current_filter = ( isset( $_GET[ $arg ] ) ) ? explode( ',', $_GET[ $arg ] ) : array();
if ( ! is_array( $current_filter ) ) {
$current_filter = array();
}
$current_filter = array_map( 'esc_attr', $current_filter );
if ( ! in_array( $term->term_id, $current_filter ) ) {
$current_filter[] = $term->term_id;
}
// Base Link decided by current page
if ( defined( 'SHOP_IS_ON_FRONT' ) ) {
$link = home_url();
} elseif ( is_post_type_archive( 'product' ) || is_page( wc_get_page_id('shop') ) ) {
$link = get_post_type_archive_link( 'product' );
} else {
$link = get_term_link( get_query_var('term'), get_query_var('taxonomy') );
}
// All current filters
if ( $_chosen_attributes ) {
foreach ( $_chosen_attributes as $name => $data ) {
if ( $name !== $taxonomy ) {
// Exclude query arg for current term archive term
while ( in_array( $current_term, $data['terms'] ) ) {
$key = array_search( $current_term, $data );
unset( $data['terms'][$key] );
}
// Remove pa_ and sanitize
$filter_name = sanitize_title( str_replace( 'pa_', '', $name ) );
if ( ! empty( $data['terms'] ) ) {
$link = add_query_arg( 'filter_' . $filter_name, implode( ',', $data['terms'] ), $link );
}
if ( 'or' == $data['query_type'] ) {
$link = add_query_arg( 'query_type_' . $filter_name, 'or', $link );
}
}
}
}
// Min/Max
if ( isset( $_GET['min_price'] ) ) {
$link = add_query_arg( 'min_price', $_GET['min_price'], $link );
}
if ( isset( $_GET['max_price'] ) ) {
$link = add_query_arg( 'max_price', $_GET['max_price'], $link );
}
// Orderby
if ( isset( $_GET['orderby'] ) ) {
$link = add_query_arg( 'orderby', $_GET['orderby'], $link );
}
// Current Filter = this widget
if ( isset( $_chosen_attributes[ $taxonomy ] ) && is_array( $_chosen_attributes[ $taxonomy ]['terms'] ) && in_array( $term->term_id, $_chosen_attributes[ $taxonomy ]['terms'] ) ) {
$class = 'class="chosen"';
// Remove this term is $current_filter has more than 1 term filtered
if ( sizeof( $current_filter ) > 1 ) {
$current_filter_without_this = array_diff( $current_filter, array( $term->term_id ) );
$link = add_query_arg( $arg, implode( ',', $current_filter_without_this ), $link );
}
} else {
$class = '';
$link = add_query_arg( $arg, implode( ',', $current_filter ), $link );
}
// Search Arg
if ( get_search_query() ) {
$link = add_query_arg( 's', get_search_query(), $link );
}
// Post Type Arg
if ( isset( $_GET['post_type'] ) ) {
$link = add_query_arg( 'post_type', $_GET['post_type'], $link );
}
// Query type Arg
if ( $query_type == 'or' && ! ( sizeof( $current_filter ) == 1 && isset( $_chosen_attributes[ $taxonomy ]['terms'] ) && is_array( $_chosen_attributes[ $taxonomy ]['terms'] ) && in_array( $term->term_id, $_chosen_attributes[ $taxonomy ]['terms'] ) ) ) {
$link = add_query_arg( 'query_type_' . sanitize_title( $instance['attribute'] ), 'or', $link );
}
echo '<li ' . $class . '>';
echo ( $count > 0 || $option_is_set ) ? '<a href="' . esc_url( apply_filters( 'woocommerce_layered_nav_link', $link ) ) . '">' : '<span>';
echo $term->name;
echo ( $count > 0 || $option_is_set ) ? '</a>' : '</span>';
echo ' <span class="count">(' . $count . ')</span></li>';
}
echo '</ul>';
} // End display type conditional
$this->widget_end( $args );
if ( ! $found ) {
ob_end_clean();
} else {
echo ob_get_clean();
echo '<option value="' . esc_attr( $term->slug ) . '" ' . selected( $option_is_set, true, false ) . '>' . esc_html( $term->name ) . '</option>';
}
echo '</select>';
wc_enqueue_js( "
jQuery( '.dropdown_layered_nav_". esc_js( $taxonomy_filter_name ) . "' ).change( function() {
var slug = jQuery( this ).val();
location.href = '" . preg_replace( '%\/page\/[0-9]+%', '', str_replace( array( '&amp;', '%2C' ), array( '&', ',' ), esc_js( add_query_arg( 'filtering', '1', remove_query_arg( array( 'page', 'filter_' . $taxonomy_filter_name ) ) ) ) ) ) . "&filter_". esc_js( $taxonomy_filter_name ) . "=' + slug;
});
" );
}
return $found;
}
/**
* Get current page URL for layered nav items.
* @return string
*/
protected function get_page_base_url() {
if ( defined( 'SHOP_IS_ON_FRONT' ) ) {
$link = home_url();
} elseif ( is_post_type_archive( 'product' ) || is_page( wc_get_page_id('shop') ) ) {
$link = get_post_type_archive_link( 'product' );
} else {
$link = get_term_link( get_query_var('term'), get_query_var('taxonomy') );
}
// Min/Max
if ( isset( $_GET['min_price'] ) ) {
$link = add_query_arg( 'min_price', wc_clean( $_GET['min_price'] ), $link );
}
if ( isset( $_GET['max_price'] ) ) {
$link = add_query_arg( 'max_price', wc_clean( $_GET['max_price'] ), $link );
}
// Orderby
if ( isset( $_GET['orderby'] ) ) {
$link = add_query_arg( 'orderby', wc_clean( $_GET['orderby'] ), $link );
}
// Search Arg
if ( get_search_query() ) {
$link = add_query_arg( 's', get_search_query(), $link );
}
// Post Type Arg
if ( isset( $_GET['post_type'] ) ) {
$link = add_query_arg( 'post_type', wc_clean( $_GET['post_type'] ), $link );
}
// Min Rating Arg
if ( isset( $_GET['min_rating'] ) ) {
$link = add_query_arg( 'min_rating', wc_clean( $_GET['min_rating'] ), $link );
}
return $link;
}
/**
* Show list based layered nav.
* @param array $terms
* @param string $taxonomy
* @param string $query_type
* @return bool Will nav display?
*/
protected function layered_nav_list( $terms, $taxonomy, $query_type ) {
global $_chosen_attributes;
// List display
echo '<ul>';
// flip the filtered_products_ids array so that we can use the more efficient array_intersect_key
$filtered_product_ids = array_flip( WC()->query->filtered_product_ids );
$unfiltered_product_ids = array_flip( WC()->query->unfiltered_product_ids );
$found = false;
foreach ( $terms as $term ) {
// Get count based on current view - uses transients
// flip the product_in_term array so that we can use array_intersect_key
$_products_in_term = array_flip( wc_get_term_product_ids( $term->term_id, $taxonomy ) );
$current_values = isset( $_chosen_attributes[ $taxonomy ]['terms'] ) ? $_chosen_attributes[ $taxonomy ]['terms'] : array();
$option_is_set = in_array( $term->slug, $current_values );
// skip the term for the current archive
if ( $this->get_current_term_id() === $term->term_id ) {
continue;
}
// If this is an AND query, only show options with count > 0
if ( 'and' === $query_type ) {
// Intersect both arrays now they have been flipped so that we can use their keys
$count = sizeof( array_intersect_key( $_products_in_term, $filtered_product_ids ) );
if ( 0 < $count ) {
$found = true;
}
if ( 0 === $count && ! $option_is_set ) {
continue;
}
// If this is an OR query, show all options so search can be expanded
} else {
// Intersect both arrays now they have been flipped so that we can use their keys
$count = sizeof( array_intersect_key( $_products_in_term, $unfiltered_product_ids ) );
if ( 0 < $count ) {
$found = true;
}
}
$filter_name = 'filter_' . sanitize_title( str_replace( 'pa_', '', $taxonomy ) );
$current_filter = isset( $_GET[ $filter_name ] ) ? explode( ',', wc_clean( $_GET[ $filter_name ] ) ) : array();
$current_filter = array_map( 'sanitize_title', $current_filter );
if ( ! in_array( $term->slug, $current_filter ) ) {
$current_filter[] = $term->slug;
}
$link = $this->get_page_base_url();
// Add current filters to URL.
foreach ( $current_filter as $key => $value ) {
// Exclude query arg for current term archive term
if ( $value === $this->get_current_term_slug() ) {
unset( $current_filter[ $key ] );
}
// Exclude self so filter can be unset on click.
if ( $option_is_set && $value === $term->slug ) {
unset( $current_filter[ $key ] );
}
}
if ( ! empty( $current_filter ) ) {
$link = add_query_arg( $filter_name, implode( ',', $current_filter ), $link );
// Add Query type Arg to URL
if ( $query_type === 'or' && ! ( 1 === sizeof( $current_filter ) && $option_is_set ) ) {
$link = add_query_arg( 'query_type_' . sanitize_title( str_replace( 'pa_', '', $taxonomy ) ), 'or', $link );
}
}
echo '<li class="wc-layered-nav-term ' . ( $option_is_set ? 'chosen' : '' ) . '">';
echo ( $count > 0 || $option_is_set ) ? '<a href="' . esc_url( apply_filters( 'woocommerce_layered_nav_link', $link ) ) . '">' : '<span>';
echo esc_html( $term->name );
echo ( $count > 0 || $option_is_set ) ? '</a>' : '</span>';
echo ' <span class="count">(' . absint( $count ) . ')</span></li>';
}
echo '</ul>';
return $found;
}
}

View File

@ -83,6 +83,10 @@ class WC_Widget_Price_Filter extends WC_Widget {
$fields .= '<input type="hidden" name="orderby" value="' . esc_attr( $_GET['orderby'] ) . '" />';
}
if ( ! empty( $_GET['min_rating'] ) ) {
$fields .= '<input type="hidden" name="min_rating" value="' . esc_attr( $_GET['min_rating'] ) . '" />';
}
if ( $_chosen_attributes ) {
foreach ( $_chosen_attributes as $attribute => $data ) {
$taxonomy_filter = 'filter_' . str_replace( 'pa_', '', $attribute );

View File

@ -0,0 +1,123 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Rating Filter Widget and related functions.
*
*
* @author WooThemes
* @category Widgets
* @package WooCommerce/Widgets
* @version 2.6.0
* @extends WC_Widget
*/
class WC_Widget_Rating_Filter extends WC_Widget {
/**
* Constructor.
*/
public function __construct() {
$this->widget_cssclass = 'woocommerce widget_rating_filter';
$this->widget_description = __( 'Filter products by rating when viewing product archives and categories.', 'woocommerce' );
$this->widget_id = 'woocommerce_rating_filter';
$this->widget_name = __( 'WooCommerce Average Rating Filter', 'woocommerce' );
$this->settings = array(
'title' => array(
'type' => 'text',
'std' => __( 'Average Rating', 'woocommerce' ),
'label' => __( 'Title', 'woocommerce' )
)
);
parent::__construct();
}
/**
* Get current page URL for layered nav items.
* @return string
*/
protected function get_page_base_url() {
if ( defined( 'SHOP_IS_ON_FRONT' ) ) {
$link = home_url();
} elseif ( is_post_type_archive( 'product' ) || is_page( wc_get_page_id('shop') ) ) {
$link = get_post_type_archive_link( 'product' );
} else {
$link = get_term_link( get_query_var('term'), get_query_var('taxonomy') );
}
// Min/Max
if ( isset( $_GET['min_price'] ) ) {
$link = add_query_arg( 'min_price', wc_clean( $_GET['min_price'] ), $link );
}
if ( isset( $_GET['max_price'] ) ) {
$link = add_query_arg( 'max_price', wc_clean( $_GET['max_price'] ), $link );
}
// Orderby
if ( isset( $_GET['orderby'] ) ) {
$link = add_query_arg( 'orderby', wc_clean( $_GET['orderby'] ), $link );
}
// Search Arg
if ( get_search_query() ) {
$link = add_query_arg( 's', get_search_query(), $link );
}
// Post Type Arg
if ( isset( $_GET['post_type'] ) ) {
$link = add_query_arg( 'post_type', wc_clean( $_GET['post_type'] ), $link );
}
return $link;
}
/**
* widget function.
*
* @see WP_Widget
*
* @param array $args
* @param array $instance
*/
public function widget( $args, $instance ) {
global $_chosen_attributes, $wpdb, $wp;
if ( ! is_post_type_archive( 'product' ) && ! is_tax( get_object_taxonomies( 'product' ) ) ) {
return;
}
if ( ! sizeof( WC()->query->unfiltered_product_ids ) ) {
return; // None shown - return
}
$min_rating = isset( $_GET['min_rating'] ) ? absint( $_GET['min_rating'] ) : '';
$this->widget_start( $args, $instance );
echo '<ul>';
for ( $rating = 4; $rating >= 1; $rating-- ) {
$link = $this->get_page_base_url();
$link = $min_rating !== $rating ? add_query_arg( 'min_rating', $rating, $link ) : $link;
echo '<li class="wc-layered-nav-rating ' . ( ! empty( $_GET['min_rating'] ) && $rating === absint( $_GET['min_rating'] ) ? 'chosen' : '' ) . '">';
echo '<a href="' . esc_url( apply_filters( 'woocommerce_rating_filter_link', $link ) ) . '">';
echo '<span class="star-rating" title="' . esc_attr( sprintf( __( 'Rated %s and above', 'woocommerce' ), $rating ) ). '">
<span style="width:' . esc_attr( ( $rating / 5 ) * 100 ) . '%">' . sprintf( __( 'Rated %s and above', 'woocommerce'), $rating ) . '</span>
</span>';
echo '</a>';
echo '</li>';
}
echo '</ul>';
$this->widget_end( $args );
}
}

View File

@ -0,0 +1,51 @@
<?php
/**
* Customer on-hold order email
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/customer-processing-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates/Emails
* @version 2.5.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* @hooked WC_Emails::email_header() Output the email header
*/
do_action( 'woocommerce_email_header', $email_heading, $email ); ?>
<p><?php _e( "Your order is on-hold until we confirm payment has been received. Your order details are shown below for your reference:", 'woocommerce' ); ?></p>
<?php
/**
* @hooked WC_Emails::order_details() Shows the order details table.
* @since 2.5.0
*/
do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );
/**
* @hooked WC_Emails::order_meta() Shows order meta data.
*/
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );
/**
* @hooked WC_Emails::customer_details() Shows customer details
* @hooked WC_Emails::email_address() Shows email address
*/
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );
/**
* @hooked WC_Emails::email_footer() Output the email footer
*/
do_action( 'woocommerce_email_footer', $email );

View File

@ -0,0 +1,49 @@
<?php
/**
* Customer on-hold order email
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/customer-processing-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates/Emails/Plain
* @version 2.5.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
echo "= " . $email_heading . " =\n\n";
echo __( "Your order is on-hold until we confirm payment has been received. Your order details are shown below for your reference:", 'woocommerce' ) . "\n\n";
echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
/**
* @hooked WC_Emails::order_details() Shows the order details table.
* @since 2.5.0
*/
do_action( 'woocommerce_email_order_details', $order, $sent_to_admin, $plain_text, $email );
echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
/**
* @hooked WC_Emails::order_meta() Shows order meta data.
*/
do_action( 'woocommerce_email_order_meta', $order, $sent_to_admin, $plain_text, $email );
/**
* @hooked WC_Emails::customer_details() Shows customer details
* @hooked WC_Emails::email_address() Shows email address
*/
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );
echo "\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
echo apply_filters( 'woocommerce_email_footer_text', get_option( 'woocommerce_email_footer_text' ) );

View File

@ -39,7 +39,7 @@ switch( $template ) {
echo '</div></div>';
break;
case 'twentysixteen' :
echo '</div></main>';
echo '</main></div>';
break;
default :
echo '</div></div>';

View File

@ -37,7 +37,7 @@ do_action( 'woocommerce_before_add_to_cart_form' ); ?>
<td class="label"><label for="<?php echo sanitize_title( $attribute_name ); ?>"><?php echo wc_attribute_label( $attribute_name ); ?></label></td>
<td class="value">
<?php
$selected = isset( $_REQUEST[ 'attribute_' . sanitize_title( $attribute_name ) ] ) ? wc_clean( $_REQUEST[ 'attribute_' . sanitize_title( $attribute_name ) ] ) : $product->get_variation_default_attribute( $attribute_name );
$selected = isset( $_REQUEST[ 'attribute_' . sanitize_title( $attribute_name ) ] ) ? wc_clean( urldecode( $_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 ? apply_filters( 'woocommerce_reset_variations_link', '<a class="reset_variations" href="#">' . __( 'Clear', 'woocommerce' ) . '</a>' ) : '';
?>

View File

@ -82,8 +82,18 @@ class Validation extends \WC_Unit_Test_Case {
array( false, \WC_Validation::is_postcode( '99999 999', 'BR' ) ),
array( false, \WC_Validation::is_postcode( '99999-ABC', 'BR' ) )
);
$ca = array(
array( true, \WC_Validation::is_postcode( 'A9A 9A9', 'CA' ) ),
array( true, \WC_Validation::is_postcode( 'A9A9A9', 'CA' ) ),
array( true, \WC_Validation::is_postcode( 'a9a9a9', 'CA' ) ),
array( false, \WC_Validation::is_postcode( 'D0A 9A9', 'CA' ) ),
array( false, \WC_Validation::is_postcode( '99999', 'CA' ) ),
array( false, \WC_Validation::is_postcode( 'ABC999', 'CA' ) ),
array( false, \WC_Validation::is_postcode( '0A0A0A', 'CA' ) )
);
return array_merge( $generic, $gb, $us, $ch, $br );
return array_merge( $generic, $gb, $us, $ch, $br, $ca );
}
/**