Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Diego Zanella 2016-02-26 14:46:00 +00:00
commit f4ad565835
86 changed files with 1797 additions and 811 deletions

26
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,26 @@
Before submitting your issue, please go through the following checklist. Thanks!
- [ ] I have searched this repository (top of the page) for the issue and it has not been fixed or reported already.
- [ ] I am not asking for support (general support - https://wordpress.org/support/plugin/woocommerce, premium plugin support - https://support.woothemes.com).
FOR BUG REPORTS
- [x] I am using the latest stable release of WooCommerce.
- [ ] I've disabled all plugins to ensure it's a core bug and not a plugin issue.
- [ ] I've switched to Twenty Twelve theme to ensure it's a core bug and not a theme issue.
- [ ] I have grabbed the system status report from WooCommerce > System Status (paste in the area below).
EXPLANATION OF THE ISSUE
What happens, under which versions, under what conditions, when, and what were you expecting instead.
STEPS TO REPRODUCE THE ISSUE
1. List steps to reproduce your issue so we can replicate.
SYSTEM STATUS REPORT
```
Grab the system status report from WooCommerce > System Status and paste it here.
```

View File

@ -19,6 +19,6 @@ This repository is not suitable for support. Please don't use our issue tracker
Support requests in issues on this repository will be closed on sight. Support requests in issues on this repository will be closed on sight.
## Contributing to WooCommerce ## Contributing to WooCommerce
If you have a patch, or stumbled upon an issue with WooCommerce core, you can contribute this back to the code. Please read our [contributor guidelines](https://github.com/woothemes/woocommerce/blob/master/CONTRIBUTING.md) for more information how you can do this. If you have a patch, or stumbled upon an issue with WooCommerce core, you can contribute this back to the code. Please read our [contributor guidelines](https://github.com/woothemes/woocommerce/blob/master/.github/CONTRIBUTING.md) for more information how you can do this.
If you have an idea for WooCommerce, see the [Roadmap Trello board](https://trello.com/b/YgRbpuze/woocommerce-roadmap). If you have an idea for WooCommerce, see the [Roadmap Trello board](https://trello.com/b/YgRbpuze/woocommerce-roadmap).

View File

@ -122,6 +122,45 @@ class WC_HookFinder {
case 'filter' : case 'filter' :
case 'action' : case 'action' :
$hook = trim( $token[1], "'" ); $hook = trim( $token[1], "'" );
$loop = 0;
if ( '_' === substr( $hook, '-1', 1 ) ) {
$hook .= '{';
$open = true;
// Keep adding to hook until we find a comma or colon
while ( 1 ) {
$loop ++;
$next_hook = trim( trim( is_string( $tokens[ $index + $loop ] ) ? $tokens[ $index + $loop ] : $tokens[ $index + $loop ][1], '"' ), "'" );
if ( in_array( $next_hook, array( '.', '{', '}', '"', "'", ' ' ) ) ) {
continue;
}
$hook_first = substr( $next_hook, 0, 1 );
$hook_last = substr( $next_hook, -1, 1 );
if ( in_array( $next_hook, array( ',', ';' ) ) ) {
if ( $open ) {
$hook .= '}';
$open = false;
}
break;
}
if ( '_' === $hook_first ) {
$next_hook = '}' . $next_hook;
$open = false;
}
if ( '_' === $hook_last ) {
$next_hook .= '{';
$open = true;
}
$hook .= $next_hook;
}
}
if ( isset( self::$custom_hooks_found[ $hook ] ) ) { if ( isset( self::$custom_hooks_found[ $hook ] ) ) {
self::$custom_hooks_found[ $hook ]['file'][] = self::$current_file; self::$custom_hooks_found[ $hook ]['file'][] = self::$current_file;
} else { } else {
@ -169,13 +208,13 @@ class WC_HookFinder {
echo '</div><div id="footer">'; echo '</div><div id="footer">';
$html = file_get_contents( '../wc-apidocs/tree.html' ); $html = file_get_contents( '../wc-apidocs/tree.html' );
$header = current( explode( '<div id="content">', $html ) ); $header = explode( '<div id="content">', $html );
$header = str_replace( '<li class="active">', '<li>', $header ); $header = str_replace( '<li class="active">', '<li>', current( $header ) );
$header = str_replace( '<li class="hooks">', '<li class="active">', $header ); $header = str_replace( '<li class="hooks">', '<li class="active">', $header );
$header = str_replace( 'Tree | ', 'Hook Reference | ', $header ); $header = str_replace( 'Tree | ', 'Hook Reference | ', $header );
$footer = end( explode( '<div id="footer">', $html ) ); $footer = explode( '<div id="footer">', $html );
file_put_contents( '../wc-apidocs/hook-docs.html', $header . ob_get_clean() . $footer ); file_put_contents( '../wc-apidocs/hook-docs.html', $header . ob_get_clean() . end( $footer ) );
echo "Hook docs generated :)\n"; echo "Hook docs generated :)\n";
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -65,7 +65,7 @@
display: none; display: none;
} }
h3 { h2, h3 {
margin: 0 !important; margin: 0 !important;
padding: 20px !important; padding: 20px !important;
background: #fff; background: #fff;
@ -216,6 +216,11 @@ mark.amount {
table.wc_status_table { table.wc_status_table {
margin-bottom: 1em; margin-bottom: 1em;
h2 {
font-size: 14px;
margin: 0;
}
tr { tr {
&:nth-child(2n) { &:nth-child(2n) {
th, th,
@ -499,7 +504,11 @@ ul.wc_coupon_list_block {
padding: 0; padding: 0;
} }
h4 { h3 {
font-size: 14px;
}
h3, h4 {
color: #333; color: #333;
margin: 1.33em 0 0; margin: 1.33em 0 0;
} }
@ -2418,6 +2427,7 @@ img.help_tip {
.woocommerce { .woocommerce {
.woo-nav-tab-wrapper { .woo-nav-tab-wrapper {
margin-bottom: 16px !important; margin-bottom: 16px !important;
border-bottom: 1px solid #ccc;
} }
.subsubsub { .subsubsub {
@ -3903,6 +3913,7 @@ img.ui-datepicker-trigger {
margin: 0 !important; margin: 0 !important;
} }
div.stats_range,
h3.stats_range { h3.stats_range {
border-bottom-color: #dfdfdf; border-bottom-color: #dfdfdf;
margin: 0; margin: 0;
@ -3928,6 +3939,7 @@ img.ui-datepicker-trigger {
padding: 0; padding: 0;
zoom: 1; zoom: 1;
background: #f5f5f5; background: #f5f5f5;
border-bottom: 1px solid #ccc;
&:before, &:before,
&:after { &:after {
@ -3944,6 +3956,8 @@ img.ui-datepicker-trigger {
margin: 0; margin: 0;
padding: 0; padding: 0;
line-height: 26px; line-height: 26px;
font-weight: bold;
font-size: 14px;
a { a {
border-right: 1px solid #dfdfdf; border-right: 1px solid #dfdfdf;

File diff suppressed because one or more lines are too long

View File

@ -501,3 +501,28 @@
} }
} }
} }
/**
* RTL styles.
*/
.rtl {
.woocommerce, .woocommerce-page {
.col2-set {
.col-1 {
float: right;
}
.col-2 {
float: left;
}
}
form {
.form-row-first,
.form-row-last {
float: right;
}
.form-row-last {
float: left;
}
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -1552,6 +1552,20 @@ p.demo_store {
* Account page * Account page
*/ */
.woocommerce-account { .woocommerce-account {
.woocommerce {
@include clearfix();
}
.my-account-navigation {
float: left;
width: 30%;
}
.my-account-content {
float: right;
width: 68%;
}
.addresses { .addresses {
.title { .title {
@include clearfix(); @include clearfix();
@ -1923,7 +1937,7 @@ p.demo_store {
} }
/** /**
* Password strength meter * Password strength meter
*/ */
.woocommerce-password-strength { .woocommerce-password-strength {
text-align: center; text-align: center;

View File

@ -198,7 +198,7 @@
var $template_html = ''; var $template_html = '';
if ( ! variation.variation_is_visible ) { if ( ! variation.variation_is_visible ) {
$template_html = unavailable_template; $template_html = unavailable_template();
// w3 total cache inline minification adds CDATA tags around our HTML (sigh) // w3 total cache inline minification adds CDATA tags around our HTML (sigh)
$template_html = $template_html.replace( '/*<![CDATA[*/', '' ); $template_html = $template_html.replace( '/*<![CDATA[*/', '' );
$template_html = $template_html.replace( '/*]]>*/', '' ); $template_html = $template_html.replace( '/*]]>*/', '' );

File diff suppressed because one or more lines are too long

View File

@ -6,7 +6,14 @@ jQuery( function( $ ) {
return false; return false;
} }
// Gets a url for a given AJAX endpoint. // Utility functions for the file.
/**
* Gets a url for a given AJAX endpoint.
*
* @param {String} endpoint The AJAX Endpoint
* @return {String} The URL to use for the request
*/
var get_url = function( endpoint ) { var get_url = function( endpoint ) {
return wc_cart_params.wc_ajax_url.toString().replace( return wc_cart_params.wc_ajax_url.toString().replace(
'%%endpoint%%', '%%endpoint%%',
@ -14,12 +21,21 @@ jQuery( function( $ ) {
); );
}; };
// Check if a node is blocked for processing. /**
* Check if a node is blocked for processing.
*
* @param {JQuery Object} $node
* @return {bool} True if the DOM Element is UI Blocked, false if not.
*/
var is_blocked = function( $node ) { var is_blocked = function( $node ) {
return $node.is( '.processing' ); return $node.is( '.processing' );
}; };
// Block a node for processing. /**
* Block a node visually for processing.
*
* @param {JQuery Object} $node
*/
var block = function( $node ) { var block = function( $node ) {
$node.addClass( 'processing' ).block( { $node.addClass( 'processing' ).block( {
message: null, message: null,
@ -30,86 +46,31 @@ jQuery( function( $ ) {
} ); } );
}; };
// Unblock a node after processing is complete. /**
* Unblock a node after processing is complete.
*
* @param {JQuery Object} $node
*/
var unblock = function( $node ) { var unblock = function( $node ) {
$node.removeClass( 'processing' ).unblock(); $node.removeClass( 'processing' ).unblock();
}; };
// Updates the .woocommerce div with a string of html. /**
* Update the .woocommerce div with a string of html.
*
* @param {String} html_str The HTML string with which to replace the div.
*/
var update_wc_div = function( html_str ) { var update_wc_div = function( html_str ) {
var $html = $.parseHTML( html_str ); var $html = $.parseHTML( html_str );
var $new_div = $( 'div.woocommerce', $html ); var $new_div = $( 'div.woocommerce', $html );
$( 'div.woocommerce' ).replaceWith( $new_div ); $( 'div.woocommerce' ).replaceWith( $new_div );
}; };
// Shipping calculator /**
$( document ).on( 'click', '.shipping-calculator-button', function() { * Clear previous notices and shows new one above form.
$( '.shipping-calculator-form' ).slideToggle( 'slow' ); *
return false; * @param {Object} The Notice HTML Element in string or object form.
} ).on( 'change', 'select.shipping_method, input[name^=shipping_method]', function() { */
var shipping_methods = [];
$( 'select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]' ).each( function() {
shipping_methods[ $( this ).data( 'index' ) ] = $( this ).val();
} );
block( $( 'div.cart_totals' ) );
var data = {
security: wc_cart_params.update_shipping_method_nonce,
shipping_method: shipping_methods
};
$.post( get_url( 'update_shipping_method' ), data, function( response ) {
$( 'div.cart_totals' ).replaceWith( response );
$( document.body ).trigger( 'updated_shipping_method' );
} );
} );
$( document ).on( 'submit', 'form.woocommerce-shipping-calculator', function( evt ) {
evt.preventDefault();
var $form = $( evt.target );
block( $form );
// Provide the submit button value because wc-form-handler expects it.
$( '<input />' ).attr( 'type', 'hidden' )
.attr( 'name', 'calc_shipping' )
.attr( 'value', 'x' )
.appendTo( $form );
// Make call to actual form post URL.
$.ajax( {
type: $form.attr( 'method' ),
url: $form.attr( 'action' ),
data: $form.serialize(),
dataType: 'html',
success: function( response ) {
update_wc_div(response );
},
complete: function() {
unblock( $form );
}
} );
} );
$( '.shipping-calculator-form' ).hide();
// Update the cart after something has changed.
var update_cart_totals = function() {
block( $( 'div.cart_totals' ) );
$.ajax( {
url: get_url( 'get_cart_totals' ),
dataType: 'html',
success: function( response ) {
$( 'div.cart_totals' ).replaceWith( response );
}
} );
};
// clears previous notices and shows new one above form.
var show_notice = function( html_element ) { var show_notice = function( html_element ) {
var $form = $( 'div.woocommerce > form' ); var $form = $( 'div.woocommerce > form' );
@ -117,126 +78,295 @@ jQuery( function( $ ) {
$form.before( html_element ); $form.before( html_element );
}; };
// Handle form submit and route to correct logic.
$( document ).on( 'submit', 'div.woocommerce > form', function( evt ) {
evt.preventDefault();
var $form = $( evt.target ); /**
var $submit = $( document.activeElement ); * Object to handle AJAX calls for cart shipping changes.
*/
var cart_shipping = {
window.console.log( $submit ); /**
* Initialize event handlers and UI state.
*/
init: function() {
this.toggle_shipping = this.toggle_shipping.bind( this );
this.shipping_method_selected = this.shipping_method_selected.bind( this );
this.shipping_calculator_submit = this.shipping_calculator_submit.bind( this );
if ( is_blocked( $form ) ) { $( document ).on(
'click',
'.shipping-calculator-button',
this.toggle_shipping
);
$( document ).on(
'change',
'select.shipping_method, input[name^=shipping_method]',
this.shipping_method_selected
);
$( document ).on(
'submit',
'form.woocommerce-shipping-calculator',
this.shipping_calculator_submit
);
$( '.shipping-calculator-form' ).hide();
},
/**
* Toggle Shipping Calculator panel
*/
toggle_shipping: function() {
$( '.shipping-calculator-form' ).slideToggle( 'slow' );
return false; return false;
},
/**
* Handles when a shipping method is selected.
*
* @param {Object} evt The JQuery event.
*/
shipping_method_selected: function( evt ) {
var target = evt.target;
var shipping_methods = [];
$( 'select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]' ).each( function() {
shipping_methods[ $( target ).data( 'index' ) ] = $( target ).val();
} );
block( $( 'div.cart_totals' ) );
var data = {
security: wc_cart_params.update_shipping_method_nonce,
shipping_method: shipping_methods
};
$.post( get_url( 'update_shipping_method' ), data, function( response ) {
$( 'div.cart_totals' ).replaceWith( response );
$( document.body ).trigger( 'updated_shipping_method' );
} );
},
/**
* Handles a shipping calculator form submit.
*
* @param {Object} evt The JQuery event.
*/
shipping_calculator_submit: function( evt ) {
evt.preventDefault();
var $form = $( evt.target );
block( $form );
// Provide the submit button value because wc-form-handler expects it.
$( '<input />' ).attr( 'type', 'hidden' )
.attr( 'name', 'calc_shipping' )
.attr( 'value', 'x' )
.appendTo( $form );
// Make call to actual form post URL.
$.ajax( {
type: $form.attr( 'method' ),
url: $form.attr( 'action' ),
data: $form.serialize(),
dataType: 'html',
success: function( response ) {
update_wc_div(response );
},
complete: function() {
unblock( $form );
}
} );
} }
if ( $submit.is( '[name="update_cart"]' ) || $submit.is( 'input.qty' ) ) {
window.console.log( 'update cart' );
quantity_update( $form );
} else if ( $submit.is( '[name="apply_coupon"]' ) || $submit.is( '#coupon_code' ) ) {
window.console.log( 'apply coupon' );
apply_coupon( $form );
}
} );
// Coupon code
var apply_coupon = function( $form ) {
block( $form );
var $text_field = $( '#coupon_code' );
var coupon_code = $text_field.val();
var data = {
security: wc_cart_params.apply_coupon_nonce,
coupon_code: coupon_code
};
$.ajax( {
type: 'POST',
url: get_url( 'apply_coupon' ),
data: data,
dataType: 'html',
success: function( response ) {
show_notice( response );
},
complete: function() {
unblock( $form );
$text_field.val( '' );
update_cart_totals();
}
} );
}; };
$( document ).on( 'click', 'a.woocommerce-remove-coupon', function( evt ) { /**
evt.preventDefault(); * Object to handle cart UI.
*/
var cart = {
/**
* Initialize cart UI events.
*/
init: function() {
this.update_cart_totals = this.update_cart_totals.bind( this );
this.cart_submit = this.cart_submit.bind( this );
this.apply_coupon = this.apply_coupon.bind( this );
this.remove_coupon_clicked = this.remove_coupon_clicked.bind( this );
this.quantity_update = this.quantity_update.bind( this );
this.item_remove_clicked = this.item_remove_clicked.bind( this );
var $tr = $( this ).parents( 'tr' ); $( document ).on(
var coupon = $( this ).attr( 'data-coupon' ); 'submit',
'div.woocommerce > form',
this.cart_submit );
$( document ).on(
'click',
'a.woocommerce-remove-coupon',
this.remove_coupon_clicked );
$( document ).on(
'click',
'td.product-remove > a',
this.item_remove_clicked );
},
block( $tr.parents( 'table' ) ); /**
* Update the cart after something has changed.
*/
update_cart_totals: function() {
block( $( 'div.cart_totals' ) );
var data = { $.ajax( {
security: wc_cart_params.remove_coupon_nonce, url: get_url( 'get_cart_totals' ),
coupon: coupon dataType: 'html',
}; success: function( response ) {
$( 'div.cart_totals' ).replaceWith( response );
}
} );
},
$.ajax( { /**
type: 'POST', * Handle cart form submit and route to correct logic.
url: get_url( 'remove_coupon' ), *
data: data, * @param {Object} evt The JQuery event
dataType: 'html', */
success: function( response ) { cart_submit: function( evt ) {
show_notice( response ); evt.preventDefault();
unblock( $tr.parents( 'table' ) );
}, var $form = $( evt.target );
complete: function() { var $submit = $( document.activeElement );
update_cart_totals();
if ( is_blocked( $form ) ) {
return false;
} }
} );
} );
// Quantity Update if ( $submit.is( '[name="update_cart"]' ) || $submit.is( 'input.qty' ) ) {
var quantity_update = function( $form ) { this.quantity_update( $form );
// Provide the submit button value because wc-form-handler expects it. } else if ( $submit.is( '[name="apply_coupon"]' ) || $submit.is( '#coupon_code' ) ) {
$( '<input />' ).attr( 'type', 'hidden' ) this.apply_coupon( $form );
.attr( 'name', 'update_cart' )
.attr( 'value', 'Update Cart' )
.appendTo( $form );
block( $form );
// Make call to actual form post URL.
$.ajax( {
type: $form.attr( 'method' ),
url: $form.attr( 'action' ),
data: $form.serialize(),
dataType: 'html',
success: update_wc_div,
complete: function() {
unblock( $form );
} }
} ); },
/**
* Apply Coupon code
*
* @param {JQuery Object} $form The cart form.
*/
apply_coupon: function( $form ) {
block( $form );
var cart = this;
var $text_field = $( '#coupon_code' );
var coupon_code = $text_field.val();
var data = {
security: wc_cart_params.apply_coupon_nonce,
coupon_code: coupon_code
};
$.ajax( {
type: 'POST',
url: get_url( 'apply_coupon' ),
data: data,
dataType: 'html',
success: function( response ) {
show_notice( response );
},
complete: function() {
unblock( $form );
$text_field.val( '' );
cart.update_cart_totals();
}
} );
},
/**
* Handle when a remove coupon link is clicked.
*
* @param {Object} evt The JQuery event
*/
remove_coupon_clicked: function( evt ) {
evt.preventDefault();
var cart = this;
var $tr = $( evt.target ).parents( 'tr' );
var coupon = $( evt.target ).attr( 'data-coupon' );
block( $tr.parents( 'table' ) );
var data = {
security: wc_cart_params.remove_coupon_nonce,
coupon: coupon
};
$.ajax( {
type: 'POST',
url: get_url( 'remove_coupon' ),
data: data,
dataType: 'html',
success: function( response ) {
show_notice( response );
unblock( $tr.parents( 'table' ) );
},
complete: function() {
cart.update_cart_totals();
}
} );
},
/**
* Handle a cart Quantity Update
*
* @param {JQuery Object} $form The cart form.
*/
quantity_update: function( $form ) {
// Provide the submit button value because wc-form-handler expects it.
$( '<input />' ).attr( 'type', 'hidden' )
.attr( 'name', 'update_cart' )
.attr( 'value', 'Update Cart' )
.appendTo( $form );
block( $form );
// Make call to actual form post URL.
$.ajax( {
type: $form.attr( 'method' ),
url: $form.attr( 'action' ),
data: $form.serialize(),
dataType: 'html',
success: update_wc_div,
complete: function() {
unblock( $form );
}
} );
},
/**
* Handle when a remove item link is clicked.
*
* @param {Object} evt The JQuery event
*/
item_remove_clicked: function( evt ) {
evt.preventDefault();
var $a = $( evt.target );
var $form = $a.parents( 'form' );
block( $form );
$.ajax( {
type: 'GET',
url: $a.attr( 'href' ),
dataType: 'html',
success: update_wc_div,
complete: function() {
unblock( $form );
}
} );
}
}; };
// Item Remove cart_shipping.init();
$( document ).on( 'click', 'td.product-remove > a', function( evt ) { cart.init();
evt.preventDefault();
var $a = $( evt.target );
var $form = $a.parents( 'form' );
block( $form );
$.ajax( {
type: 'GET',
url: $a.attr( 'href' ),
dataType: 'html',
success: update_wc_div,
complete: function() {
unblock( $form );
}
} );
} );
} ); } );

View File

@ -1 +1 @@
jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a("div.woocommerce",c);a("div.woocommerce").replaceWith(d)};a(document).on("click",".shipping-calculator-button",function(){return a(".shipping-calculator-form").slideToggle("slow"),!1}).on("change","select.shipping_method, input[name^=shipping_method]",function(){var c=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){c[a(this).data("index")]=a(this).val()}),d(a("div.cart_totals"));var e={security:wc_cart_params.update_shipping_method_nonce,shipping_method:c};a.post(b("update_shipping_method"),e,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})}),a(document).on("submit","form.woocommerce-shipping-calculator",function(b){b.preventDefault();var c=a(b.target);d(c),a("<input />").attr("type","hidden").attr("name","calc_shipping").attr("value","x").appendTo(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:function(a){f(a)},complete:function(){e(c)}})}),a(".shipping-calculator-form").hide();var g=function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},h=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)};a(document).on("submit","div.woocommerce > form",function(b){b.preventDefault();var d=a(b.target),e=a(document.activeElement);return window.console.log(e),c(d)?!1:void(e.is('[name="update_cart"]')||e.is("input.qty")?(window.console.log("update cart"),j(d)):(e.is('[name="apply_coupon"]')||e.is("#coupon_code"))&&(window.console.log("apply coupon"),i(d)))});var i=function(c){d(c);var f=a("#coupon_code"),i=f.val(),j={security:wc_cart_params.apply_coupon_nonce,coupon_code:i};a.ajax({type:"POST",url:b("apply_coupon"),data:j,dataType:"html",success:function(a){h(a)},complete:function(){e(c),f.val(""),g()}})};a(document).on("click","a.woocommerce-remove-coupon",function(c){c.preventDefault();var f=a(this).parents("tr"),i=a(this).attr("data-coupon");d(f.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){h(a),e(f.parents("table"))},complete:function(){g()}})});var j=function(b){a("<input />").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(b),d(b),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:f,complete:function(){e(b)}})};a(document).on("click","td.product-remove > a",function(b){b.preventDefault();var c=a(b.target),g=c.parents("form");d(g),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(g)}})})}); jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")},d=function(a){a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a("div.woocommerce",c);a("div.woocommerce").replaceWith(d)},g=function(b){var c=a("div.woocommerce > form");a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)},h={init:function(){this.toggle_shipping=this.toggle_shipping.bind(this),this.shipping_method_selected=this.shipping_method_selected.bind(this),this.shipping_calculator_submit=this.shipping_calculator_submit.bind(this),a(document).on("click",".shipping-calculator-button",this.toggle_shipping),a(document).on("change","select.shipping_method, input[name^=shipping_method]",this.shipping_method_selected),a(document).on("submit","form.woocommerce-shipping-calculator",this.shipping_calculator_submit),a(".shipping-calculator-form").hide()},toggle_shipping:function(){return a(".shipping-calculator-form").slideToggle("slow"),!1},shipping_method_selected:function(c){var e=c.target,f=[];a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){f[a(e).data("index")]=a(e).val()}),d(a("div.cart_totals"));var g={security:wc_cart_params.update_shipping_method_nonce,shipping_method:f};a.post(b("update_shipping_method"),g,function(b){a("div.cart_totals").replaceWith(b),a(document.body).trigger("updated_shipping_method")})},shipping_calculator_submit:function(b){b.preventDefault();var c=a(b.target);d(c),a("<input />").attr("type","hidden").attr("name","calc_shipping").attr("value","x").appendTo(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:function(a){f(a)},complete:function(){e(c)}})}},i={init:function(){this.update_cart_totals=this.update_cart_totals.bind(this),this.cart_submit=this.cart_submit.bind(this),this.apply_coupon=this.apply_coupon.bind(this),this.remove_coupon_clicked=this.remove_coupon_clicked.bind(this),this.quantity_update=this.quantity_update.bind(this),this.item_remove_clicked=this.item_remove_clicked.bind(this),a(document).on("submit","div.woocommerce > form",this.cart_submit),a(document).on("click","a.woocommerce-remove-coupon",this.remove_coupon_clicked),a(document).on("click","td.product-remove > a",this.item_remove_clicked)},update_cart_totals:function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(b){a("div.cart_totals").replaceWith(b)}})},cart_submit:function(b){b.preventDefault();var d=a(b.target),e=a(document.activeElement);return c(d)?!1:void(e.is('[name="update_cart"]')||e.is("input.qty")?this.quantity_update(d):(e.is('[name="apply_coupon"]')||e.is("#coupon_code"))&&this.apply_coupon(d))},apply_coupon:function(c){d(c);var f=this,h=a("#coupon_code"),i=h.val(),j={security:wc_cart_params.apply_coupon_nonce,coupon_code:i};a.ajax({type:"POST",url:b("apply_coupon"),data:j,dataType:"html",success:function(a){g(a)},complete:function(){e(c),h.val(""),f.update_cart_totals()}})},remove_coupon_clicked:function(c){c.preventDefault();var f=this,h=a(c.target).parents("tr"),i=a(c.target).attr("data-coupon");d(h.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(a){g(a),e(h.parents("table"))},complete:function(){f.update_cart_totals()}})},quantity_update:function(b){a("<input />").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(b),d(b),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:f,complete:function(){e(b)}})},item_remove_clicked:function(b){b.preventDefault();var c=a(b.target),g=c.parents("form");d(g),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(g)}})}};h.init(),i.init()});

View File

@ -1711,7 +1711,7 @@
</wp:postmeta> </wp:postmeta>
<wp:postmeta> <wp:postmeta>
<wp:meta_key>_featured</wp:meta_key> <wp:meta_key>_featured</wp:meta_key>
<wp:meta_value><![CDATA[no]]></wp:meta_value> <wp:meta_value><![CDATA[yes]]></wp:meta_value>
</wp:postmeta> </wp:postmeta>
<wp:postmeta> <wp:postmeta>
<wp:meta_key>_weight</wp:meta_key> <wp:meta_key>_weight</wp:meta_key>
@ -3357,7 +3357,7 @@ I'm ordering mine next week";s:7:"POST__n";s:10:"a80bd2f042";s:21:"POST__wp_http
</wp:postmeta> </wp:postmeta>
<wp:postmeta> <wp:postmeta>
<wp:meta_key>_featured</wp:meta_key> <wp:meta_key>_featured</wp:meta_key>
<wp:meta_value><![CDATA[no]]></wp:meta_value> <wp:meta_value><![CDATA[yes]]></wp:meta_value>
</wp:postmeta> </wp:postmeta>
<wp:postmeta> <wp:postmeta>
<wp:meta_key>_weight</wp:meta_key> <wp:meta_key>_weight</wp:meta_key>
@ -3807,7 +3807,7 @@ If only it came in red as well!";s:7:"POST__n";s:10:"2145d644a3";s:21:"POST__wp_
</wp:postmeta> </wp:postmeta>
<wp:postmeta> <wp:postmeta>
<wp:meta_key>_featured</wp:meta_key> <wp:meta_key>_featured</wp:meta_key>
<wp:meta_value><![CDATA[no]]></wp:meta_value> <wp:meta_value><![CDATA[yes]]></wp:meta_value>
</wp:postmeta> </wp:postmeta>
<wp:postmeta> <wp:postmeta>
<wp:meta_key>_weight</wp:meta_key> <wp:meta_key>_weight</wp:meta_key>
@ -5810,7 +5810,7 @@ If only it came in red as well!";s:7:"POST__n";s:10:"2145d644a3";s:21:"POST__wp_
</wp:postmeta> </wp:postmeta>
<wp:postmeta> <wp:postmeta>
<wp:meta_key>_featured</wp:meta_key> <wp:meta_key>_featured</wp:meta_key>
<wp:meta_value><![CDATA[no]]></wp:meta_value> <wp:meta_value><![CDATA[yes]]></wp:meta_value>
</wp:postmeta> </wp:postmeta>
<wp:postmeta> <wp:postmeta>
<wp:meta_key>_weight</wp:meta_key> <wp:meta_key>_weight</wp:meta_key>

View File

@ -632,6 +632,11 @@ abstract class WC_Abstract_Order {
$taxes = array(); $taxes = array();
$tax_based_on = get_option( 'woocommerce_tax_based_on' ); $tax_based_on = get_option( 'woocommerce_tax_based_on' );
// If is_vat_exempt is 'yes', or wc_tax_enabled is false, return and do nothing.
if ( 'yes' === $this->is_vat_exempt or ! wc_tax_enabled() ) {
return false;
}
if ( 'billing' === $tax_based_on ) { if ( 'billing' === $tax_based_on ) {
$country = $this->billing_country; $country = $this->billing_country;
$state = $this->billing_state; $state = $this->billing_state;

View File

@ -1313,7 +1313,7 @@ class WC_Product {
* This means if a related product is edited and no longer related, it won't be removed for 24 hours. Acceptable trade-off for performance. * This means if a related product is edited and no longer related, it won't be removed for 24 hours. Acceptable trade-off for performance.
* - Saving a product will flush caches for that product. * - Saving a product will flush caches for that product.
* *
* @param int $limit (default: 5) * @param int $limit (default: 5) Should be an integer greater than 0.
* @return array Array of post IDs * @return array Array of post IDs
*/ */
public function get_related( $limit = 5 ) { public function get_related( $limit = 5 ) {
@ -1321,6 +1321,7 @@ class WC_Product {
$transient_name = 'wc_related_' . $this->id; $transient_name = 'wc_related_' . $this->id;
$related_posts = get_transient( $transient_name ); $related_posts = get_transient( $transient_name );
$limit = $limit > 0 ? $limit : 5;
// We want to query related posts if they are not cached, or we don't have enough // We want to query related posts if they are not cached, or we don't have enough
if ( false === $related_posts || sizeof( $related_posts ) < $limit ) { if ( false === $related_posts || sizeof( $related_posts ) < $limit ) {

View File

@ -74,7 +74,6 @@ abstract class WC_Shipping_Method extends WC_Settings_API {
*/ */
public $fee = null; public $fee = null;
/** @var float Minimum fee for the method */
/** /**
* Minimum fee for the method (if applicable). * Minimum fee for the method (if applicable).
* @var string * @var string

View File

@ -59,7 +59,7 @@ class WC_Admin_API_Keys {
* Table list output. * Table list output.
*/ */
private static function table_list_output() { private static function table_list_output() {
echo '<h3>' . __( 'Keys/Apps', 'woocommerce' ) . ' <a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=api&section=keys&create-key=1' ) ) . '" class="add-new-h2">' . __( 'Add Key', 'woocommerce' ) . '</a></h3>'; echo '<h2>' . __( 'Keys/Apps', 'woocommerce' ) . ' <a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=api&section=keys&create-key=1' ) ) . '" class="add-new-h2">' . __( 'Add Key', 'woocommerce' ) . '</a></h2>';
$keys_table_list = new WC_Admin_API_Keys_Table_List(); $keys_table_list = new WC_Admin_API_Keys_Table_List();
$keys_table_list->prepare_items(); $keys_table_list->prepare_items();

View File

@ -428,7 +428,7 @@ class WC_Admin_Attributes {
<div id="col-left"> <div id="col-left">
<div class="col-wrap"> <div class="col-wrap">
<div class="form-wrap"> <div class="form-wrap">
<h3><?php _e( 'Add New Attribute', 'woocommerce' ); ?></h3> <h2><?php _e( 'Add New Attribute', 'woocommerce' ); ?></h2>
<p><?php _e( 'Attributes let you define extra product data, such as size or colour. You can use these attributes in the shop sidebar using the "layered nav" widgets. Please note: you cannot rename an attribute later on.', 'woocommerce' ); ?></p> <p><?php _e( 'Attributes let you define extra product data, such as size or colour. You can use these attributes in the shop sidebar using the "layered nav" widgets. Please note: you cannot rename an attribute later on.', 'woocommerce' ); ?></p>
<form action="edit.php?post_type=product&amp;page=product_attributes" method="post"> <form action="edit.php?post_type=product&amp;page=product_attributes" method="post">
<div class="form-field"> <div class="form-field">

View File

@ -194,7 +194,7 @@ class WC_Admin_Help {
'title' => __( 'Found a bug?', 'woocommerce' ), 'title' => __( 'Found a bug?', 'woocommerce' ),
'content' => 'content' =>
'<h2>' . __( 'Found a bug?', 'woocommerce' ) . '</h2>' . '<h2>' . __( 'Found a bug?', 'woocommerce' ) . '</h2>' .
'<p>' . sprintf( __( 'If you find a bug within WooCommerce core you can create a ticket via <a href="%s">Github issues</a>. Ensure you read the <a href="%s">contribution guide</a> prior to submitting your report. To help us solve your issue, please be as descriptive as possible and include your <a href="%s">system status report</a>.', 'woocommerce' ), 'https://github.com/woothemes/woocommerce/issues?state=open', 'https://github.com/woothemes/woocommerce/blob/master/CONTRIBUTING.md', admin_url( 'admin.php?page=wc-status' ) ) . '</p>' . '<p>' . sprintf( __( 'If you find a bug within WooCommerce core you can create a ticket via <a href="%s">Github issues</a>. Ensure you read the <a href="%s">contribution guide</a> prior to submitting your report. To help us solve your issue, please be as descriptive as possible and include your <a href="%s">system status report</a>.', 'woocommerce' ), 'https://github.com/woothemes/woocommerce/issues?state=open', 'https://github.com/woothemes/woocommerce/blob/master/.github/CONTRIBUTING.md', admin_url( 'admin.php?page=wc-status' ) ) . '</p>' .
'<p><a href="' . 'https://github.com/woothemes/woocommerce/issues?state=open' . '" class="button button-primary">' . __( 'Report a bug', 'woocommerce' ) . '</a> <a href="' . admin_url( 'admin.php?page=wc-status' ) . '" class="button">' . __( 'System Status', 'woocommerce' ) . '</a></p>' '<p><a href="' . 'https://github.com/woothemes/woocommerce/issues?state=open' . '" class="button button-primary">' . __( 'Report a bug', 'woocommerce' ) . '</a> <a href="' . admin_url( 'admin.php?page=wc-status' ) . '" class="button">' . __( 'System Status', 'woocommerce' ) . '</a></p>'
) ); ) );

View File

@ -81,7 +81,6 @@ class WC_Admin_Post_Types {
// Edit post screens // Edit post screens
add_filter( 'enter_title_here', array( $this, 'enter_title_here' ), 1, 2 ); add_filter( 'enter_title_here', array( $this, 'enter_title_here' ), 1, 2 );
add_action( 'edit_form_after_title', array( $this, 'edit_form_after_title' ) ); add_action( 'edit_form_after_title', array( $this, 'edit_form_after_title' ) );
add_filter( 'media_view_strings', array( $this, 'change_insert_into_post' ) );
add_filter( 'default_hidden_meta_boxes', array( $this, 'hidden_meta_boxes' ), 10, 2 ); add_filter( 'default_hidden_meta_boxes', array( $this, 'hidden_meta_boxes' ), 10, 2 );
add_action( 'post_submitbox_misc_actions', array( $this, 'product_data_visibility' ) ); add_action( 'post_submitbox_misc_actions', array( $this, 'product_data_visibility' ) );
@ -102,6 +101,9 @@ class WC_Admin_Post_Types {
// Disable DFW feature pointer // Disable DFW feature pointer
add_action( 'admin_footer', array( $this, 'disable_dfw_feature_pointer' ) ); add_action( 'admin_footer', array( $this, 'disable_dfw_feature_pointer' ) );
// Disable post type view mode options
add_filter( 'view_mode_post_types', array( $this, 'disable_view_mode_options' ) );
// If first time editing, disable columns by default. // If first time editing, disable columns by default.
if ( false === get_user_option( 'manageedit-shop_ordercolumnshidden' ) ) { if ( false === get_user_option( 'manageedit-shop_ordercolumnshidden' ) ) {
$user = wp_get_current_user(); $user = wp_get_current_user();
@ -2099,24 +2101,6 @@ class WC_Admin_Post_Types {
} }
} }
/**
* Change label for insert buttons.
* @param array $strings
* @return array
*/
public function change_insert_into_post( $strings ) {
global $post_type;
if ( in_array( $post_type, array( 'product', 'shop_coupon' ) ) || in_array( $post_type, wc_get_order_types() ) ) {
$obj = get_post_type_object( $post_type );
$strings['insertIntoPost'] = sprintf( __( 'Insert into %s', 'woocommerce' ), $obj->labels->singular_name );
$strings['uploadedToThisPost'] = sprintf( __( 'Uploaded to this %s', 'woocommerce' ), $obj->labels->singular_name );
}
return $strings;
}
/** /**
* Hidden default Meta-Boxes. * Hidden default Meta-Boxes.
* @param array $hidden * @param array $hidden
@ -2288,6 +2272,20 @@ class WC_Admin_Post_Types {
remove_action( 'admin_print_footer_scripts', array( 'WP_Internal_Pointers', 'pointer_wp410_dfw' ) ); remove_action( 'admin_print_footer_scripts', array( 'WP_Internal_Pointers', 'pointer_wp410_dfw' ) );
} }
} }
/**
* Removes products, orders, and coupons from the list of post types that support "View Mode" switching.
* View mode is seen on posts where you can switch between list or excerpt. Our post types don't support
* it, so we want to hide the useless UI from the screen options tab.
*
* @since 2.6
* @param array $post_types Array of post types supporting view mode
* @return array Array of post types supporting view mode, without products, orders, and coupons
*/
public function disable_view_mode_options( $post_types ) {
unset( $post_types['product'], $post_types['shop_order'], $post_types['shop_coupon'] );
return $post_types;
}
} }
endif; endif;

View File

@ -115,11 +115,11 @@ class WC_Admin_Settings {
public static function show_messages() { public static function show_messages() {
if ( sizeof( self::$errors ) > 0 ) { if ( sizeof( self::$errors ) > 0 ) {
foreach ( self::$errors as $error ) { foreach ( self::$errors as $error ) {
echo '<div id="message" class="error"><p><strong>' . esc_html( $error ) . '</strong></p></div>'; echo '<div id="message" class="error inline"><p><strong>' . esc_html( $error ) . '</strong></p></div>';
} }
} elseif ( sizeof( self::$messages ) > 0 ) { } elseif ( sizeof( self::$messages ) > 0 ) {
foreach ( self::$messages as $message ) { foreach ( self::$messages as $message ) {
echo '<div id="message" class="updated"><p><strong>' . esc_html( $message ) . '</strong></p></div>'; echo '<div id="message" class="updated inline"><p><strong>' . esc_html( $message ) . '</strong></p></div>';
} }
} }
} }
@ -265,7 +265,7 @@ class WC_Admin_Settings {
// Section Titles // Section Titles
case 'title': case 'title':
if ( ! empty( $value['title'] ) ) { if ( ! empty( $value['title'] ) ) {
echo '<h3>' . esc_html( $value['title'] ) . '</h3>'; echo '<h2>' . esc_html( $value['title'] ) . '</h2>';
} }
if ( ! empty( $value['desc'] ) ) { if ( ! empty( $value['desc'] ) ) {
echo wpautop( wptexturize( wp_kses_post( $value['desc'] ) ) ); echo wpautop( wptexturize( wp_kses_post( $value['desc'] ) ) );

View File

@ -47,7 +47,7 @@ class WC_Admin_Status {
wc_delete_shop_order_transients(); wc_delete_shop_order_transients();
WC_Cache_Helper::get_transient_version( 'shipping', true ); WC_Cache_Helper::get_transient_version( 'shipping', true );
echo '<div class="updated"><p>' . __( 'Product Transients Cleared', 'woocommerce' ) . '</p></div>'; echo '<div class="updated inline"><p>' . __( 'Product Transients Cleared', 'woocommerce' ) . '</p></div>';
break; break;
case 'clear_expired_transients' : case 'clear_expired_transients' :
@ -72,15 +72,14 @@ class WC_Admin_Status {
AND b.option_value < %d"; AND b.option_value < %d";
$rows2 = $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_site_transient_' ) . '%', $wpdb->esc_like( '_site_transient_timeout_' ) . '%', time() ) ); $rows2 = $wpdb->query( $wpdb->prepare( $sql, $wpdb->esc_like( '_site_transient_' ) . '%', $wpdb->esc_like( '_site_transient_timeout_' ) . '%', time() ) );
echo '<div class="updated"><p>' . sprintf( __( '%d Transients Rows Cleared', 'woocommerce' ), $rows + $rows2 ) . '</p></div>'; echo '<div class="updated inline"><p>' . sprintf( __( '%d Transients Rows Cleared', 'woocommerce' ), $rows + $rows2 ) . '</p></div>';
break; break;
case 'reset_roles' : case 'reset_roles' :
// Remove then re-add caps and roles // Remove then re-add caps and roles
WC_Install::remove_roles(); WC_Install::remove_roles();
WC_Install::create_roles(); WC_Install::create_roles();
echo '<div class="updated"><p>' . __( 'Roles successfully reset', 'woocommerce' ) . '</p></div>'; echo '<div class="updated inline"><p>' . __( 'Roles successfully reset', 'woocommerce' ) . '</p></div>';
break; break;
case 'recount_terms' : case 'recount_terms' :
@ -92,7 +91,7 @@ class WC_Admin_Status {
_wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false ); _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false );
echo '<div class="updated"><p>' . __( 'Terms successfully recounted', 'woocommerce' ) . '</p></div>'; echo '<div class="updated inline"><p>' . __( 'Terms successfully recounted', 'woocommerce' ) . '</p></div>';
break; break;
case 'clear_sessions' : case 'clear_sessions' :
@ -100,11 +99,11 @@ class WC_Admin_Status {
wp_cache_flush(); wp_cache_flush();
echo '<div class="updated"><p>' . __( 'Sessions successfully cleared', 'woocommerce' ) . '</p></div>'; echo '<div class="updated inline"><p>' . __( 'Sessions successfully cleared', 'woocommerce' ) . '</p></div>';
break; break;
case 'install_pages' : case 'install_pages' :
WC_Install::create_pages(); WC_Install::create_pages();
echo '<div class="updated"><p>' . __( 'All missing WooCommerce pages was installed successfully.', 'woocommerce' ) . '</p></div>'; echo '<div class="updated inline"><p>' . __( 'All missing WooCommerce pages was installed successfully.', 'woocommerce' ) . '</p></div>';
break; break;
case 'delete_taxes' : case 'delete_taxes' :
@ -112,13 +111,13 @@ class WC_Admin_Status {
$wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" ); $wpdb->query( "TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;" );
WC_Cache_Helper::incr_cache_prefix( 'taxes' ); WC_Cache_Helper::incr_cache_prefix( 'taxes' );
echo '<div class="updated"><p>' . __( 'Tax rates successfully deleted', 'woocommerce' ) . '</p></div>'; echo '<div class="updated inline"><p>' . __( 'Tax rates successfully deleted', 'woocommerce' ) . '</p></div>';
break; break;
case 'reset_tracking' : case 'reset_tracking' :
delete_option( 'woocommerce_allow_tracking' ); delete_option( 'woocommerce_allow_tracking' );
WC_Admin_Notices::add_notice( 'tracking' ); WC_Admin_Notices::add_notice( 'tracking' );
echo '<div class="updated"><p>' . __( 'Usage tracking settings successfully reset.', 'woocommerce' ) . '</p></div>'; echo '<div class="updated inline"><p>' . __( 'Usage tracking settings successfully reset.', 'woocommerce' ) . '</p></div>';
break; break;
default : default :
$action = esc_attr( $_GET['action'] ); $action = esc_attr( $_GET['action'] );
@ -127,10 +126,9 @@ class WC_Admin_Status {
$return = call_user_func( $callback ); $return = call_user_func( $callback );
if ( $return === false ) { if ( $return === false ) {
if ( is_array( $callback ) ) { if ( is_array( $callback ) ) {
echo '<div class="error"><p>' . sprintf( __( 'There was an error calling %s::%s', 'woocommerce' ), get_class( $callback[0] ), $callback[1] ) . '</p></div>'; echo '<div class="error inline"><p>' . sprintf( __( 'There was an error calling %s::%s', 'woocommerce' ), get_class( $callback[0] ), $callback[1] ) . '</p></div>';
} else { } else {
echo '<div class="error"><p>' . sprintf( __( 'There was an error calling %s', 'woocommerce' ), $callback ) . '</p></div>'; echo '<div class="error inline"><p>' . sprintf( __( 'There was an error calling %s', 'woocommerce' ), $callback ) . '</p></div>';
} }
} }
} }
@ -140,7 +138,7 @@ class WC_Admin_Status {
// Display message if settings settings have been saved // Display message if settings settings have been saved
if ( isset( $_REQUEST['settings-updated'] ) ) { if ( isset( $_REQUEST['settings-updated'] ) ) {
echo '<div class="updated"><p>' . __( 'Your changes have been saved.', 'woocommerce' ) . '</p></div>'; echo '<div class="updated inline"><p>' . __( 'Your changes have been saved.', 'woocommerce' ) . '</p></div>';
} }
include_once( 'views/html-admin-page-status-tools.php' ); include_once( 'views/html-admin-page-status-tools.php' );

View File

@ -400,7 +400,7 @@ class WC_Admin_Webhooks {
* Table list output. * Table list output.
*/ */
private static function table_list_output() { private static function table_list_output() {
echo '<h3>' . __( 'Webhooks', 'woocommerce' ) . ' <a href="' . esc_url( wp_nonce_url( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&create-webhook=1' ), 'create-webhook' ) ) . '" class="add-new-h2">' . __( 'Add Webhook', 'woocommerce' ) . '</a></h3>'; echo '<h2>' . __( 'Webhooks', 'woocommerce' ) . ' <a href="' . esc_url( wp_nonce_url( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&create-webhook=1' ), 'create-webhook' ) ) . '" class="add-new-h2">' . __( 'Add Webhook', 'woocommerce' ) . '</a></h2>';
$webhooks_table_list = new WC_Admin_Webhooks_Table_List(); $webhooks_table_list = new WC_Admin_Webhooks_Table_List();
$webhooks_table_list->prepare_items(); $webhooks_table_list->prepare_items();

View File

@ -208,7 +208,6 @@ class WC_Admin {
return $footer_text; return $footer_text;
} }
} }
return new WC_Admin(); return new WC_Admin();

View File

@ -166,7 +166,7 @@ class WC_Tax_Rate_Importer extends WP_Importer {
} }
// Show Result // Show Result
echo '<div class="updated settings-error below-h2"><p> echo '<div class="updated settings-error"><p>
' . sprintf( __( 'Import complete - imported <strong>%s</strong> tax rates.', 'woocommerce' ), $loop ) . ' ' . sprintf( __( 'Import complete - imported <strong>%s</strong> tax rates.', 'woocommerce' ), $loop ) . '
</p></div>'; </p></div>';

View File

@ -49,7 +49,7 @@ class WC_Meta_Box_Order_Actions {
if ( ! empty( $mails ) ) { if ( ! empty( $mails ) ) {
foreach ( $mails as $mail ) { foreach ( $mails as $mail ) {
if ( in_array( $mail->id, $available_emails ) ) { if ( in_array( $mail->id, $available_emails ) && 'yes' === $mail->enabled ) {
echo '<option value="send_email_'. esc_attr( $mail->id ) .'">' . esc_html( $mail->title ) . '</option>'; echo '<option value="send_email_'. esc_attr( $mail->id ) .'">' . esc_html( $mail->title ) . '</option>';
} }
} }

View File

@ -189,7 +189,7 @@ class WC_Meta_Box_Order_Data {
<div class="order_data_column_container"> <div class="order_data_column_container">
<div class="order_data_column"> <div class="order_data_column">
<h4><?php _e( 'General Details', 'woocommerce' ); ?></h4> <h3><?php _e( 'General Details', 'woocommerce' ); ?></h3>
<p class="form-field form-field-wide"><label for="order_date"><?php _e( 'Order date:', 'woocommerce' ) ?></label> <p class="form-field form-field-wide"><label for="order_date"><?php _e( 'Order date:', 'woocommerce' ) ?></label>
<input type="text" class="date-picker" name="order_date" id="order_date" maxlength="10" value="<?php echo date_i18n( 'Y-m-d', strtotime( $post->post_date ) ); ?>" pattern="[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" />@<input type="text" class="hour" placeholder="<?php esc_attr_e( 'h', 'woocommerce' ) ?>" name="order_date_hour" id="order_date_hour" maxlength="2" size="2" value="<?php echo date_i18n( 'H', strtotime( $post->post_date ) ); ?>" pattern="\-?\d+(\.\d{0,})?" />:<input type="text" class="minute" placeholder="<?php esc_attr_e( 'm', 'woocommerce' ) ?>" name="order_date_minute" id="order_date_minute" maxlength="2" size="2" value="<?php echo date_i18n( 'i', strtotime( $post->post_date ) ); ?>" pattern="\-?\d+(\.\d{0,})?" /> <input type="text" class="date-picker" name="order_date" id="order_date" maxlength="10" value="<?php echo date_i18n( 'Y-m-d', strtotime( $post->post_date ) ); ?>" pattern="[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" />@<input type="text" class="hour" placeholder="<?php esc_attr_e( 'h', 'woocommerce' ) ?>" name="order_date_hour" id="order_date_hour" maxlength="2" size="2" value="<?php echo date_i18n( 'H', strtotime( $post->post_date ) ); ?>" pattern="\-?\d+(\.\d{0,})?" />:<input type="text" class="minute" placeholder="<?php esc_attr_e( 'm', 'woocommerce' ) ?>" name="order_date_minute" id="order_date_minute" maxlength="2" size="2" value="<?php echo date_i18n( 'i', strtotime( $post->post_date ) ); ?>" pattern="\-?\d+(\.\d{0,})?" />
@ -239,11 +239,11 @@ class WC_Meta_Box_Order_Data {
<?php do_action( 'woocommerce_admin_order_data_after_order_details', $order ); ?> <?php do_action( 'woocommerce_admin_order_data_after_order_details', $order ); ?>
</div> </div>
<div class="order_data_column"> <div class="order_data_column">
<h4> <h3>
<?php _e( 'Billing Details', 'woocommerce' ); ?> <?php _e( 'Billing Details', 'woocommerce' ); ?>
<a href="#" class="edit_address"><?php _e( 'Edit', 'woocommerce' ); ?></a> <a href="#" class="edit_address"><?php _e( 'Edit', 'woocommerce' ); ?></a>
<a href="#" class="tips load_customer_billing" data-tip="<?php esc_attr_e( 'Load billing address', 'woocommerce' ); ?>" style="display:none;"><?php _e( 'Load billing address', 'woocommerce' ); ?></a> <a href="#" class="tips load_customer_billing" data-tip="<?php esc_attr_e( 'Load billing address', 'woocommerce' ); ?>" style="display:none;"><?php _e( 'Load billing address', 'woocommerce' ); ?></a>
</h4> </h3>
<?php <?php
// Display values // Display values
echo '<div class="address">'; echo '<div class="address">';
@ -323,12 +323,12 @@ class WC_Meta_Box_Order_Data {
</div> </div>
<div class="order_data_column"> <div class="order_data_column">
<h4> <h3>
<?php _e( 'Shipping Details', 'woocommerce' ); ?> <?php _e( 'Shipping Details', 'woocommerce' ); ?>
<a href="#" class="edit_address"><?php _e( 'Edit', 'woocommerce' ); ?></a> <a href="#" class="edit_address"><?php _e( 'Edit', 'woocommerce' ); ?></a>
<a href="#" class="tips billing-same-as-shipping" data-tip="<?php esc_attr_e( 'Copy from billing', 'woocommerce' ); ?>" style="display:none;"><?php _e( 'Copy from billing', 'woocommerce' ); ?></a> <a href="#" class="tips billing-same-as-shipping" data-tip="<?php esc_attr_e( 'Copy from billing', 'woocommerce' ); ?>" style="display:none;"><?php _e( 'Copy from billing', 'woocommerce' ); ?></a>
<a href="#" class="tips load_customer_shipping" data-tip="<?php esc_attr_e( 'Load shipping address', 'woocommerce' ); ?>" style="display:none;"><?php _e( 'Load shipping address', 'woocommerce' ); ?></a> <a href="#" class="tips load_customer_shipping" data-tip="<?php esc_attr_e( 'Load shipping address', 'woocommerce' ); ?>" style="display:none;"><?php _e( 'Load shipping address', 'woocommerce' ); ?></a>
</h4> </h3>
<?php <?php
// Display values // Display values
echo '<div class="address">'; echo '<div class="address">';

View File

@ -57,6 +57,15 @@ class WC_Settings_Accounts extends WC_Settings_Page {
array( 'title' => __( 'My Account Endpoints', 'woocommerce' ), 'type' => 'title', 'desc' => __( 'Endpoints are appended to your page URLs to handle specific actions on the accounts pages. They should be unique.', 'woocommerce' ), 'id' => 'account_endpoint_options' ), array( 'title' => __( 'My Account Endpoints', 'woocommerce' ), 'type' => 'title', 'desc' => __( 'Endpoints are appended to your page URLs to handle specific actions on the accounts pages. They should be unique.', 'woocommerce' ), 'id' => 'account_endpoint_options' ),
array(
'title' => __( 'Orders', 'woocommerce' ),
'desc' => __( 'Endpoint for the My Account &rarr; Orders page', 'woocommerce' ),
'id' => 'woocommerce_myaccount_orders_endpoint',
'type' => 'text',
'default' => 'orders',
'desc_tip' => true,
),
array( array(
'title' => __( 'View Order', 'woocommerce' ), 'title' => __( 'View Order', 'woocommerce' ),
'desc' => __( 'Endpoint for the My Account &rarr; View Order page', 'woocommerce' ), 'desc' => __( 'Endpoint for the My Account &rarr; View Order page', 'woocommerce' ),
@ -66,6 +75,15 @@ class WC_Settings_Accounts extends WC_Settings_Page {
'desc_tip' => true, 'desc_tip' => true,
), ),
array(
'title' => __( 'Downloads', 'woocommerce' ),
'desc' => __( 'Endpoint for the My Account &rarr; Downloads page', 'woocommerce' ),
'id' => 'woocommerce_myaccount_downloads_endpoint',
'type' => 'text',
'default' => 'downloads',
'desc_tip' => true,
),
array( array(
'title' => __( 'Edit Account', 'woocommerce' ), 'title' => __( 'Edit Account', 'woocommerce' ),
'desc' => __( 'Endpoint for the My Account &rarr; Edit Account page', 'woocommerce' ), 'desc' => __( 'Endpoint for the My Account &rarr; Edit Account page', 'woocommerce' ),
@ -84,6 +102,15 @@ class WC_Settings_Accounts extends WC_Settings_Page {
'desc_tip' => true, 'desc_tip' => true,
), ),
array(
'title' => __( 'Payment Methods', 'woocommerce' ),
'desc' => __( 'Endpoint for the My Account &rarr; Payment Methods page', 'woocommerce' ),
'id' => 'woocommerce_myaccount_payment_methods_endpoint',
'type' => 'text',
'default' => 'payment-methods',
'desc_tip' => true,
),
array( array(
'title' => __( 'Lost Password', 'woocommerce' ), 'title' => __( 'Lost Password', 'woocommerce' ),
'desc' => __( 'Endpoint for the My Account &rarr; Lost Password page', 'woocommerce' ), 'desc' => __( 'Endpoint for the My Account &rarr; Lost Password page', 'woocommerce' ),

View File

@ -4,7 +4,7 @@ if ( ! defined( 'ABSPATH' ) ) {
} }
?> ?>
<h2><?php echo esc_html( $shipping_method->get_method_title() ); ?> <small class="wc-admin-breadcrumb"><a href="<?php echo esc_url( admin_url( 'admin.php?page=wc-settings&tab=shipping&zone_id=' . absint( $zone->get_zone_id() ) ) ); ?>" title="<?php echo esc_attr( __( 'Return to Shipping Methods', 'woocommerce' ) . ' (' . $zone->get_zone_name() . ')' ); ?>">&#x21a9;</a></small></h2> <h2><?php echo esc_html( $shipping_method->get_method_title() ); ?> <?php wc_back_link( __( 'Return to Shipping Methods', 'woocommerce' ), admin_url( 'admin.php?page=wc-settings&tab=shipping&zone_id=' . absint( $zone->get_zone_id() ) ) ); ?></h2>
<?php $shipping_method->admin_options(); ?> <?php $shipping_method->admin_options(); ?>
<p class="submit"><input type="submit" class="button button-primary" name="save_method" value="<?php _e( 'Save changes', 'woocommerce' ); ?>" /></p> <p class="submit"><input type="submit" class="button button-primary" name="save_method" value="<?php _e( 'Save changes', 'woocommerce' ); ?>" /></p>
<?php wp_nonce_field( 'woocommerce_save_method', 'woocommerce_save_method_nonce' ); ?> <?php wp_nonce_field( 'woocommerce_save_method', 'woocommerce_save_method_nonce' ); ?>

View File

@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) {
?> ?>
<div id="key-fields" class="settings-panel"> <div id="key-fields" class="settings-panel">
<h3><?php _e( 'Key Details', 'woocommerce' ); ?></h3> <h2><?php _e( 'Key Details', 'woocommerce' ); ?></h2>
<input type="hidden" id="key_id" value="<?php echo esc_attr( $key_id ); ?>" /> <input type="hidden" id="key_id" value="<?php echo esc_attr( $key_id ); ?>" />

View File

@ -7,7 +7,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<input type="hidden" name="webhook_id" value="<?php echo esc_attr( $webhook->id ); ?>" /> <input type="hidden" name="webhook_id" value="<?php echo esc_attr( $webhook->id ); ?>" />
<div id="webhook-options" class="settings-panel"> <div id="webhook-options" class="settings-panel">
<h3><?php _e( 'Webhook Data', 'woocommerce' ); ?></h3> <h2><?php _e( 'Webhook Data', 'woocommerce' ); ?></h2>
<table class="form-table"> <table class="form-table">
<tbody> <tbody>
<tr valign="top"> <tr valign="top">
@ -113,7 +113,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</div> </div>
<div id="webhook-actions" class="settings-panel"> <div id="webhook-actions" class="settings-panel">
<h3><?php _e( 'Webhook Actions', 'woocommerce' ); ?></h3> <h2><?php _e( 'Webhook Actions', 'woocommerce' ); ?></h2>
<table class="form-table"> <table class="form-table">
<tbody> <tbody>
<?php if ( '0000-00-00 00:00:00' != $webhook->post_data->post_modified_gmt ) : ?> <?php if ( '0000-00-00 00:00:00' != $webhook->post_data->post_modified_gmt ) : ?>
@ -160,7 +160,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</div> </div>
<div id="webhook-logs" class="settings-panel"> <div id="webhook-logs" class="settings-panel">
<h3><?php _e( 'Webhook Logs', 'woocommerce' ); ?></h3> <h2><?php _e( 'Webhook Logs', 'woocommerce' ); ?></h2>
<?php WC_Admin_Webhooks::logs_output( $webhook ); ?> <?php WC_Admin_Webhooks::logs_output( $webhook ); ?>
</div> </div>

View File

@ -8,6 +8,7 @@
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
?> ?>
<div class="wrap woocommerce wc_addons_wrap"> <div class="wrap woocommerce wc_addons_wrap">
<div class="icon32 icon32-posts-product" id="icon-woocommerce"><br /></div> <div class="icon32 icon32-posts-product" id="icon-woocommerce"><br /></div>
@ -31,7 +32,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( ! empty( $addon->image ) ) : ?> <?php if ( ! empty( $addon->image ) ) : ?>
<img src="<?php echo esc_attr( $addon->image ); ?>"/> <img src="<?php echo esc_attr( $addon->image ); ?>"/>
<?php else : ?> <?php else : ?>
<h3><?php echo esc_html( $addon->title ); ?></h3> <h2><?php echo esc_html( $addon->title ); ?></h2>
<?php endif; ?> <?php endif; ?>
<span class="price"><?php echo wp_kses_post( $addon->price ); ?></span> <span class="price"><?php echo wp_kses_post( $addon->price ); ?></span>
<p><?php echo wp_kses_post( $addon->excerpt ); ?></p> <p><?php echo wp_kses_post( $addon->excerpt ); ?></p>
@ -47,7 +48,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<?php if ( 'Storefront' !== $theme['Name'] ) : ?> <?php if ( 'Storefront' !== $theme['Name'] ) : ?>
<div class="storefront"> <div class="storefront">
<img src="<?php echo WC()->plugin_url(); ?>/assets/images/storefront.jpg" alt="Storefront" /> <img src="<?php echo WC()->plugin_url(); ?>/assets/images/storefront.jpg" alt="Storefront" />
<h3><?php _e( 'Looking for a WooCommerce theme?', 'woocommerce' ); ?></h3> <h2><?php _e( 'Looking for a WooCommerce theme?', 'woocommerce' ); ?></h2>
<p><?php printf( __( 'We recommend Storefront, the %sofficial%s WooCommerce theme.', 'woocommerce' ), '<em>', '</em>' ); ?></p> <p><?php printf( __( 'We recommend Storefront, the %sofficial%s WooCommerce theme.', 'woocommerce' ), '<em>', '</em>' ); ?></p>
<p><?php printf( __( 'Storefront is an intuitive &amp; flexible, %sfree%s WordPress theme offering deep integration with WooCommerce and many of the most popular customer-facing extensions.', 'woocommerce' ), '<strong>', '</strong>' ); ?></p> <p><?php printf( __( 'Storefront is an intuitive &amp; flexible, %sfree%s WordPress theme offering deep integration with WooCommerce and many of the most popular customer-facing extensions.', 'woocommerce' ), '<strong>', '</strong>' ); ?></p>
<p> <p>

View File

@ -4,23 +4,24 @@
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly exit;
} }
?> ?>
<div class="wrap woocommerce"> <div class="wrap woocommerce">
<div class="icon32 icon32-woocommerce-reports" id="icon-woocommerce"><br /></div><h2 class="nav-tab-wrapper woo-nav-tab-wrapper"> <div class="icon32 icon32-woocommerce-reports" id="icon-woocommerce"><br /></div>
<h1><?php echo sprintf( esc_html__( '%s Report' ), $reports[ $current_tab ]['title'] ); ?></h1>
<h2 class="nav-tab-wrapper woo-nav-tab-wrapper">
<?php <?php
foreach ( $reports as $key => $report_group ) { foreach ( $reports as $key => $report_group ) {
echo '<a href="'.admin_url( 'admin.php?page=wc-reports&tab=' . urlencode( $key ) ).'" class="nav-tab '; echo '<a href="'.admin_url( 'admin.php?page=wc-reports&tab=' . urlencode( $key ) ).'" class="nav-tab ';
if ( $current_tab == $key ) echo 'nav-tab-active'; if ( $current_tab == $key ) echo 'nav-tab-active';
echo '">' . esc_html( $report_group[ 'title' ] ) . '</a>'; echo '">' . esc_html( $report_group[ 'title' ] ) . '</a>';
} }
?>
<?php do_action('wc_reports_tabs'); ?>
</h2>
do_action( 'wc_reports_tabs' );
?>
</h2>
<?php if ( sizeof( $reports[ $current_tab ]['reports'] ) > 1 ) { <?php if ( sizeof( $reports[ $current_tab ]['reports'] ) > 1 ) {
?> ?>
<ul class="subsubsub"> <ul class="subsubsub">
@ -52,8 +53,11 @@ if ( ! defined( 'ABSPATH' ) ) {
$report = $reports[ $current_tab ][ 'reports' ][ $current_report ]; $report = $reports[ $current_tab ][ 'reports' ][ $current_report ];
if ( ! isset( $report['hide_title'] ) || $report['hide_title'] != true ) if ( ! isset( $report['hide_title'] ) || $report['hide_title'] != true ) {
echo '<h3>' . $report['title'] . '</h3>'; echo '<h2>' . esc_html( $report['title'] ) . '</h2>';
} else {
echo '<h2 class="screen-reader-text">' . esc_html( $report['title'] ) . '</h2>';
}
if ( $report['description'] ) if ( $report['description'] )
echo '<p>' . $report['description'] . '</p>'; echo '<p>' . $report['description'] . '</p>';

View File

@ -8,11 +8,10 @@ if ( ! defined( 'ABSPATH' ) ) {
} }
?> ?>
<?php if ( $logs ) : ?> <?php if ( $logs ) : ?>
<div id="log-viewer-select"> <div id="log-viewer-select">
<div class="alignleft"> <div class="alignleft">
<h3><?php printf( __( 'Log file: %s (%s)', 'woocommerce' ), esc_html( $viewed_log ), date_i18n( get_option( 'date_format') . ' ' . get_option( 'time_format'), filemtime( WC_LOG_DIR . $viewed_log ) ) ); ?></h3> <h2><?php printf( __( 'Log file: %s (%s)', 'woocommerce' ), esc_html( $viewed_log ), date_i18n( get_option( 'date_format') . ' ' . get_option( 'time_format'), filemtime( WC_LOG_DIR . $viewed_log ) ) ); ?></h2>
</div> </div>
<div class="alignright"> <div class="alignright">
<form action="<?php echo admin_url( 'admin.php?page=wc-status&tab=logs' ); ?>" method="post"> <form action="<?php echo admin_url( 'admin.php?page=wc-status&tab=logs' ); ?>" method="post">
@ -30,5 +29,5 @@ if ( ! defined( 'ABSPATH' ) ) {
<textarea cols="70" rows="25"><?php echo esc_textarea( file_get_contents( WC_LOG_DIR . $viewed_log ) ); ?></textarea> <textarea cols="70" rows="25"><?php echo esc_textarea( file_get_contents( WC_LOG_DIR . $viewed_log ) ); ?></textarea>
</div> </div>
<?php else : ?> <?php else : ?>
<div class="updated woocommerce-message below-h2"><p><?php _e( 'There are currently no logs to view.', 'woocommerce' ); ?></p></div> <div class="updated woocommerce-message inline"><p><?php _e( 'There are currently no logs to view.', 'woocommerce' ); ?></p></div>
<?php endif; ?> <?php endif; ?>

View File

@ -8,7 +8,7 @@ if ( ! defined( 'ABSPATH' ) ) {
} }
?> ?>
<div class="updated woocommerce-message"> <div class="updated woocommerce-message inline">
<p><?php _e( 'Please copy and paste this information in your ticket when contacting support:', 'woocommerce' ); ?> </p> <p><?php _e( 'Please copy and paste this information in your ticket when contacting support:', 'woocommerce' ); ?> </p>
<p class="submit"><a href="#" class="button-primary debug-report"><?php _e( 'Get System Report', 'woocommerce' ); ?></a> <p class="submit"><a href="#" class="button-primary debug-report"><?php _e( 'Get System Report', 'woocommerce' ); ?></a>
<a class="button-secondary docs" href="http://docs.woothemes.com/document/understanding-the-woocommerce-system-status-report/" target="_blank"><?php _e( 'Understanding the Status Report', 'woocommerce' ); ?></a></p> <a class="button-secondary docs" href="http://docs.woothemes.com/document/understanding-the-woocommerce-system-status-report/" target="_blank"><?php _e( 'Understanding the Status Report', 'woocommerce' ); ?></a></p>
@ -20,7 +20,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<table class="wc_status_table widefat" cellspacing="0" id="status"> <table class="wc_status_table widefat" cellspacing="0" id="status">
<thead> <thead>
<tr> <tr>
<th colspan="3" data-export-label="WordPress Environment"><?php _e( 'WordPress Environment', 'woocommerce' ); ?></th> <th colspan="3" data-export-label="WordPress Environment"><h2><?php _e( 'WordPress Environment', 'woocommerce' ); ?></h2></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -110,7 +110,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<table class="wc_status_table widefat" cellspacing="0"> <table class="wc_status_table widefat" cellspacing="0">
<thead> <thead>
<tr> <tr>
<th colspan="3" data-export-label="Server Environment"><?php _e( 'Server Environment', 'woocommerce' ); ?></th> <th colspan="3" data-export-label="Server Environment"><h2><?php _e( 'Server Environment', 'woocommerce' ); ?></h2></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -309,7 +309,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<table class="wc_status_table widefat" cellspacing="0"> <table class="wc_status_table widefat" cellspacing="0">
<thead> <thead>
<tr> <tr>
<th colspan="3" data-export-label="Database"><?php _e( 'Database', 'woocommerce' ); ?></th> <th colspan="3" data-export-label="Database"><h2><?php _e( 'Database', 'woocommerce' ); ?></h2></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -351,7 +351,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<table class="wc_status_table widefat" cellspacing="0"> <table class="wc_status_table widefat" cellspacing="0">
<thead> <thead>
<tr> <tr>
<th colspan="3" data-export-label="Active Plugins (<?php echo count( (array) get_option( 'active_plugins' ) ); ?>)"><?php _e( 'Active Plugins', 'woocommerce' ); ?> (<?php echo count( (array) get_option( 'active_plugins' ) ); ?>)</th> <th colspan="3" data-export-label="Active Plugins (<?php echo count( (array) get_option( 'active_plugins' ) ); ?>)"><h2><?php _e( 'Active Plugins', 'woocommerce' ); ?> (<?php echo count( (array) get_option( 'active_plugins' ) ); ?>)</h2></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -423,7 +423,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<table class="wc_status_table widefat" cellspacing="0"> <table class="wc_status_table widefat" cellspacing="0">
<thead> <thead>
<tr> <tr>
<th colspan="3" data-export-label="Settings"><?php _e( 'Settings', 'woocommerce' ); ?></th> <th colspan="3" data-export-label="Settings"><h2><?php _e( 'Settings', 'woocommerce' ); ?></h2></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -462,7 +462,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<table class="wc_status_table widefat" cellspacing="0"> <table class="wc_status_table widefat" cellspacing="0">
<thead> <thead>
<tr> <tr>
<th colspan="3" data-export-label="API"><?php _e( 'API', 'woocommerce' ); ?></th> <th colspan="3" data-export-label="API"><h2><?php _e( 'API', 'woocommerce' ); ?></h2></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -481,7 +481,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<table class="wc_status_table widefat" cellspacing="0"> <table class="wc_status_table widefat" cellspacing="0">
<thead> <thead>
<tr> <tr>
<th colspan="3" data-export-label="WC Pages"><?php _e( 'WC Pages', 'woocommerce' ); ?></th> <th colspan="3" data-export-label="WC Pages"><h2><?php _e( 'WC Pages', 'woocommerce' ); ?></h2></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -528,6 +528,9 @@ if ( ! defined( 'ABSPATH' ) ) {
if ( ! $page_id ) { if ( ! $page_id ) {
echo '<mark class="error">' . __( 'Page not set', 'woocommerce' ) . '</mark>'; echo '<mark class="error">' . __( 'Page not set', 'woocommerce' ) . '</mark>';
$error = true; $error = true;
} else if ( get_post_status( $page_id ) !== 'publish' ) {
echo '<mark class="error">' . sprintf( __( 'Page visibility should be %spublic%s', 'woocommerce' ), '<a href="https://codex.wordpress.org/Content_Visibility" target="_blank">', '</a>' ) . '</mark>';
$error = true;
} else { } else {
// Shortcode check // Shortcode check
@ -559,7 +562,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<table class="wc_status_table widefat" cellspacing="0"> <table class="wc_status_table widefat" cellspacing="0">
<thead> <thead>
<tr> <tr>
<th colspan="3" data-export-label="Taxonomies"><?php _e( 'Taxonomies', 'woocommerce' ); ?><?php echo wc_help_tip( __( 'A list of taxonomy terms that can be used in regard to order/product statuses.', 'woocommerce' ) ); ?></th> <th colspan="3" data-export-label="Taxonomies"><h2><?php _e( 'Taxonomies', 'woocommerce' ); ?><?php echo wc_help_tip( __( 'A list of taxonomy terms that can be used in regard to order/product statuses.', 'woocommerce' ) ); ?></h2></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -580,7 +583,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<table class="wc_status_table widefat" cellspacing="0"> <table class="wc_status_table widefat" cellspacing="0">
<thead> <thead>
<tr> <tr>
<th colspan="3" data-export-label="Theme"><?php _e( 'Theme', 'woocommerce' ); ?></th> <th colspan="3" data-export-label="Theme"><h2><?php _e( 'Theme', 'woocommerce' ); ?></h2></th>
</tr> </tr>
</thead> </thead>
<?php <?php
@ -662,7 +665,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<table class="wc_status_table widefat" cellspacing="0"> <table class="wc_status_table widefat" cellspacing="0">
<thead> <thead>
<tr> <tr>
<th colspan="3" data-export-label="Templates"><?php _e( 'Templates', 'woocommerce' ); ?><?php echo wc_help_tip( __( 'This section shows any files that are overriding the default WooCommerce template pages.', 'woocommerce' ) ); ?></th> <th colspan="3" data-export-label="Templates"><h2><?php _e( 'Templates', 'woocommerce' ); ?><?php echo wc_help_tip( __( 'This section shows any files that are overriding the default WooCommerce template pages.', 'woocommerce' ) ); ?></h2></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -8,16 +8,10 @@ if ( ! defined( 'ABSPATH' ) ) {
} }
?> ?>
<form method="post" action="options.php"> <form method="post" action="options.php">
<?php settings_fields( 'woocommerce_status_settings_fields' ); ?> <?php settings_fields( 'woocommerce_status_settings_fields' ); ?>
<?php $options = wp_parse_args( get_option( 'woocommerce_status_options', array() ), array( 'uninstall_data' => 0, 'template_debug_mode' => 0, 'shipping_debug_mode' => 0 ) ); ?> <?php $options = wp_parse_args( get_option( 'woocommerce_status_options', array() ), array( 'uninstall_data' => 0, 'template_debug_mode' => 0, 'shipping_debug_mode' => 0 ) ); ?>
<table class="wc_status_table widefat" cellspacing="0"> <table class="wc_status_table widefat" cellspacing="0">
<thead class="tools">
<tr>
<th colspan="2"><?php _e( 'Tools', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody class="tools"> <tbody class="tools">
<?php foreach ( $tools as $action => $tool ) : ?> <?php foreach ( $tools as $action => $tool ) : ?>
<tr class="<?php echo sanitize_html_class( $action ); ?>"> <tr class="<?php echo sanitize_html_class( $action ); ?>">

View File

@ -8,15 +8,18 @@ if ( ! defined( 'ABSPATH' ) ) {
} }
$current_tab = ! empty( $_REQUEST['tab'] ) ? sanitize_title( $_REQUEST['tab'] ) : 'status'; $current_tab = ! empty( $_REQUEST['tab'] ) ? sanitize_title( $_REQUEST['tab'] ) : 'status';
$tabs = array(
'status' => __( 'System Status', 'woocommerce' ),
'tools' => __( 'Tools', 'woocommerce' ),
'logs' => __( 'Logs', 'woocommerce' ),
);
?> ?>
<div class="wrap woocommerce"> <div class="wrap woocommerce">
<div class="icon32 icon32-woocommerce-status" id="icon-woocommerce"><br /></div><h2 class="nav-tab-wrapper woo-nav-tab-wrapper"> <div class="icon32 icon32-woocommerce-status" id="icon-woocommerce"><br /></div>
<h1><?php echo esc_html( $tabs[ $current_tab ] ); ?></h1>
<h2 class="nav-tab-wrapper woo-nav-tab-wrapper">
<?php <?php
$tabs = array(
'status' => __( 'System Status', 'woocommerce' ),
'tools' => __( 'Tools', 'woocommerce' ),
'logs' => __( 'Logs', 'woocommerce' ),
);
foreach ( $tabs as $name => $label ) { foreach ( $tabs as $name => $label ) {
echo '<a href="' . admin_url( 'admin.php?page=wc-status&tab=' . $name ) . '" class="nav-tab '; echo '<a href="' . admin_url( 'admin.php?page=wc-status&tab=' . $name ) . '" class="nav-tab ';
if ( $current_tab == $name ) echo 'nav-tab-active'; if ( $current_tab == $name ) echo 'nav-tab-active';

View File

@ -5,10 +5,12 @@
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
?> ?>
<div class="wrap woocommerce"> <div class="wrap woocommerce">
<form method="<?php echo esc_attr( apply_filters( 'woocommerce_settings_form_method_tab_' . $current_tab, 'post' ) ); ?>" id="mainform" action="" enctype="multipart/form-data"> <form method="<?php echo esc_attr( apply_filters( 'woocommerce_settings_form_method_tab_' . $current_tab, 'post' ) ); ?>" id="mainform" action="" enctype="multipart/form-data">
<div class="icon32 icon32-woocommerce-settings" id="icon-woocommerce"><br /></div> <div class="icon32 icon32-woocommerce-settings" id="icon-woocommerce"><br /></div>
<h1 class="screen-reader-text"><?php echo esc_html( $tabs[ $current_tab ] ); ?></h1>
<h2 class="nav-tab-wrapper woo-nav-tab-wrapper"> <h2 class="nav-tab-wrapper woo-nav-tab-wrapper">
<?php <?php
foreach ( $tabs as $name => $label ) { foreach ( $tabs as $name => $label ) {
@ -18,7 +20,6 @@ if ( ! defined( 'ABSPATH' ) ) {
do_action( 'woocommerce_settings_tabs' ); do_action( 'woocommerce_settings_tabs' );
?> ?>
</h2> </h2>
<?php <?php
do_action( 'woocommerce_sections_' . $current_tab ); do_action( 'woocommerce_sections_' . $current_tab );
@ -27,7 +28,6 @@ if ( ! defined( 'ABSPATH' ) ) {
do_action( 'woocommerce_settings_' . $current_tab ); do_action( 'woocommerce_settings_' . $current_tab );
do_action( 'woocommerce_settings_tabs_' . $current_tab ); // @deprecated hook do_action( 'woocommerce_settings_tabs_' . $current_tab ); // @deprecated hook
?> ?>
<p class="submit"> <p class="submit">
<?php if ( ! isset( $GLOBALS['hide_save_button'] ) ) : ?> <?php if ( ! isset( $GLOBALS['hide_save_button'] ) ) : ?>
<input name="save" class="button-primary" type="submit" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>" /> <input name="save" class="button-primary" type="submit" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>" />

View File

@ -11,7 +11,10 @@ if ( ! defined( 'ABSPATH' ) ) {
<div id="poststuff" class="woocommerce-reports-wide"> <div id="poststuff" class="woocommerce-reports-wide">
<div class="postbox"> <div class="postbox">
<h3 class="stats_range">
<h3 class="screen-reader-text"><?php echo esc_html( $ranges[ $current_range ] ); ?></h3>
<div class="stats_range">
<?php $this->get_export_button(); ?> <?php $this->get_export_button(); ?>
<ul> <ul>
<?php <?php
@ -43,7 +46,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</form> </form>
</li> </li>
</ul> </ul>
</h3> </div>
<?php if ( empty( $hide_sidebar ) ) : ?> <?php if ( empty( $hide_sidebar ) ) : ?>
<div class="inside chart-with-sidebar"> <div class="inside chart-with-sidebar">
<div class="chart-sidebar"> <div class="chart-sidebar">

View File

@ -215,6 +215,7 @@ class WC_API_Orders extends WC_API_Resource {
'tax_lines' => array(), 'tax_lines' => array(),
'fee_lines' => array(), 'fee_lines' => array(),
'coupon_lines' => array(), 'coupon_lines' => array(),
'is_vat_exempt' => $order->is_vat_exempt === 'yes' ? true : false,
); );
// Add line items. // Add line items.
@ -471,6 +472,11 @@ class WC_API_Orders extends WC_API_Resource {
} }
} }
// set is vat exempt
if ( isset( $data['is_vat_exempt'] ) ) {
update_post_meta( $order->id, '_is_vat_exempt', $data['is_vat_exempt'] ? 'yes' : 'no' );
}
// calculate totals and set them // calculate totals and set them
$order->calculate_totals(); $order->calculate_totals();

View File

@ -1546,87 +1546,93 @@ class WC_AJAX {
// Action // Action
$items = apply_filters( 'woocommerce_ajax_calc_line_taxes', $items, $order_id, $country, $_POST ); $items = apply_filters( 'woocommerce_ajax_calc_line_taxes', $items, $order_id, $country, $_POST );
// Get items and fees taxes $is_vat_exempt = get_post_meta( $order_id, '_is_vat_exempt', true );
if ( isset( $items['order_item_id'] ) ) {
$line_total = $line_subtotal = $order_item_tax_class = array();
foreach ( $items['order_item_id'] as $item_id ) { // Tax is calculated only if tax is enabled and order is not vat exempted
$item_id = absint( $item_id ); if ( wc_tax_enabled() && $is_vat_exempt !== 'yes' ) {
$line_total[ $item_id ] = isset( $items['line_total'][ $item_id ] ) ? wc_format_decimal( $items['line_total'][ $item_id ] ) : 0;
$line_subtotal[ $item_id ] = isset( $items['line_subtotal'][ $item_id ] ) ? wc_format_decimal( $items['line_subtotal'][ $item_id ] ) : $line_total[ $item_id ];
$order_item_tax_class[ $item_id ] = isset( $items['order_item_tax_class'][ $item_id ] ) ? sanitize_text_field( $items['order_item_tax_class'][ $item_id ] ) : '';
$product_id = $order->get_item_meta( $item_id, '_product_id', true );
// Get product details // Get items and fees taxes
if ( get_post_type( $product_id ) == 'product' ) { if ( isset( $items['order_item_id'] ) ) {
$_product = wc_get_product( $product_id ); $line_total = $line_subtotal = $order_item_tax_class = array();
$item_tax_status = $_product->get_tax_status();
} else {
$item_tax_status = 'taxable';
}
if ( '0' !== $order_item_tax_class[ $item_id ] && 'taxable' === $item_tax_status ) { foreach ( $items['order_item_id'] as $item_id ) {
$tax_rates = WC_Tax::find_rates( array( $item_id = absint( $item_id );
'country' => $country, $line_total[ $item_id ] = isset( $items['line_total'][ $item_id ] ) ? wc_format_decimal( $items['line_total'][ $item_id ] ) : 0;
'state' => $state, $line_subtotal[ $item_id ] = isset( $items['line_subtotal'][ $item_id ] ) ? wc_format_decimal( $items['line_subtotal'][ $item_id ] ) : $line_total[ $item_id ];
'postcode' => $postcode, $order_item_tax_class[ $item_id ] = isset( $items['order_item_tax_class'][ $item_id ] ) ? sanitize_text_field( $items['order_item_tax_class'][ $item_id ] ) : '';
'city' => $city, $product_id = $order->get_item_meta( $item_id, '_product_id', true );
'tax_class' => $order_item_tax_class[ $item_id ]
) );
$line_taxes = WC_Tax::calc_tax( $line_total[ $item_id ], $tax_rates, false ); // Get product details
$line_subtotal_taxes = WC_Tax::calc_tax( $line_subtotal[ $item_id ], $tax_rates, false ); if ( get_post_type( $product_id ) == 'product' ) {
$_product = wc_get_product( $product_id );
// Set the new line_tax $item_tax_status = $_product->get_tax_status();
foreach ( $line_taxes as $_tax_id => $_tax_value ) { } else {
$items['line_tax'][ $item_id ][ $_tax_id ] = $_tax_value; $item_tax_status = 'taxable';
} }
// Set the new line_subtotal_tax if ( '0' !== $order_item_tax_class[ $item_id ] && 'taxable' === $item_tax_status ) {
foreach ( $line_subtotal_taxes as $_tax_id => $_tax_value ) { $tax_rates = WC_Tax::find_rates( array(
$items['line_subtotal_tax'][ $item_id ][ $_tax_id ] = $_tax_value; 'country' => $country,
} 'state' => $state,
'postcode' => $postcode,
'city' => $city,
'tax_class' => $order_item_tax_class[ $item_id ]
) );
// Sum the item taxes $line_taxes = WC_Tax::calc_tax( $line_total[ $item_id ], $tax_rates, false );
foreach ( array_keys( $taxes + $line_taxes ) as $key ) { $line_subtotal_taxes = WC_Tax::calc_tax( $line_subtotal[ $item_id ], $tax_rates, false );
$taxes[ $key ] = ( isset( $line_taxes[ $key ] ) ? $line_taxes[ $key ] : 0 ) + ( isset( $taxes[ $key ] ) ? $taxes[ $key ] : 0 );
}
}
}
}
// Get shipping taxes // Set the new line_tax
if ( isset( $items['shipping_method_id'] ) ) { foreach ( $line_taxes as $_tax_id => $_tax_value ) {
$matched_tax_rates = array(); $items['line_tax'][ $item_id ][ $_tax_id ] = $_tax_value;
}
$tax_rates = WC_Tax::find_rates( array( // Set the new line_subtotal_tax
'country' => $country, foreach ( $line_subtotal_taxes as $_tax_id => $_tax_value ) {
'state' => $state, $items['line_subtotal_tax'][ $item_id ][ $_tax_id ] = $_tax_value;
'postcode' => $postcode, }
'city' => $city,
'tax_class' => ''
) );
if ( $tax_rates ) { // Sum the item taxes
foreach ( $tax_rates as $key => $rate ) { foreach ( array_keys( $taxes + $line_taxes ) as $key ) {
if ( isset( $rate['shipping'] ) && 'yes' == $rate['shipping'] ) { $taxes[ $key ] = ( isset( $line_taxes[ $key ] ) ? $line_taxes[ $key ] : 0 ) + ( isset( $taxes[ $key ] ) ? $taxes[ $key ] : 0 );
$matched_tax_rates[ $key ] = $rate; }
} }
} }
} }
$shipping_cost = $shipping_taxes = array(); // Get shipping taxes
if ( isset( $items['shipping_method_id'] ) ) {
$matched_tax_rates = array();
foreach ( $items['shipping_method_id'] as $item_id ) { $tax_rates = WC_Tax::find_rates( array(
$item_id = absint( $item_id ); 'country' => $country,
$shipping_cost[ $item_id ] = isset( $items['shipping_cost'][ $item_id ] ) ? wc_format_decimal( $items['shipping_cost'][ $item_id ] ) : 0; 'state' => $state,
$_shipping_taxes = WC_Tax::calc_shipping_tax( $shipping_cost[ $item_id ], $matched_tax_rates ); 'postcode' => $postcode,
'city' => $city,
'tax_class' => ''
) );
// Set the new shipping_taxes if ( $tax_rates ) {
foreach ( $_shipping_taxes as $_tax_id => $_tax_value ) { foreach ( $tax_rates as $key => $rate ) {
$items['shipping_taxes'][ $item_id ][ $_tax_id ] = $_tax_value; if ( isset( $rate['shipping'] ) && 'yes' == $rate['shipping'] ) {
$matched_tax_rates[ $key ] = $rate;
}
}
}
$shipping_taxes[ $_tax_id ] = isset( $shipping_taxes[ $_tax_id ] ) ? $shipping_taxes[ $_tax_id ] + $_tax_value : $_tax_value; $shipping_cost = $shipping_taxes = array();
foreach ( $items['shipping_method_id'] as $item_id ) {
$item_id = absint( $item_id );
$shipping_cost[ $item_id ] = isset( $items['shipping_cost'][ $item_id ] ) ? wc_format_decimal( $items['shipping_cost'][ $item_id ] ) : 0;
$_shipping_taxes = WC_Tax::calc_shipping_tax( $shipping_cost[ $item_id ], $matched_tax_rates );
// Set the new shipping_taxes
foreach ( $_shipping_taxes as $_tax_id => $_tax_value ) {
$items['shipping_taxes'][ $item_id ][ $_tax_id ] = $_tax_value;
$shipping_taxes[ $_tax_id ] = isset( $shipping_taxes[ $_tax_id ] ) ? $shipping_taxes[ $_tax_id ] + $_tax_value : $_tax_value;
}
} }
} }
} }
@ -2986,12 +2992,12 @@ class WC_AJAX {
* Handle submissions from assets/js/settings-views-html-settings-tax.js Backbone model. * Handle submissions from assets/js/settings-views-html-settings-tax.js Backbone model.
*/ */
public static function tax_rates_save_changes() { public static function tax_rates_save_changes() {
if ( ! isset( $_POST['current_class'], $_POST['wc_tax_nonce'], $_POST['changes'] ) ) { if ( ! isset( $_POST['wc_tax_nonce'], $_POST['changes'] ) ) {
wp_send_json_error( 'missing_fields' ); wp_send_json_error( 'missing_fields' );
exit; exit;
} }
$current_class = $_POST['current_class']; // This is sanitized seven lines later. $current_class = ! empty( $_POST['current_class'] ) ? $_POST['current_class'] : ''; // This is sanitized seven lines later.
if ( ! wp_verify_nonce( $_POST['wc_tax_nonce'], 'wc_tax_nonce-class:' . $current_class ) ) { if ( ! wp_verify_nonce( $_POST['wc_tax_nonce'], 'wc_tax_nonce-class:' . $current_class ) ) {
wp_send_json_error( 'bad_nonce' ); wp_send_json_error( 'bad_nonce' );

View File

@ -72,6 +72,7 @@ class WC_Emails {
'woocommerce_order_status_pending_to_on-hold', 'woocommerce_order_status_pending_to_on-hold',
'woocommerce_order_status_failed_to_processing', 'woocommerce_order_status_failed_to_processing',
'woocommerce_order_status_failed_to_completed', 'woocommerce_order_status_failed_to_completed',
'woocommerce_order_status_failed_to_on-hold',
'woocommerce_order_status_on-hold_to_processing', 'woocommerce_order_status_on-hold_to_processing',
'woocommerce_order_status_on-hold_to_cancelled', 'woocommerce_order_status_on-hold_to_cancelled',
'woocommerce_order_status_on-hold_to_failed', 'woocommerce_order_status_on-hold_to_failed',

View File

@ -84,7 +84,9 @@ class WC_Geolocation {
} }
/** /**
* Get user IP Address using a service. * Get user IP Address using an external service.
* This is used mainly as a fallback for users on localhost where
* get_ip_address() will be a local IP and non-geolocatable.
* @return string * @return string
*/ */
public static function get_external_ip_address() { public static function get_external_ip_address() {

View File

@ -346,12 +346,6 @@ class WC_Install {
} }
} }
if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}woocommerce_tax_rate_locations';" ) ) {
if ( $wpdb->get_var( "SHOW INDEX FROM `{$wpdb->prefix}woocommerce_tax_rate_locations` WHERE Key_name LIKE 'location_type_code';" ) ) {
$wpdb->query( "DROP INDEX `location_type_code` ON {$wpdb->prefix}woocommerce_tax_rate_locations;" );
}
}
dbDelta( self::get_schema() ); dbDelta( self::get_schema() );
} }

View File

@ -256,6 +256,11 @@ class WC_Post_types {
'set_featured_image' => __( 'Set product image', 'woocommerce' ), 'set_featured_image' => __( 'Set product image', 'woocommerce' ),
'remove_featured_image' => __( 'Remove product image', 'woocommerce' ), 'remove_featured_image' => __( 'Remove product image', 'woocommerce' ),
'use_featured_image' => __( 'Use as product image', 'woocommerce' ), 'use_featured_image' => __( 'Use as product image', 'woocommerce' ),
'insert_into_item' => __( 'Insert into product', 'woocommerce' ),
'uploaded_to_this_item' => __( 'Uploaded to this product', 'woocommerce' ),
'filter_items_list' => __( 'Filter products', 'woocommerce' ),
'items_list_navigation' => __( 'Products navigation', 'woocommerce' ),
'items_list' => __( 'Products list', 'woocommerce' ),
), ),
'description' => __( 'This is where you can add new products to your store.', 'woocommerce' ), 'description' => __( 'This is where you can add new products to your store.', 'woocommerce' ),
'public' => true, 'public' => true,
@ -291,20 +296,23 @@ class WC_Post_types {
apply_filters( 'woocommerce_register_post_type_shop_order', apply_filters( 'woocommerce_register_post_type_shop_order',
array( array(
'labels' => array( 'labels' => array(
'name' => __( 'Orders', 'woocommerce' ), 'name' => __( 'Orders', 'woocommerce' ),
'singular_name' => _x( 'Order', 'shop_order post type singular name', 'woocommerce' ), 'singular_name' => _x( 'Order', 'shop_order post type singular name', 'woocommerce' ),
'add_new' => __( 'Add Order', 'woocommerce' ), 'add_new' => __( 'Add Order', 'woocommerce' ),
'add_new_item' => __( 'Add New Order', 'woocommerce' ), 'add_new_item' => __( 'Add New Order', 'woocommerce' ),
'edit' => __( 'Edit', 'woocommerce' ), 'edit' => __( 'Edit', 'woocommerce' ),
'edit_item' => __( 'Edit Order', 'woocommerce' ), 'edit_item' => __( 'Edit Order', 'woocommerce' ),
'new_item' => __( 'New Order', 'woocommerce' ), 'new_item' => __( 'New Order', 'woocommerce' ),
'view' => __( 'View Order', 'woocommerce' ), 'view' => __( 'View Order', 'woocommerce' ),
'view_item' => __( 'View Order', 'woocommerce' ), 'view_item' => __( 'View Order', 'woocommerce' ),
'search_items' => __( 'Search Orders', 'woocommerce' ), 'search_items' => __( 'Search Orders', 'woocommerce' ),
'not_found' => __( 'No Orders found', 'woocommerce' ), 'not_found' => __( 'No Orders found', 'woocommerce' ),
'not_found_in_trash' => __( 'No Orders found in trash', 'woocommerce' ), 'not_found_in_trash' => __( 'No Orders found in trash', 'woocommerce' ),
'parent' => __( 'Parent Orders', 'woocommerce' ), 'parent' => __( 'Parent Orders', 'woocommerce' ),
'menu_name' => _x( 'Orders', 'Admin menu name', 'woocommerce' ) 'menu_name' => _x( 'Orders', 'Admin menu name', 'woocommerce' ),
'filter_items_list' => __( 'Filter orders', 'woocommerce' ),
'items_list_navigation' => __( 'Orders navigation', 'woocommerce' ),
'items_list' => __( 'Orders list', 'woocommerce' ),
), ),
'description' => __( 'This is where store orders are stored.', 'woocommerce' ), 'description' => __( 'This is where store orders are stored.', 'woocommerce' ),
'public' => false, 'public' => false,
@ -349,20 +357,23 @@ class WC_Post_types {
apply_filters( 'woocommerce_register_post_type_shop_coupon', apply_filters( 'woocommerce_register_post_type_shop_coupon',
array( array(
'labels' => array( 'labels' => array(
'name' => __( 'Coupons', 'woocommerce' ), 'name' => __( 'Coupons', 'woocommerce' ),
'singular_name' => __( 'Coupon', 'woocommerce' ), 'singular_name' => __( 'Coupon', 'woocommerce' ),
'menu_name' => _x( 'Coupons', 'Admin menu name', 'woocommerce' ), 'menu_name' => _x( 'Coupons', 'Admin menu name', 'woocommerce' ),
'add_new' => __( 'Add Coupon', 'woocommerce' ), 'add_new' => __( 'Add Coupon', 'woocommerce' ),
'add_new_item' => __( 'Add New Coupon', 'woocommerce' ), 'add_new_item' => __( 'Add New Coupon', 'woocommerce' ),
'edit' => __( 'Edit', 'woocommerce' ), 'edit' => __( 'Edit', 'woocommerce' ),
'edit_item' => __( 'Edit Coupon', 'woocommerce' ), 'edit_item' => __( 'Edit Coupon', 'woocommerce' ),
'new_item' => __( 'New Coupon', 'woocommerce' ), 'new_item' => __( 'New Coupon', 'woocommerce' ),
'view' => __( 'View Coupons', 'woocommerce' ), 'view' => __( 'View Coupons', 'woocommerce' ),
'view_item' => __( 'View Coupon', 'woocommerce' ), 'view_item' => __( 'View Coupon', 'woocommerce' ),
'search_items' => __( 'Search Coupons', 'woocommerce' ), 'search_items' => __( 'Search Coupons', 'woocommerce' ),
'not_found' => __( 'No Coupons found', 'woocommerce' ), 'not_found' => __( 'No Coupons found', 'woocommerce' ),
'not_found_in_trash' => __( 'No Coupons found in trash', 'woocommerce' ), 'not_found_in_trash' => __( 'No Coupons found in trash', 'woocommerce' ),
'parent' => __( 'Parent Coupon', 'woocommerce' ) 'parent' => __( 'Parent Coupon', 'woocommerce' ),
'filter_items_list' => __( 'Filter coupons', 'woocommerce' ),
'items_list_navigation' => __( 'Coupons navigation', 'woocommerce' ),
'items_list' => __( 'Coupons list', 'woocommerce' ),
), ),
'description' => __( 'This is where you can add new coupons that customers can use in your store.', 'woocommerce' ), 'description' => __( 'This is where you can add new coupons that customers can use in your store.', 'woocommerce' ),
'public' => false, 'public' => false,

View File

@ -134,12 +134,11 @@ class WC_Product_Grouped extends WC_Product {
$child_prices = array(); $child_prices = array();
foreach ( $this->get_children() as $child_id ) { foreach ( $this->get_children() as $child_id ) {
$child = wc_get_product( $child_id ); $child = wc_get_product( $child_id );
$child_prices[] = $child->get_price(); $child_prices[] = 'incl' === $tax_display_mode ? $child->get_price_including_tax() : $child->get_price_excluding_tax();
} }
$child_prices = array_unique( $child_prices ); $child_prices = array_unique( $child_prices );
$get_price_method = 'get_price_' . $tax_display_mode . 'uding_tax';
if ( ! empty( $child_prices ) ) { if ( ! empty( $child_prices ) ) {
$min_price = min( $child_prices ); $min_price = min( $child_prices );
@ -150,16 +149,11 @@ class WC_Product_Grouped extends WC_Product {
} }
if ( $min_price ) { if ( $min_price ) {
if ( $min_price == $max_price ) { if ( $min_price === $max_price ) {
$display_price = wc_price( $this->$get_price_method( 1, $min_price ) ); $price = wc_price( $min_price ) . $this->get_price_suffix();
} else { } else {
$from = wc_price( $this->$get_price_method( 1, $min_price ) ); $price = sprintf( _x( '%1$s&ndash;%2$s', 'Price range: from-to', 'woocommerce' ), wc_price( $min_price ), wc_price( $max_price ) ) . $this->get_price_suffix();
$to = wc_price( $this->$get_price_method( 1, $max_price ) );
$display_price = sprintf( _x( '%1$s&ndash;%2$s', 'Price range: from-to', 'woocommerce' ), $from, $to );
} }
$price .= $display_price . $this->get_price_suffix();
$price = apply_filters( 'woocommerce_grouped_price_html', $price, $this ); $price = apply_filters( 'woocommerce_grouped_price_html', $price, $this );
} else { } else {
$price = apply_filters( 'woocommerce_grouped_empty_price_html', '', $this ); $price = apply_filters( 'woocommerce_grouped_empty_price_html', '', $this );

View File

@ -60,16 +60,19 @@ class WC_Query {
* Init query vars by loading options. * Init query vars by loading options.
*/ */
public function init_query_vars() { public function init_query_vars() {
// Query vars to add to WP // Query vars to add to WP.
$this->query_vars = array( $this->query_vars = array(
// Checkout actions // Checkout actions.
'order-pay' => get_option( 'woocommerce_checkout_pay_endpoint', 'order-pay' ), 'order-pay' => get_option( 'woocommerce_checkout_pay_endpoint', 'order-pay' ),
'order-received' => get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' ), 'order-received' => get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' ),
// My account actions // My account actions.
'orders' => get_option( 'woocommerce_myaccount_orders_endpoint', 'orders' ),
'view-order' => get_option( 'woocommerce_myaccount_view_order_endpoint', 'view-order' ), 'view-order' => get_option( 'woocommerce_myaccount_view_order_endpoint', 'view-order' ),
'downloads' => get_option( 'woocommerce_myaccount_downloads_endpoint', 'downloads' ),
'edit-account' => get_option( 'woocommerce_myaccount_edit_account_endpoint', 'edit-account' ), 'edit-account' => get_option( 'woocommerce_myaccount_edit_account_endpoint', 'edit-account' ),
'edit-address' => get_option( 'woocommerce_myaccount_edit_address_endpoint', 'edit-address' ), 'edit-address' => get_option( 'woocommerce_myaccount_edit_address_endpoint', 'edit-address' ),
'payment-methods' => get_option( 'woocommerce_myaccount_payment_methods_endpoint', 'payment-methods' ),
'lost-password' => get_option( 'woocommerce_myaccount_lost_password_endpoint', 'lost-password' ), 'lost-password' => get_option( 'woocommerce_myaccount_lost_password_endpoint', 'lost-password' ),
'customer-logout' => get_option( 'woocommerce_logout_endpoint', 'customer-logout' ), 'customer-logout' => get_option( 'woocommerce_logout_endpoint', 'customer-logout' ),
'add-payment-method' => get_option( 'woocommerce_myaccount_add_payment_method_endpoint', 'add-payment-method' ), 'add-payment-method' => get_option( 'woocommerce_myaccount_add_payment_method_endpoint', 'add-payment-method' ),
@ -91,16 +94,29 @@ class WC_Query {
case 'order-received' : case 'order-received' :
$title = __( 'Order Received', 'woocommerce' ); $title = __( 'Order Received', 'woocommerce' );
break; break;
case 'orders' :
if ( ! empty( $wp->query_vars['orders'] ) ) {
$title = sprintf( __( 'Orders (page %d)', 'woocommerce' ), intval( $wp->query_vars['orders'] ) );
} else {
$title = __( 'Orders', 'woocommerce' );
}
break;
case 'view-order' : case 'view-order' :
$order = wc_get_order( $wp->query_vars['view-order'] ); $order = wc_get_order( $wp->query_vars['view-order'] );
$title = ( $order ) ? sprintf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ) : ''; $title = ( $order ) ? sprintf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ) : '';
break; break;
case 'downloads' :
$title = __( 'Downloads', 'woocommerce' );
break;
case 'edit-account' : case 'edit-account' :
$title = __( 'Edit Account Details', 'woocommerce' ); $title = __( 'Edit Account Details', 'woocommerce' );
break; break;
case 'edit-address' : case 'edit-address' :
$title = __( 'Edit Address', 'woocommerce' ); $title = __( 'Edit Address', 'woocommerce' );
break; break;
case 'payment-methods' :
$title = __( 'Payment Methods', 'woocommerce' );
break;
case 'add-payment-method' : case 'add-payment-method' :
$title = __( 'Add Payment Method', 'woocommerce' ); $title = __( 'Add Payment Method', 'woocommerce' );
break; break;
@ -108,9 +124,10 @@ class WC_Query {
$title = __( 'Lost Password', 'woocommerce' ); $title = __( 'Lost Password', 'woocommerce' );
break; break;
default : default :
$title = ''; $title = apply_filters( 'woocommerce_endpoint_' . $endpoint . '_title', '' );
break; break;
} }
return $title; return $title;
} }
@ -500,21 +517,22 @@ class WC_Query {
$min = isset( $_GET['min_price'] ) ? floatval( $_GET['min_price'] ) : 0; $min = isset( $_GET['min_price'] ) ? floatval( $_GET['min_price'] ) : 0;
$max = isset( $_GET['max_price'] ) ? floatval( $_GET['max_price'] ) : 9999999999; $max = isset( $_GET['max_price'] ) ? floatval( $_GET['max_price'] ) : 9999999999;
// If displaying prices in the shop including taxes, but prices don't include taxes.. /**
* Adjust if the store taxes are not displayed how they are stored.
* Max is left alone because the filter was already increased.
* Kicks in when prices excluding tax are displayed including tax.
*/
if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) { if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) {
$tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() ); $tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() );
$class_min = $min;
foreach ( $tax_classes as $tax_class ) { foreach ( $tax_classes as $tax_class ) {
$tax_rates = WC_Tax::get_rates( $tax_class ); if ( $tax_rates = WC_Tax::get_rates( $tax_class ) ) {
$class_min = $min - WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $min, $tax_rates ) ); $class_min = $min - WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $min, $tax_rates ) );
$class_max = $max - WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $max, $tax_rates ) );
if ( $class_min < $min ) {
$min = $class_min;
}
if ( $class_max > $max ) {
$max = $class_max;
} }
} }
$min = $class_min;
} }
return array( return array(

View File

@ -173,39 +173,19 @@ class WC_Session_Handler extends WC_Session {
if ( $this->_dirty && $this->has_session() ) { if ( $this->_dirty && $this->has_session() ) {
global $wpdb; global $wpdb;
$session_id = $wpdb->get_var( $wpdb->prepare( "SELECT session_id FROM $this->_table WHERE session_key = %s;", $this->_customer_id ) ); $wpdb->replace(
$this->_table,
if ( $session_id ) { array(
$wpdb->update( 'session_key' => $this->_customer_id,
$this->_table, 'session_value' => maybe_serialize( $this->_data ),
array( 'session_expiry' => $this->_session_expiration
'session_key' => $this->_customer_id, ),
'session_value' => maybe_serialize( $this->_data ), array(
'session_expiry' => $this->_session_expiration '%s',
), '%s',
array( 'session_id' => $session_id ), '%d'
array( )
'%s', );
'%s',
'%d'
),
array( '%d' )
);
} else {
$wpdb->insert(
$this->_table,
array(
'session_key' => $this->_customer_id,
'session_value' => maybe_serialize( $this->_data ),
'session_expiry' => $this->_session_expiration
),
array(
'%s',
'%s',
'%d'
)
);
}
// Set cache // Set cache
wp_cache_set( $this->get_cache_prefix() . $this->_customer_id, $this->_data, WC_SESSION_CACHE_GROUP, $this->_session_expiration - time() ); wp_cache_set( $this->get_cache_prefix() . $this->_customer_id, $this->_data, WC_SESSION_CACHE_GROUP, $this->_session_expiration - time() );

View File

@ -231,7 +231,8 @@ class WC_Shipping_Zone implements WC_Data {
// as classes. If the "class" is an instance, just use it. If not, // as classes. If the "class" is an instance, just use it. If not,
// create an instance. // create an instance.
if ( is_object( $class_name ) ) { if ( is_object( $class_name ) ) {
$methods[ $raw_method->instance_id ] = $class_name; $class_name_of_instance = get_class( $class_name );
$methods[ $raw_method->instance_id ] = new $class_name_of_instance( $raw_method->instance_id );
} else { } else {
// If the class is not an object, it should be a string. It's better // If the class is not an object, it should be a string. It's better
// to double check, to be sure (a class must be a string, anything) // to double check, to be sure (a class must be a string, anything)

View File

@ -93,6 +93,9 @@ class WC_Shipping_Zones {
if ( in_array( $raw_shipping_method->method_id, array_keys( $allowed_classes ) ) ) { if ( in_array( $raw_shipping_method->method_id, array_keys( $allowed_classes ) ) ) {
$class_name = $allowed_classes[ $raw_shipping_method->method_id ]; $class_name = $allowed_classes[ $raw_shipping_method->method_id ];
if ( is_object( $class_name ) ) {
$class_name = get_class( $class_name );
}
return new $class_name( $raw_shipping_method->instance_id ); return new $class_name( $raw_shipping_method->instance_id );
} }
return false; return false;

View File

@ -1299,7 +1299,7 @@ class WC_CLI_Product extends WC_CLI_Command {
// Update parent if grouped so price sorting works and stays in sync with the cheapest child // Update parent if grouped so price sorting works and stays in sync with the cheapest child
$_product = wc_get_product( $product_id ); $_product = wc_get_product( $product_id );
if ( $_product->post->post_parent > 0 || $product_type == 'grouped' ) { if ( $_product && $_product->post->post_parent > 0 || $product_type == 'grouped' ) {
$clear_parent_ids = array(); $clear_parent_ids = array();
@ -1449,14 +1449,14 @@ class WC_CLI_Product extends WC_CLI_Command {
} }
// Product categories // Product categories
if ( isset( $data['categories'] ) && is_array( $data['categories'] ) ) { if ( isset( $data['categories'] ) ) {
$term_ids = array_unique( array_map( 'intval', $data['categories'] ) ); $term_ids = array_unique( array_map( 'intval', (array) $data['categories'] ) );
wp_set_object_terms( $product_id, $term_ids, 'product_cat' ); wp_set_object_terms( $product_id, $term_ids, 'product_cat' );
} }
// Product tags // Product tags
if ( isset( $data['tags'] ) && is_array( $data['tags'] ) ) { if ( isset( $data['tags'] ) ) {
$term_ids = array_unique( array_map( 'intval', $data['tags'] ) ); $term_ids = array_unique( array_map( 'intval', (array) $data['tags'] ) );
wp_set_object_terms( $product_id, $term_ids, 'product_tag' ); wp_set_object_terms( $product_id, $term_ids, 'product_tag' );
} }

View File

@ -216,7 +216,7 @@ class WC_Email extends WC_Settings_API {
$this->replace['site-title'] = $this->get_blogname(); $this->replace['site-title'] = $this->get_blogname();
// For multipart messages // For multipart messages
add_filter( 'phpmailer_init', array( $this, 'handle_multipart' ) ); add_action( 'phpmailer_init', array( $this, 'handle_multipart' ) );
} }
/** /**
@ -704,7 +704,8 @@ class WC_Email extends WC_Settings_API {
// Do admin actions. // Do admin actions.
$this->admin_actions(); $this->admin_actions();
?> ?>
<h3><?php echo esc_html( $this->get_title() ); ?></h3> <h2><?php echo esc_html( $this->get_title() ); ?> <?php wc_back_link( __( 'Return to Emails', 'woocommerce' ), admin_url( 'admin.php?page=wc-settings&tab=email' ) ); ?></h2>
<?php echo wpautop( wp_kses_post( $this->get_description() ) ); ?> <?php echo wpautop( wp_kses_post( $this->get_description() ) ); ?>
<?php <?php

View File

@ -35,7 +35,6 @@ class WC_Shortcode_My_Account {
} }
if ( ! is_user_logged_in() ) { if ( ! is_user_logged_in() ) {
$message = apply_filters( 'woocommerce_my_account_message', '' ); $message = apply_filters( 'woocommerce_my_account_message', '' );
if ( ! empty( $message ) ) { if ( ! empty( $message ) ) {
@ -43,66 +42,53 @@ class WC_Shortcode_My_Account {
} }
if ( isset( $wp->query_vars['lost-password'] ) ) { if ( isset( $wp->query_vars['lost-password'] ) ) {
self::lost_password(); self::lost_password();
} else { } else {
wc_get_template( 'myaccount/form-login.php' ); wc_get_template( 'myaccount/form-login.php' );
}
} else {
// See if showing an account endpoint
foreach ( $wp->query_vars as $key => $value ) {
// Ignore pagename param.
if ( 'pagename' === $key ) {
continue;
}
if ( has_action( 'woocommerce_account_' . $key . '_endpoint' ) ) {
do_action( 'woocommerce_account_' . $key . '_endpoint', $value );
return;
}
} }
} else { // No endpoint? Show main account page.
self::my_account( $atts );
if ( ! empty( $wp->query_vars['view-order'] ) ) {
self::view_order( absint( $wp->query_vars['view-order'] ) );
} elseif ( isset( $wp->query_vars['edit-account'] ) ) {
self::edit_account();
} elseif ( isset( $wp->query_vars['edit-address'] ) ) {
self::edit_address( wc_edit_address_i18n( sanitize_title( $wp->query_vars['edit-address'] ), true ) );
} elseif ( isset( $wp->query_vars['add-payment-method'] ) ) {
self::add_payment_method();
} else {
self::my_account( $atts );
}
} }
} }
/** /**
* My account page. * My account page.
* *
* @param array $atts * @param array $atts
*/ */
private static function my_account( $atts ) { private static function my_account( $atts ) {
extract( shortcode_atts( array( extract( shortcode_atts( array(
'order_count' => 15 'order_count' => 15 // @deprecated 2.6.0. Keep for backward compatibility.
), $atts ) ); ), $atts ) );
wc_get_template( 'myaccount/my-account.php', array( wc_get_template( 'myaccount/my-account.php', array(
'current_user' => get_user_by( 'id', get_current_user_id() ), 'current_user' => get_user_by( 'id', get_current_user_id() ),
'order_count' => 'all' == $order_count ? -1 : $order_count 'order_count' => 'all' == $order_count ? -1 : $order_count
) ); ) );
} }
/** /**
* View order page. * View order page.
* *
* @param int $order_id * @param int $order_id
*/ */
private static function view_order( $order_id ) { public static function view_order( $order_id ) {
$user_id = get_current_user_id(); $user_id = get_current_user_id();
$order = wc_get_order( $order_id ); $order = wc_get_order( $order_id );
if ( ! current_user_can( 'view_order', $order_id ) ) { if ( ! current_user_can( 'view_order', $order_id ) ) {
echo '<div class="woocommerce-error">' . __( 'Invalid order.', 'woocommerce' ) . ' <a href="' . wc_get_page_permalink( 'myaccount' ).'" class="wc-forward">'. __( 'My Account', 'woocommerce' ) .'</a>' . '</div>'; echo '<div class="woocommerce-error">' . __( 'Invalid order.', 'woocommerce' ) . ' <a href="' . wc_get_page_permalink( 'myaccount' ).'" class="wc-forward">'. __( 'My Account', 'woocommerce' ) .'</a>' . '</div>';
@ -123,17 +109,16 @@ class WC_Shortcode_My_Account {
/** /**
* Edit account details page. * Edit account details page.
*/ */
private static function edit_account() { public static function edit_account() {
wc_get_template( 'myaccount/form-edit-account.php', array( 'user' => get_user_by( 'id', get_current_user_id() ) ) ); wc_get_template( 'myaccount/form-edit-account.php', array( 'user' => get_user_by( 'id', get_current_user_id() ) ) );
} }
/** /**
* Edit address page. * Edit address page.
* *
* @access public
* @param string $load_address * @param string $load_address
*/ */
private static function edit_address( $load_address = 'billing' ) { public static function edit_address( $load_address = 'billing' ) {
$current_user = wp_get_current_user(); $current_user = wp_get_current_user();
$load_address = sanitize_key( $load_address ); $load_address = sanitize_key( $load_address );
@ -187,9 +172,9 @@ class WC_Shortcode_My_Account {
$user = self::check_password_reset_key( $_GET['key'], $_GET['login'] ); $user = self::check_password_reset_key( $_GET['key'], $_GET['login'] );
// reset key / login is correct, display reset password form with hidden key / login values // reset key / login is correct, display reset password form with hidden key / login values
if( is_object( $user ) ) { if ( is_object( $user ) ) {
$args['form'] = 'reset_password'; $args['form'] = 'reset_password';
$args['key'] = esc_attr( $_GET['key'] ); $args['key'] = esc_attr( $_GET['key'] );
$args['login'] = esc_attr( $_GET['login'] ); $args['login'] = esc_attr( $_GET['login'] );
} }
} elseif ( isset( $_GET['reset'] ) ) { } elseif ( isset( $_GET['reset'] ) ) {
@ -204,7 +189,6 @@ class WC_Shortcode_My_Account {
* *
* Based on retrieve_password() in core wp-login.php. * Based on retrieve_password() in core wp-login.php.
* *
* @access public
* @uses $wpdb WordPress Database object * @uses $wpdb WordPress Database object
* @return bool True: when finish. False: on error * @return bool True: when finish. False: on error
*/ */
@ -340,7 +324,7 @@ class WC_Shortcode_My_Account {
/** /**
* Show the add payment method page. * Show the add payment method page.
*/ */
private static function add_payment_method() { public static function add_payment_method() {
if ( ! is_user_logged_in() ) { if ( ! is_user_logged_in() ) {

View File

@ -0,0 +1,210 @@
<?php
/**
* WooCommerce Account Functions
*
* Functions for account specific things.
*
* @author WooThemes
* @category Core
* @package WooCommerce/Functions
* @version 2.6.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Returns the url to the lost password endpoint url.
*
* @access public
* @param string $default_url
* @return string
*/
function wc_lostpassword_url( $default_url = '' ) {
$wc_password_reset_url = wc_get_page_permalink( 'myaccount' );
if ( false !== $wc_password_reset_url ) {
return wc_get_endpoint_url( 'lost-password', '', $wc_password_reset_url );
} else {
return $default_url;
}
}
add_filter( 'lostpassword_url', 'wc_lostpassword_url', 10, 1 );
/**
* Get the link to the edit account details page.
*
* @return string
*/
function wc_customer_edit_account_url() {
$edit_account_url = wc_get_endpoint_url( 'edit-account', '', wc_get_page_permalink( 'myaccount' ) );
return apply_filters( 'woocommerce_customer_edit_account_url', $edit_account_url );
}
/**
* Get the edit address slug translation.
*
* @param string $id Address ID.
* @param bool $flip Flip the array to make it possible to retrieve the values from both sides.
*
* @return string Address slug i18n.
*/
function wc_edit_address_i18n( $id, $flip = false ) {
$slugs = apply_filters( 'woocommerce_edit_address_slugs', array(
'billing' => sanitize_title( _x( 'billing', 'edit-address-slug', 'woocommerce' ) ),
'shipping' => sanitize_title( _x( 'shipping', 'edit-address-slug', 'woocommerce' ) )
) );
if ( $flip ) {
$slugs = array_flip( $slugs );
}
if ( ! isset( $slugs[ $id ] ) ) {
return $id;
}
return $slugs[ $id ];
}
/**
* Get My Account menu items.
*
* @since 2.6.0
* @return array
*/
function wc_get_account_menu_items() {
return apply_filters( 'woocommerce_account_menu_items', array(
'dashboard' => __( 'Dashboard', 'woocommerce' ),
'orders' => __( 'Orders', 'woocommerce' ),
'downloads' => __( 'Downloads', 'woocommerce' ),
'edit-address' => __( 'Addresses', 'woocommerce' ),
'payment-methods' => __( 'Payment Methods', 'woocommerce' ),
'edit-account' => __( 'Account Details', 'woocommerce' ),
'customer-logout' => __( 'Logout', 'woocommerce' ),
) );
}
/**
* Get account menu item classes.
*
* @since 2.6.0
* @param string $endpoint
* @return string
*/
function wc_get_account_menu_item_classes( $endpoint ) {
global $wp;
$classes = array(
'my-account-menu-item-' . $endpoint,
);
// Set current item class.
$current = isset( $wp->query_vars[ $endpoint ] );
if ( 'dashboard' === $endpoint && ( isset( $wp->query_vars['page'] ) || empty( $wp->query_vars ) ) ) {
$current = true; // Dashboard is not an endpoint, so needs a custom check.
}
if ( $current ) {
$classes[] = 'current-item';
}
$classes = apply_filters( 'woocommerce_account_menu_item_classes', $classes, $endpoint );
return implode( ' ', array_map( 'sanitize_html_class', $classes ) );
}
/**
* Get account endpoint URL.
*
* @since 2.6.0
* @param string $endpoint
* @return string
*/
function wc_get_account_endpoint_url( $endpoint ) {
if ( 'dashboard' === $endpoint ) {
return wc_get_page_permalink( 'myaccount' );
}
return wc_get_endpoint_url( $endpoint );
}
/**
* Get My Account > Orders columns.
*
* @since 2.6.0
* @return array
*/
function wc_get_account_orders_columns() {
$columns = apply_filters( 'woocommerce_account_orders_columns', array(
'order-number' => __( 'Order', 'woocommerce' ),
'order-date' => __( 'Date', 'woocommerce' ),
'order-status' => __( 'Status', 'woocommerce' ),
'order-total' => __( 'Total', 'woocommerce' ),
'order-actions' => '&nbsp;',
) );
// Deprecated filter since 2.6.0.
return apply_filters( 'woocommerce_my_account_my_orders_columns', $columns );
}
/**
* Get My Account > Orders query args.
*
* @since 2.6.0
* @param int $current_page
* @return array
*/
function wc_get_account_orders_query_args( $current_page = 1 ) {
$args = array(
'numberposts' => 15,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(),
'post_type' => wc_get_order_types( 'view-orders' ),
'post_status' => array_keys( wc_get_order_statuses() ),
);
// @deprecated 2.6.0.
$args = apply_filters( 'woocommerce_my_account_my_orders_query', $args );
// Remove deprecated option.
$args['posts_per_page'] = $args['numberposts'];
unset( $args['numberposts'] );
if ( 1 < $current_page ) {
$args['paged'] = absint( $current_page );
}
return apply_filters( 'woocommerce_account_orders_query', $args );
}
/**
* Get My Account > Downloads columns.
*
* @since 2.6.0
* @return array
*/
function wc_get_account_downloads_columns() {
return apply_filters( 'woocommerce_account_downloads_columns', array(
'download-file' => __( 'File', 'woocommerce' ),
'download-remaining' => __( 'Remaining', 'woocommerce' ),
'download-expires' => __( 'Expires', 'woocommerce' ),
'download-actions' => '&nbsp;',
) );
}
/**
* Get My Account > Payment methods columns.
*
* @since 2.6.0
* @return array
*/
function wc_get_account_payment_methods_columns() {
return apply_filters( 'woocommerce_account_payment_methods_columns', array(
'method' => __( 'Method', 'woocommerce' ),
'expires' => __( 'Expires', 'woocommerce' ),
'actions' => '&nbsp;',
) );
}

View File

@ -23,6 +23,7 @@ include( 'wc-formatting-functions.php' );
include( 'wc-order-functions.php' ); include( 'wc-order-functions.php' );
include( 'wc-page-functions.php' ); include( 'wc-page-functions.php' );
include( 'wc-product-functions.php' ); include( 'wc-product-functions.php' );
include( 'wc-account-functions.php' );
include( 'wc-term-functions.php' ); include( 'wc-term-functions.php' );
include( 'wc-attribute-functions.php' ); include( 'wc-attribute-functions.php' );
@ -934,3 +935,13 @@ function woocommerce_register_shipping_method( $shipping_method ) {
function wc_get_shipping_zone( $package ) { function wc_get_shipping_zone( $package ) {
return WC_Shipping_Zones::get_zone_matching_package( $package ); return WC_Shipping_Zones::get_zone_matching_package( $package );
} }
/**
* Outputs a "back" link so admin screens can easily jump back a page.
*
* @param string $label Title of the page to return to.
* @param string $url URL of the page to return to.
*/
function wc_back_link( $label, $url ) {
echo '<small class="wc-admin-breadcrumb"><a href="' . esc_url( $url ) . '" title="' . esc_attr( $label ) . '">&#x21a9;</a></small>';
}

View File

@ -669,7 +669,11 @@ function wc_strtolower( $string ) {
*/ */
function wc_trim_string( $string, $chars = 200, $suffix = '...' ) { function wc_trim_string( $string, $chars = 200, $suffix = '...' ) {
if ( strlen( $string ) > $chars ) { if ( strlen( $string ) > $chars ) {
$string = substr( $string, 0, ( $chars - strlen( $suffix ) ) ) . $suffix; if ( function_exists( 'mb_substr' ) ) {
$string = mb_substr( $string, 0, ( $chars - mb_strlen( $suffix ) ) ) . $suffix;
} else {
$string = substr( $string, 0, ( $chars - strlen( $suffix ) ) ) . $suffix;
}
} }
return $string; return $string;
} }

View File

@ -120,7 +120,7 @@ function wc_print_notices() {
foreach ( $notice_types as $notice_type ) { foreach ( $notice_types as $notice_type ) {
if ( wc_notice_count( $notice_type ) > 0 ) { if ( wc_notice_count( $notice_type ) > 0 ) {
wc_get_template( "notices/{$notice_type}.php", array( wc_get_template( "notices/{$notice_type}.php", array(
'messages' => $all_notices[$notice_type] 'messages' => array_filter( $all_notices[ $notice_type ] )
) ); ) );
} }
} }

View File

@ -4,10 +4,10 @@
* *
* Functions related to pages and menus. * Functions related to pages and menus.
* *
* @author WooThemes * @author WooThemes
* @category Core * @category Core
* @package WooCommerce/Functions * @package WooCommerce/Functions
* @version 2.1.0 * @version 2.6.0
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
@ -85,8 +85,9 @@ function wc_get_page_permalink( $page ) {
* @return string * @return string
*/ */
function wc_get_endpoint_url( $endpoint, $value = '', $permalink = '' ) { function wc_get_endpoint_url( $endpoint, $value = '', $permalink = '' ) {
if ( ! $permalink ) if ( ! $permalink ) {
$permalink = get_permalink(); $permalink = get_permalink();
}
// Map endpoint to options // Map endpoint to options
$endpoint = ! empty( WC()->query->query_vars[ $endpoint ] ) ? WC()->query->query_vars[ $endpoint ] : $endpoint; $endpoint = ! empty( WC()->query->query_vars[ $endpoint ] ) ? WC()->query->query_vars[ $endpoint ] : $endpoint;
@ -107,60 +108,6 @@ function wc_get_endpoint_url( $endpoint, $value = '', $permalink = '' ) {
return apply_filters( 'woocommerce_get_endpoint_url', $url, $endpoint, $value, $permalink ); return apply_filters( 'woocommerce_get_endpoint_url', $url, $endpoint, $value, $permalink );
} }
/**
* Get the edit address slug translation.
*
* @param string $id Address ID.
* @param bool $flip Flip the array to make it possible to retrieve the values from both sides.
*
* @return string Address slug i18n.
*/
function wc_edit_address_i18n( $id, $flip = false ) {
$slugs = apply_filters( 'woocommerce_edit_address_slugs', array(
'billing' => sanitize_title( _x( 'billing', 'edit-address-slug', 'woocommerce' ) ),
'shipping' => sanitize_title( _x( 'shipping', 'edit-address-slug', 'woocommerce' ) )
) );
if ( $flip ) {
$slugs = array_flip( $slugs );
}
if ( ! isset( $slugs[ $id ] ) ) {
return $id;
}
return $slugs[ $id ];
}
/**
* Returns the url to the lost password endpoint url.
*
* @access public
* @param string $default_url
* @return string
*/
function wc_lostpassword_url( $default_url = '' ) {
$wc_password_reset_url = wc_get_page_permalink( 'myaccount' );
if ( false !== $wc_password_reset_url ) {
return wc_get_endpoint_url( 'lost-password', '', $wc_password_reset_url );
} else {
return $default_url;
}
}
add_filter( 'lostpassword_url', 'wc_lostpassword_url', 10, 1 );
/**
* Get the link to the edit account details page.
*
* @return string
*/
function wc_customer_edit_account_url() {
$edit_account_url = wc_get_endpoint_url( 'edit-account', '', wc_get_page_permalink( 'myaccount' ) );
return apply_filters( 'woocommerce_customer_edit_account_url', $edit_account_url );
}
/** /**
* Hide menu items conditionally. * Hide menu items conditionally.
* *

View File

@ -51,7 +51,9 @@ function wc_update_product_stock( $product_id, $new_stock_level ) {
*/ */
function wc_update_product_stock_status( $product_id, $status ) { function wc_update_product_stock_status( $product_id, $status ) {
$product = wc_get_product( $product_id ); $product = wc_get_product( $product_id );
$product->set_stock_status( $status ); if ( $product ) {
$product->set_stock_status( $status );
}
} }
/** /**
@ -638,10 +640,12 @@ function wc_get_product_variation_attributes( $variation_id ) {
// Compare to parent variable product attributes and ensure they match // Compare to parent variable product attributes and ensure they match
foreach ( $parent_attributes as $attribute_name => $options ) { foreach ( $parent_attributes as $attribute_name => $options ) {
$attribute = 'attribute_' . sanitize_title( $attribute_name ); if ( ! empty( $options['is_variation'] ) ) {
$found_parent_attributes[] = $attribute; $attribute = 'attribute_' . sanitize_title( $attribute_name );
if ( ! empty( $options['is_variation'] ) && ! array_key_exists( $attribute, $variation_attributes ) ) { $found_parent_attributes[] = $attribute;
$variation_attributes[ $attribute ] = ''; // Add it - 'any' will be asumed if ( ! array_key_exists( $attribute, $variation_attributes ) ) {
$variation_attributes[ $attribute ] = ''; // Add it - 'any' will be asumed
}
} }
} }

View File

@ -906,7 +906,7 @@ if ( ! function_exists( 'woocommerce_template_single_add_to_cart' ) ) {
*/ */
function woocommerce_template_single_add_to_cart() { function woocommerce_template_single_add_to_cart() {
global $product; global $product;
do_action( 'woocommerce_' . $product->product_type . '_add_to_cart' ); do_action( 'woocommerce_' . $product->product_type . '_add_to_cart' );
} }
} }
if ( ! function_exists( 'woocommerce_simple_add_to_cart' ) ) { if ( ! function_exists( 'woocommerce_simple_add_to_cart' ) ) {
@ -997,11 +997,13 @@ if ( ! function_exists( 'woocommerce_quantity_input' ) ) {
} }
$defaults = array( $defaults = array(
'input_name' => 'quantity', 'input_name' => 'quantity',
'input_value' => '1', 'input_value' => '1',
'max_value' => apply_filters( 'woocommerce_quantity_input_max', '', $product ), 'max_value' => apply_filters( 'woocommerce_quantity_input_max', '', $product ),
'min_value' => apply_filters( 'woocommerce_quantity_input_min', '', $product ), 'min_value' => apply_filters( 'woocommerce_quantity_input_min', '', $product ),
'step' => apply_filters( 'woocommerce_quantity_input_step', '1', $product ) 'step' => apply_filters( 'woocommerce_quantity_input_step', '1', $product ),
'pattern' => apply_filters( 'woocommerce_quantity_input_pattern', has_filter( 'woocommerce_stock_amount', 'intval' ) ? '[0-9]*' : '' ),
'inputmode' => apply_filters( 'woocommerce_quantity_input_inputmode', has_filter( 'woocommerce_stock_amount', 'intval' ) ? 'numeric' : '' ),
); );
$args = apply_filters( 'woocommerce_quantity_input_args', wp_parse_args( $args, $defaults ), $product ); $args = apply_filters( 'woocommerce_quantity_input_args', wp_parse_args( $args, $defaults ), $product );
@ -1474,8 +1476,8 @@ if ( ! function_exists( 'woocommerce_products_will_display' ) ) {
$products_will_display = false; $products_will_display = false;
} else { } else {
// If we get here, the parents were empty so we're forced to check children // If we get here, the parents were empty so we're forced to check children
foreach ( $has_children as $term ) { foreach ( $has_children as $term_id ) {
$children = get_term_children( $term, $term->taxonomy ); $children = get_term_children( $term_id, $term->taxonomy );
if ( sizeof( get_objects_in_term( $children, $term->taxonomy ) ) > 0 ) { if ( sizeof( get_objects_in_term( $children, $term->taxonomy ) ) > 0 ) {
$products_will_display = false; $products_will_display = false;
@ -2023,5 +2025,84 @@ if ( ! function_exists( 'wc_dropdown_variation_attribute_options' ) ) {
echo apply_filters( 'woocommerce_dropdown_variation_attribute_options_html', $html, $args ); echo apply_filters( 'woocommerce_dropdown_variation_attribute_options_html', $html, $args );
} }
}
if ( ! function_exists( 'woocommerce_account_orders' ) ) {
/**
* My Account > Orders template.
*
* @param int $current_page Current page number.
*/
function woocommerce_account_orders( $current_page ) {
$current_page = empty( $current_page ) ? 1 : $current_page;
wc_get_template( 'myaccount/orders.php', array( 'current_page' => absint( $current_page ) ) );
}
}
if ( ! function_exists( 'woocommerce_account_view_order' ) ) {
/**
* My Account > View order template.
*
* @param int $order_id Order ID.
*/
function woocommerce_account_view_order( $order_id ) {
WC_Shortcode_My_Account::view_order( absint( $order_id ) );
}
}
if ( ! function_exists( 'woocommerce_account_downloads' ) ) {
/**
* My Account > Downloads template.
*/
function woocommerce_account_downloads() {
wc_get_template( 'myaccount/downloads.php' );
}
}
if ( ! function_exists( 'woocommerce_account_edit_address' ) ) {
/**
* My Account > Edit address template.
*
* @param string $type Address type.
*/
function woocommerce_account_edit_address( $type ) {
$type = wc_edit_address_i18n( sanitize_title( $type ), true );
WC_Shortcode_My_Account::edit_address( $type );
}
}
if ( ! function_exists( 'woocommerce_account_payment_methods' ) ) {
/**
* My Account > Downloads template.
*/
function woocommerce_account_payment_methods() {
wc_get_template( 'myaccount/payment-methods.php' );
}
}
if ( ! function_exists( 'woocommerce_account_add_payment_method' ) ) {
/**
* My Account > Add payment method template.
*/
function woocommerce_account_add_payment_method() {
WC_Shortcode_My_Account::add_payment_method();
}
}
if ( ! function_exists( 'woocommerce_account_edit_account' ) ) {
/**
* My Account > Edit account template.
*/
function woocommerce_account_edit_account() {
WC_Shortcode_My_Account::edit_account();
}
} }

View File

@ -239,3 +239,14 @@ add_action( 'woocommerce_auth_page_footer', 'woocommerce_output_auth_footer', 10
* Disable Jetpack comments. * Disable Jetpack comments.
*/ */
add_filter( 'jetpack_comment_form_enabled_for_product', '__return_false' ); add_filter( 'jetpack_comment_form_enabled_for_product', '__return_false' );
/**
* My Account.
*/
add_action( 'woocommerce_account_orders_endpoint', 'woocommerce_account_orders' );
add_action( 'woocommerce_account_view-order_endpoint', 'woocommerce_account_view_order' );
add_action( 'woocommerce_account_downloads_endpoint', 'woocommerce_account_downloads' );
add_action( 'woocommerce_account_edit-address_endpoint', 'woocommerce_account_edit_address' );
add_action( 'woocommerce_account_payment-methods_endpoint', 'woocommerce_account_payment_methods' );
add_action( 'woocommerce_account_add-payment-method_endpoint', 'woocommerce_account_add_payment_method' );
add_action( 'woocommerce_account_edit-account_endpoint', 'woocommerce_account_edit_account' );

View File

@ -404,8 +404,6 @@ function wc_get_customer_available_downloads( $customer_id ) {
", $customer_id, date( 'Y-m-d', current_time( 'timestamp' ) ) ) ), $customer_id ); ", $customer_id, date( 'Y-m-d', current_time( 'timestamp' ) ) ) ), $customer_id );
if ( $results ) { if ( $results ) {
$looped_downloads = array();
foreach ( $results as $result ) { foreach ( $results as $result ) {
if ( ! $order || $order->id != $result->order_id ) { if ( ! $order || $order->id != $result->order_id ) {
// new order // new order
@ -438,13 +436,6 @@ function wc_get_customer_available_downloads( $customer_id ) {
$download_file = $_product->get_file( $result->download_id ); $download_file = $_product->get_file( $result->download_id );
// Check if the file has been already added to the downloads list
if ( in_array( $download_file, $looped_downloads ) ) {
continue;
}
array_push( $looped_downloads, $download_file );
// Download name will be 'Product Name' for products with a single downloadable file, and 'Product Name - File X' for products with multiple files // Download name will be 'Product Name' for products with a single downloadable file, and 'Product Name - File X' for products with multiple files
$download_name = apply_filters( $download_name = apply_filters(
'woocommerce_downloadable_product_name', 'woocommerce_downloadable_product_name',
@ -585,9 +576,9 @@ add_action( 'template_redirect', 'wc_disable_author_archives_for_customers' );
/** /**
* Hooks into the `profile_update` hook to set the user last updated timestamp. * Hooks into the `profile_update` hook to set the user last updated timestamp.
* *
* @since 2.6 * @since 2.6.0
* @param int $user_id The user that was updated * @param int $user_id The user that was updated.
* @param array $old The profile fields pre-change * @param array $old The profile fields pre-change.
*/ */
function wc_update_profile_last_update_time( $user_id, $old ) { function wc_update_profile_last_update_time( $user_id, $old ) {
wc_set_user_last_update_time( $user_id ); wc_set_user_last_update_time( $user_id );
@ -598,11 +589,11 @@ add_action( 'profile_update', 'wc_update_profile_last_update_time', 10, 2 );
/** /**
* Hooks into the update user meta function to set the user last updated timestamp. * Hooks into the update user meta function to set the user last updated timestamp.
* *
* @since 2.6 * @since 2.6.0
* @param int $meta_id ID of the meta object that was changed * @param int $meta_id ID of the meta object that was changed.
* @param int $user_id The user that was updated * @param int $user_id The user that was updated.
* @param string $meta_key Name of the meta key that was changed * @param string $meta_key Name of the meta key that was changed.
* @param string $_meta_value Value of the meta that was changed * @param string $_meta_value Value of the meta that was changed.
*/ */
function wc_meta_update_last_update_time( $meta_id, $user_id, $meta_key, $_meta_value ) { function wc_meta_update_last_update_time( $meta_id, $user_id, $meta_key, $_meta_value ) {
$keys_to_track = apply_filters( 'woocommerce_user_last_update_fields', array( 'first_name', 'last_name' ) ); $keys_to_track = apply_filters( 'woocommerce_user_last_update_fields', array( 'first_name', 'last_name' ) );
@ -627,9 +618,20 @@ add_action( 'update_user_meta', 'wc_meta_update_last_update_time', 10, 4 );
/** /**
* Sets a user's "last update" time to the current timestamp. * Sets a user's "last update" time to the current timestamp.
* *
* @since 2.6 * @since 2.6.0
* @param int $user_id The user to set a timestamp for * @param int $user_id The user to set a timestamp for.
*/ */
function wc_set_user_last_update_time( $user_id ) { function wc_set_user_last_update_time( $user_id ) {
update_user_meta( $user_id, 'last_update', time() ); update_user_meta( $user_id, 'last_update', time() );
} }
/**
* Get customer saved payment methods list.
*
* @since 2.6.0
* @param int $customer_id
* @return array
*/
function wc_get_customer_saved_methods_list( $customer_id ) {
return apply_filters( 'woocommerce_saved_payment_methods_list', array(), $customer_id );
}

View File

@ -118,27 +118,28 @@ class WC_Widget_Price_Filter extends WC_Widget {
$this->widget_start( $args, $instance ); $this->widget_start( $args, $instance );
if ( '' == get_option( 'permalink_structure' ) ) { if ( '' === get_option( 'permalink_structure' ) ) {
$form_action = remove_query_arg( array( 'page', 'paged' ), add_query_arg( $wp->query_string, '', home_url( $wp->request ) ) ); $form_action = remove_query_arg( array( 'page', 'paged' ), add_query_arg( $wp->query_string, '', home_url( $wp->request ) ) );
} else { } else {
$form_action = preg_replace( '%\/page/[0-9]+%', '', home_url( trailingslashit( $wp->request ) ) ); $form_action = preg_replace( '%\/page/[0-9]+%', '', home_url( trailingslashit( $wp->request ) ) );
} }
// Adjust min and max if the store taxes are not displayed how they are stored /**
* Adjust max if the store taxes are not displayed how they are stored.
* Min is left alone because the product may not be taxable.
* Kicks in when prices excluding tax are displayed including tax.
*/
if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) { if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) {
$tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() ); $tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() );
$class_max = $max;
foreach ( $tax_classes as $tax_class ) { foreach ( $tax_classes as $tax_class ) {
$tax_rates = WC_Tax::get_rates( $tax_class ); if ( $tax_rates = WC_Tax::get_rates( $tax_class ) ) {
$class_min = $min + WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $min, $tax_rates ) ); $class_max = $max + WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $max, $tax_rates ) );
$class_max = $max + WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $max, $tax_rates ) );
if ( $class_min < $min ) {
$min = $class_min;
}
if ( $class_max > $max ) {
$max = $class_max;
} }
} }
$max = $class_max;
} }
echo '<form method="get" action="' . esc_url( $form_action ) . '"> echo '<form method="get" action="' . esc_url( $form_action ) . '">

View File

@ -149,6 +149,7 @@ class WC_Widget_Rating_Filter extends WC_Widget {
ob_start(); ob_start();
$found = false;
$min_rating = isset( $_GET['min_rating'] ) ? absint( $_GET['min_rating'] ) : ''; $min_rating = isset( $_GET['min_rating'] ) ? absint( $_GET['min_rating'] ) : '';
$this->widget_start( $args, $instance ); $this->widget_start( $args, $instance );

View File

@ -1,5 +1,5 @@
=== WooCommerce === === WooCommerce ===
Contributors: automattic, mikejolley, jameskoster, claudiosanches, royho, woothemes Contributors: automattic, mikejolley, jameskoster, claudiosanches, jshreve, coderkevin, woothemes
Tags: ecommerce, e-commerce, store, sales, sell, shop, cart, checkout, downloadable, downloads, paypal, storefront Tags: ecommerce, e-commerce, store, sales, sell, shop, cart, checkout, downloadable, downloads, paypal, storefront
Requires at least: 4.1 Requires at least: 4.1
Tested up to: 4.4 Tested up to: 4.4
@ -162,6 +162,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
* Dev - Made coupon optional in cart has_discount() method. * Dev - Made coupon optional in cart has_discount() method.
* Tweak - Removed tag/cat classes from loops since WP does the same. * Tweak - Removed tag/cat classes from loops since WP does the same.
* Tweak - Added hash check for orders so that if the cart changes before payment, a new order is made. * Tweak - Added hash check for orders so that if the cart changes before payment, a new order is made.
* Feature - Cart operations now use ajax (item quantities/remove, coupon apply/remove, shipping options)
[See changelog for all versions](https://raw.githubusercontent.com/woothemes/woocommerce/master/CHANGELOG.txt). [See changelog for all versions](https://raw.githubusercontent.com/woothemes/woocommerce/master/CHANGELOG.txt).

View File

@ -21,5 +21,5 @@ if ( ! defined( 'ABSPATH' ) ) {
} }
?> ?>
<div class="quantity"> <div class="quantity">
<input type="number" step="<?php echo esc_attr( $step ); ?>" min="<?php echo esc_attr( $min_value ); ?>" max="<?php echo esc_attr( $max_value ); ?>" name="<?php echo esc_attr( $input_name ); ?>" value="<?php echo esc_attr( $input_value ); ?>" title="<?php echo esc_attr_x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ) ?>" class="input-text qty text" size="4" /> <input type="number" step="<?php echo esc_attr( $step ); ?>" min="<?php echo esc_attr( $min_value ); ?>" max="<?php echo esc_attr( $max_value ); ?>" name="<?php echo esc_attr( $input_name ); ?>" value="<?php echo esc_attr( $input_value ); ?>" title="<?php echo esc_attr_x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ) ?>" class="input-text qty text" size="4" pattern="<?php echo esc_attr( $pattern ); ?>" inputmode="<?php echo esc_attr( $inputmode ); ?>" />
</div> </div>

View File

@ -35,12 +35,10 @@ if ( ! woocommerce_products_will_display() )
$first = ( $per_page * $paged ) - $per_page + 1; $first = ( $per_page * $paged ) - $per_page + 1;
$last = min( $total, $wp_query->get( 'posts_per_page' ) * $paged ); $last = min( $total, $wp_query->get( 'posts_per_page' ) * $paged );
if ( 1 === $total ) { if ( $total <= $per_page || -1 === $per_page ) {
_e( 'Showing the single result', 'woocommerce' ); printf( _n( 'Showing the single result', 'Showing all %d results', $total, 'woocommerce' ), $total );
} elseif ( $total <= $per_page || -1 === $per_page ) {
printf( __( 'Showing all %d results', 'woocommerce' ), $total );
} else { } else {
printf( _x( 'Showing %1$d&ndash;%2$d of %3$d results', '%1$d = first, %2$d = last, %3$d = total', 'woocommerce' ), $first, $last, $total ); printf( _nx( 'Showing the single result', 'Showing %1$d&ndash;%2$d of %3$d results', $total, '%1$d = first, %2$d = last, %3$d = total', 'woocommerce' ), $first, $last, $total );
} }
?> ?>
</p> </p>

View File

@ -0,0 +1,104 @@
<?php
/**
* Downloads
*
* Shows downloads on the account page.
*
* This template can be overridden by copying it to yourtheme/woocommerce/myaccount/downloads.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
* @version 2.6.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$downloads = WC()->customer->get_downloadable_products();
$has_downloads = (bool) $downloads;
wc_print_notices(); ?>
<?php wc_get_template( 'myaccount/navigation.php' ); ?>
<div class="my-account-content">
<?php do_action( 'woocommerce_before_account_downloads', $has_downloads ); ?>
<?php if ( $has_downloads ) : ?>
<?php do_action( 'woocommerce_before_available_downloads' ); ?>
<table class="shop_table shop_table_responsive account-downloads-table">
<thead>
<tr>
<?php foreach ( wc_get_account_downloads_columns() as $column_id => $column_name ) : ?>
<th class="<?php echo esc_attr( $column_id ); ?>"><span class="nobr"><?php echo esc_html( $column_name ); ?></span></th>
<?php endforeach; ?>
</tr>
</thead>
<?php foreach ( $downloads as $download ) : ?>
<tr class="download">
<?php foreach ( wc_get_account_downloads_columns() as $column_id => $column_name ) : ?>
<td class="<?php echo esc_attr( $column_id ); ?>" data-title="<?php echo esc_attr( $column_name ); ?>">
<?php if ( has_action( 'woocommerce_account_downloads_column_' . $column_id ) ) : ?>
<?php do_action( 'woocommerce_account_downloads_column_' . $column_id, $download ); ?>
<?php elseif ( 'download-file' === $column_id ) : ?>
<a href="<?php echo esc_url( get_permalink( $download['product_id'] ) ); ?>">
<?php echo esc_html( $download['download_name'] ); ?>
</a>
<?php elseif ( 'download-remaining' === $column_id ) : ?>
<?php
if ( is_numeric( $download['downloads_remaining'] ) ) {
echo esc_html( $download['downloads_remaining'] );
} else {
_e( '&infin;', 'woocommerce' );
}
?>
<?php elseif ( 'download-expires' === $column_id ) : ?>
<?php if ( ! empty( $download['access_expires'] ) ) : ?>
<time datetime="<?php echo date( 'Y-m-d', strtotime( $download['access_expires'] ) ); ?>" title="<?php echo esc_attr( strtotime( $download['access_expires'] ) ); ?>"><?php echo date_i18n( get_option( 'date_format' ), strtotime( $download['access_expires'] ) ); ?></time>
<?php else : ?>
<?php _e( 'Never', 'woocommerce' ); ?>
<?php endif; ?>
<?php elseif ( 'download-actions' === $column_id ) : ?>
<?php
$actions = array(
'download' => array(
'url' => $download['download_url'],
'name' => __( 'Download', 'woocommerce' )
)
);
if ( $actions = apply_filters( 'woocommerce_account_download_actions', $actions, $download ) ) {
foreach ( $actions as $key => $action ) {
echo '<a href="' . esc_url( $action['url'] ) . '" class="button ' . sanitize_html_class( $key ) . '">' . esc_html( $action['name'] ) . '</a>';
}
}
?>
<?php endif; ?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>
<?php do_action( 'woocommerce_after_available_downloads' ); ?>
<?php endif; ?>
<?php do_action( 'woocommerce_after_account_downloads', $has_downloads ); ?>
</div>

View File

@ -10,49 +10,55 @@
* happen. When this occurs the version of the template file will be bumped and * happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes. * the readme will list any important changes.
* *
* @see http://docs.woothemes.com/document/template-structure/ * @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes * @author WooThemes
* @package WooCommerce/Templates * @package WooCommerce/Templates
* @version 2.1 * @version 2.6.0
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; exit;
} }
?> wc_get_template( 'myaccount/navigation.php' ); ?>
<form id="add_payment_method" method="post">
<div id="payment">
<?php if ( $available_gateways = WC()->payment_gateways->get_available_payment_gateways() ) : ?>
<ul class="payment_methods methods"><?php
// Chosen Method
if ( sizeof( $available_gateways ) ) {
current( $available_gateways )->set_current();
}
foreach ( $available_gateways as $gateway ) { <div class="my-account-content">
?> <?php if ( $available_gateways = WC()->payment_gateways->get_available_payment_gateways() ) : ?>
<li class="payment_method_<?php echo $gateway->id; ?>"> <form id="add_payment_method" method="post">
<input id="payment_method_<?php echo $gateway->id; ?>" type="radio" class="input-radio" name="payment_method" value="<?php echo esc_attr( $gateway->id ); ?>" <?php checked( $gateway->chosen, true ); ?> /> <div id="payment">
<label for="payment_method_<?php echo $gateway->id; ?>"><?php echo $gateway->get_title(); ?> <?php echo $gateway->get_icon(); ?></label> <ul class="payment_methods methods">
<?php
if ( $gateway->has_fields() || $gateway->get_description() ) {
echo '<div class="payment_box payment_method_' . $gateway->id . '" style="display:none;">';
$gateway->payment_fields();
echo '</div>';
}
?>
</li>
<?php <?php
} // Chosen Method.
?></ul> if ( count( $available_gateways ) ) {
<div class="form-row"> current( $available_gateways )->set_current();
<?php wp_nonce_field( 'woocommerce-add-payment-method' ); ?> }
<input type="submit" class="button alt" id="place_order" value="<?php esc_attr_e( 'Add Payment Method', 'woocommerce' ); ?>" />
<input type="hidden" name="woocommerce_add_payment_method" value="1" /> foreach ( $available_gateways as $gateway ) {
?>
<li class="payment_method_<?php echo $gateway->id; ?>">
<input id="payment_method_<?php echo $gateway->id; ?>" type="radio" class="input-radio" name="payment_method" value="<?php echo esc_attr( $gateway->id ); ?>" <?php checked( $gateway->chosen, true ); ?> />
<label for="payment_method_<?php echo $gateway->id; ?>"><?php echo $gateway->get_title(); ?> <?php echo $gateway->get_icon(); ?></label>
<?php
if ( $gateway->has_fields() || $gateway->get_description() ) {
echo '<div class="payment_box payment_method_' . $gateway->id . '" style="display: none;">';
$gateway->payment_fields();
echo '</div>';
}
?>
</li>
<?php
}
?>
</ul>
<div class="form-row">
<?php wp_nonce_field( 'woocommerce-add-payment-method' ); ?>
<input type="submit" class="button alt" id="place_order" value="<?php esc_attr_e( 'Add Payment Method', 'woocommerce' ); ?>" />
<input type="hidden" name="woocommerce_add_payment_method" value="1" />
</div>
</div> </div>
<?php else : ?> </form>
<p><?php _e( 'Sorry, it seems that there are no payment methods which support adding a new payment method. Please contact us if you require assistance or wish to make alternate arrangements.', 'woocommerce' ); ?></p> <?php else : ?>
<?php endif; ?> <p><?php esc_html_e( 'Sorry, it seems that there are no payment methods which support adding a new payment method. Please contact us if you require assistance or wish to make alternate arrangements.', 'woocommerce' ); ?></p>
</div> <?php endif; ?>
</form> </div>

View File

@ -10,64 +10,66 @@
* happen. When this occurs the version of the template file will be bumped and * happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes. * the readme will list any important changes.
* *
* @see http://docs.woothemes.com/document/template-structure/ * @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes * @author WooThemes
* @package WooCommerce/Templates * @package WooCommerce/Templates
* @version 2.5.1 * @version 2.6.0
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly exit;
} }
?>
<?php wc_print_notices(); ?> wc_print_notices();
<form class="edit-account" action="" method="post"> wc_get_template( 'myaccount/navigation.php' ); ?>
<?php do_action( 'woocommerce_edit_account_form_start' ); ?> <div class="my-account-content">
<form class="edit-account" action="" method="post">
<p class="form-row form-row-first"> <?php do_action( 'woocommerce_edit_account_form_start' ); ?>
<label for="account_first_name"><?php _e( 'First name', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="text" class="input-text" name="account_first_name" id="account_first_name" value="<?php echo esc_attr( $user->first_name ); ?>" />
</p>
<p class="form-row form-row-last">
<label for="account_last_name"><?php _e( 'Last name', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="text" class="input-text" name="account_last_name" id="account_last_name" value="<?php echo esc_attr( $user->last_name ); ?>" />
</p>
<div class="clear"></div>
<p class="form-row form-row-wide"> <p class="form-row form-row-first">
<label for="account_email"><?php _e( 'Email address', 'woocommerce' ); ?> <span class="required">*</span></label> <label for="account_first_name"><?php _e( 'First name', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="email" class="input-text" name="account_email" id="account_email" value="<?php echo esc_attr( $user->user_email ); ?>" /> <input type="text" class="input-text" name="account_first_name" id="account_first_name" value="<?php echo esc_attr( $user->first_name ); ?>" />
</p> </p>
<p class="form-row form-row-last">
<fieldset> <label for="account_last_name"><?php _e( 'Last name', 'woocommerce' ); ?> <span class="required">*</span></label>
<legend><?php _e( 'Password Change', 'woocommerce' ); ?></legend> <input type="text" class="input-text" name="account_last_name" id="account_last_name" value="<?php echo esc_attr( $user->last_name ); ?>" />
</p>
<div class="clear"></div>
<p class="form-row form-row-wide"> <p class="form-row form-row-wide">
<label for="password_current"><?php _e( 'Current Password (leave blank to leave unchanged)', 'woocommerce' ); ?></label> <label for="account_email"><?php _e( 'Email address', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="password" class="input-text" name="password_current" id="password_current" /> <input type="email" class="input-text" name="account_email" id="account_email" value="<?php echo esc_attr( $user->user_email ); ?>" />
</p> </p>
<p class="form-row form-row-wide">
<label for="password_1"><?php _e( 'New Password (leave blank to leave unchanged)', 'woocommerce' ); ?></label> <fieldset>
<input type="password" class="input-text" name="password_1" id="password_1" /> <legend><?php _e( 'Password Change', 'woocommerce' ); ?></legend>
<p class="form-row form-row-wide">
<label for="password_current"><?php _e( 'Current Password (leave blank to leave unchanged)', 'woocommerce' ); ?></label>
<input type="password" class="input-text" name="password_current" id="password_current" />
</p>
<p class="form-row form-row-wide">
<label for="password_1"><?php _e( 'New Password (leave blank to leave unchanged)', 'woocommerce' ); ?></label>
<input type="password" class="input-text" name="password_1" id="password_1" />
</p>
<p class="form-row form-row-wide">
<label for="password_2"><?php _e( 'Confirm New Password', 'woocommerce' ); ?></label>
<input type="password" class="input-text" name="password_2" id="password_2" />
</p>
</fieldset>
<div class="clear"></div>
<?php do_action( 'woocommerce_edit_account_form' ); ?>
<p>
<?php wp_nonce_field( 'save_account_details' ); ?>
<input type="submit" class="button" name="save_account_details" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>" />
<input type="hidden" name="action" value="save_account_details" />
</p> </p>
<p class="form-row form-row-wide">
<label for="password_2"><?php _e( 'Confirm New Password', 'woocommerce' ); ?></label>
<input type="password" class="input-text" name="password_2" id="password_2" />
</p>
</fieldset>
<div class="clear"></div>
<?php do_action( 'woocommerce_edit_account_form' ); ?> <?php do_action( 'woocommerce_edit_account_form_end' ); ?>
</form>
<p> </div>
<?php wp_nonce_field( 'save_account_details' ); ?>
<input type="submit" class="button" name="save_account_details" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>" />
<input type="hidden" name="action" value="save_account_details" />
</p>
<?php do_action( 'woocommerce_edit_account_form_end' ); ?>
</form>

View File

@ -10,47 +10,48 @@
* happen. When this occurs the version of the template file will be bumped and * happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes. * the readme will list any important changes.
* *
* @see http://docs.woothemes.com/document/template-structure/ * @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes * @author WooThemes
* @package WooCommerce/Templates * @package WooCommerce/Templates
* @version 2.1.0 * @version 2.6.0
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly exit;
} }
$page_title = ( $load_address === 'billing' ) ? __( 'Billing Address', 'woocommerce' ) : __( 'Shipping Address', 'woocommerce' ); $page_title = ( $load_address === 'billing' ) ? __( 'Billing Address', 'woocommerce' ) : __( 'Shipping Address', 'woocommerce' );
?>
<?php wc_print_notices(); ?> wc_print_notices();
<?php if ( ! $load_address ) : ?> wc_get_template( 'myaccount/navigation.php' ); ?>
<?php wc_get_template( 'myaccount/my-address.php' ); ?> <div class="my-account-content">
<?php if ( ! $load_address ) : ?>
<?php wc_get_template( 'myaccount/my-address.php' ); ?>
<?php else : ?>
<?php else : ?> <form method="post">
<form method="post"> <h3><?php echo apply_filters( 'woocommerce_my_account_edit_address_title', $page_title ); ?></h3>
<h3><?php echo apply_filters( 'woocommerce_my_account_edit_address_title', $page_title ); ?></h3> <?php do_action( "woocommerce_before_edit_address_form_{$load_address}" ); ?>
<?php do_action( "woocommerce_before_edit_address_form_{$load_address}" ); ?> <?php foreach ( $address as $key => $field ) : ?>
<?php foreach ( $address as $key => $field ) : ?> <?php woocommerce_form_field( $key, $field, ! empty( $_POST[ $key ] ) ? wc_clean( $_POST[ $key ] ) : $field['value'] ); ?>
<?php woocommerce_form_field( $key, $field, ! empty( $_POST[ $key ] ) ? wc_clean( $_POST[ $key ] ) : $field['value'] ); ?> <?php endforeach; ?>
<?php endforeach; ?> <?php do_action( "woocommerce_after_edit_address_form_{$load_address}" ); ?>
<?php do_action( "woocommerce_after_edit_address_form_{$load_address}" ); ?> <p>
<input type="submit" class="button" name="save_address" value="<?php esc_attr_e( 'Save Address', 'woocommerce' ); ?>" />
<?php wp_nonce_field( 'woocommerce-edit_address' ); ?>
<input type="hidden" name="action" value="edit_address" />
</p>
<p> </form>
<input type="submit" class="button" name="save_address" value="<?php esc_attr_e( 'Save Address', 'woocommerce' ); ?>" />
<?php wp_nonce_field( 'woocommerce-edit_address' ); ?>
<input type="hidden" name="action" value="edit_address" />
</p>
</form> <?php endif; ?>
</div>
<?php endif; ?>

View File

@ -10,10 +10,10 @@
* happen. When this occurs the version of the template file will be bumped and * happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes. * the readme will list any important changes.
* *
* @see http://docs.woothemes.com/document/template-structure/ * @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes * @author WooThemes
* @package WooCommerce/Templates * @package WooCommerce/Templates
* @version 2.2.6 * @version 2.2.6
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {

View File

@ -10,7 +10,7 @@
* happen. When this occurs the version of the template file will be bumped and * happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes. * the readme will list any important changes.
* *
* @see http://docs.woothemes.com/document/template-structure/ * @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes * @author WooThemes
* @package WooCommerce/Templates * @package WooCommerce/Templates
* @version 2.3.0 * @version 2.3.0

View File

@ -10,38 +10,53 @@
* happen. When this occurs the version of the template file will be bumped and * happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes. * the readme will list any important changes.
* *
* @see http://docs.woothemes.com/document/template-structure/ * @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes * @author WooThemes
* @package WooCommerce/Templates * @package WooCommerce/Templates
* @version 2.0.0 * @version 2.6.0
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly exit;
} }
wc_print_notices(); ?> wc_print_notices(); ?>
<p class="myaccount_user"> <?php wc_get_template( 'myaccount/navigation.php' ); ?>
<div class="my-account-content">
<p class="myaccount_user">
<?php
printf(
__( 'Hello <strong>%1$s</strong> (not %1$s? <a href="%2$s">Sign out</a>).', 'woocommerce' ) . ' ',
$current_user->display_name,
wc_get_endpoint_url( 'customer-logout', '', wc_get_page_permalink( 'myaccount' ) )
);
_e( 'From your account dashboard you can view your recent orders, manage your shipping and billing addresses and edit your password and account details.', 'woocommerce' );
?>
</p>
<?php <?php
printf( /**
__( 'Hello <strong>%1$s</strong> (not %1$s? <a href="%2$s">Sign out</a>).', 'woocommerce' ) . ' ', * My Account dashboard.
$current_user->display_name, *
wc_get_endpoint_url( 'customer-logout', '', wc_get_page_permalink( 'myaccount' ) ) * @since 2.6.0
); */
do_action( 'woocommerce_account_dashboard' );
printf( __( 'From your account dashboard you can view your recent orders, manage your shipping and billing addresses and <a href="%s">edit your password and account details</a>.', 'woocommerce' ), /**
wc_customer_edit_account_url() * Deprecated woocommerce_before_my_account action.
); *
* @deprecated 2.6.0
*/
do_action( 'woocommerce_before_my_account' );
/**
* Deprecated woocommerce_after_my_account action.
*
* @deprecated 2.6.0
*/
do_action( 'woocommerce_after_my_account' );
?> ?>
</p> </div>
<?php do_action( 'woocommerce_before_my_account' ); ?>
<?php wc_get_template( 'myaccount/my-downloads.php' ); ?>
<?php wc_get_template( 'myaccount/my-orders.php', array( 'order_count' => $order_count ) ); ?>
<?php wc_get_template( 'myaccount/my-address.php' ); ?>
<?php do_action( 'woocommerce_after_my_account' ); ?>

View File

@ -10,10 +10,10 @@
* happen. When this occurs the version of the template file will be bumped and * happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes. * the readme will list any important changes.
* *
* @see http://docs.woothemes.com/document/template-structure/ * @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes * @author WooThemes
* @package WooCommerce/Templates * @package WooCommerce/Templates
* @version 2.2.0 * @version 2.2.0
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
@ -24,13 +24,13 @@ $customer_id = get_current_user_id();
if ( ! wc_ship_to_billing_address_only() && wc_shipping_enabled() ) { if ( ! wc_ship_to_billing_address_only() && wc_shipping_enabled() ) {
$page_title = apply_filters( 'woocommerce_my_account_my_address_title', __( 'My Addresses', 'woocommerce' ) ); $page_title = apply_filters( 'woocommerce_my_account_my_address_title', __( 'My Addresses', 'woocommerce' ) );
$get_addresses = apply_filters( 'woocommerce_my_account_get_addresses', array( $get_addresses = apply_filters( 'woocommerce_my_account_get_addresses', array(
'billing' => __( 'Billing Address', 'woocommerce' ), 'billing' => __( 'Billing Address', 'woocommerce' ),
'shipping' => __( 'Shipping Address', 'woocommerce' ) 'shipping' => __( 'Shipping Address', 'woocommerce' )
), $customer_id ); ), $customer_id );
} else { } else {
$page_title = apply_filters( 'woocommerce_my_account_my_address_title', __( 'My Address', 'woocommerce' ) ); $page_title = apply_filters( 'woocommerce_my_account_my_address_title', __( 'My Address', 'woocommerce' ) );
$get_addresses = apply_filters( 'woocommerce_my_account_get_addresses', array( $get_addresses = apply_filters( 'woocommerce_my_account_get_addresses', array(
'billing' => __( 'Billing Address', 'woocommerce' ) 'billing' => __( 'Billing Address', 'woocommerce' )
), $customer_id ); ), $customer_id );
} }
@ -51,7 +51,7 @@ $col = 1;
<div class="col-<?php echo ( ( $col = $col * -1 ) < 0 ) ? 1 : 2; ?> address"> <div class="col-<?php echo ( ( $col = $col * -1 ) < 0 ) ? 1 : 2; ?> address">
<header class="title"> <header class="title">
<h3><?php echo $title; ?></h3> <h3><?php echo $title; ?></h3>
<a href="<?php echo wc_get_endpoint_url( 'edit-address', $name ); ?>" class="edit"><?php _e( 'Edit', 'woocommerce' ); ?></a> <a href="<?php echo esc_url( wc_get_endpoint_url( 'edit-address', $name ) ); ?>" class="edit"><?php _e( 'Edit', 'woocommerce' ); ?></a>
</header> </header>
<address> <address>
<?php <?php

View File

@ -1,8 +1,8 @@
<?php <?php
/** /**
* My Orders * My Downloads
* *
* Shows recent orders on the account page. * Shows downloads on the account page.
* *
* This template can be overridden by copying it to yourtheme/woocommerce/myaccount/my-downloads.php. * This template can be overridden by copying it to yourtheme/woocommerce/myaccount/my-downloads.php.
* *
@ -12,10 +12,11 @@
* happen. When this occurs the version of the template file will be bumped and * happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes. * the readme will list any important changes.
* *
* @see http://docs.woothemes.com/document/template-structure/ * @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes * @author WooThemes
* @package WooCommerce/Templates * @package WooCommerce/Templates
* @version 2.0.0 * @version 2.0.0
* @depreacated 2.6.0
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {

View File

@ -12,10 +12,11 @@
* happen. When this occurs the version of the template file will be bumped and * happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes. * the readme will list any important changes.
* *
* @see http://docs.woothemes.com/document/template-structure/ * @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes * @author WooThemes
* @package WooCommerce/Templates * @package WooCommerce/Templates
* @version 2.5.0 * @version 2.5.0
* @depreacated 2.6.0
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {

View File

@ -0,0 +1,33 @@
<?php
/**
* My Account navigation
*
* This template can be overridden by copying it to yourtheme/woocommerce/myaccount/navigation.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
* @version 2.6.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<nav class="my-account-navigation">
<ul>
<?php foreach ( wc_get_account_menu_items() as $endpoint => $label ) : ?>
<li class="<?php echo wc_get_account_menu_item_classes( $endpoint ); ?>">
<a href="<?php echo esc_url( wc_get_account_endpoint_url( $endpoint ) ); ?>"><?php echo esc_html( $label ); ?></a>
</li>
<?php endforeach; ?>
</ul>
</nav>

View File

@ -0,0 +1,136 @@
<?php
/**
* Orders
*
* Shows orders on the account page.
*
* This template can be overridden by copying it to yourtheme/woocommerce/myaccount/orders.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
* @version 2.6.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$customer_orders = new WP_Query( wc_get_account_orders_query_args( $current_page ) );
$has_orders = $customer_orders->have_posts();
wc_print_notices();
wc_get_template( 'myaccount/navigation.php' ); ?>
<div class="my-account-content">
<?php do_action( 'woocommerce_before_account_orders', $has_orders ); ?>
<?php if ( $has_orders ) : ?>
<table class="shop_table shop_table_responsive my_account_orders account-orders-table">
<thead>
<tr>
<?php foreach ( wc_get_account_orders_columns() as $column_id => $column_name ) : ?>
<th class="<?php echo esc_attr( $column_id ); ?>"><span class="nobr"><?php echo esc_html( $column_name ); ?></span></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php foreach ( $customer_orders->posts as $customer_order ) :
$order = wc_get_order( $customer_order );
$item_count = $order->get_item_count();
?>
<tr class="order">
<?php foreach ( wc_get_account_orders_columns() as $column_id => $column_name ) : ?>
<td class="<?php echo esc_attr( $column_id ); ?>" data-title="<?php echo esc_attr( $column_name ); ?>">
<?php if ( has_action( 'woocommerce_my_account_my_orders_column_' . $column_id ) ) : ?>
<?php do_action( 'woocommerce_my_account_my_orders_column_' . $column_id, $order ); ?>
<?php elseif ( 'order-number' === $column_id ) : ?>
<a href="<?php echo esc_url( $order->get_view_order_url() ); ?>">
<?php echo _x( '#', 'hash before order number', 'woocommerce' ) . $order->get_order_number(); ?>
</a>
<?php elseif ( 'order-date' === $column_id ) : ?>
<time datetime="<?php echo date( 'Y-m-d', strtotime( $order->order_date ) ); ?>" title="<?php echo esc_attr( strtotime( $order->order_date ) ); ?>"><?php echo date_i18n( get_option( 'date_format' ), strtotime( $order->order_date ) ); ?></time>
<?php elseif ( 'order-status' === $column_id ) : ?>
<?php echo wc_get_order_status_name( $order->get_status() ); ?>
<?php elseif ( 'order-total' === $column_id ) : ?>
<?php echo sprintf( _n( '%s for %s item', '%s for %s items', $item_count, 'woocommerce' ), $order->get_formatted_order_total(), $item_count ); ?>
<?php elseif ( 'order-actions' === $column_id ) : ?>
<?php
$actions = array(
'pay' => array(
'url' => $order->get_checkout_payment_url(),
'name' => __( 'Pay', 'woocommerce' )
),
'view' => array(
'url' => $order->get_view_order_url(),
'name' => __( 'View', 'woocommerce' )
),
'cancel' => array(
'url' => $order->get_cancel_order_url( wc_get_page_permalink( 'myaccount' ) ),
'name' => __( 'Cancel', 'woocommerce' )
)
);
if ( ! $order->needs_payment() ) {
unset( $actions['pay'] );
}
if ( ! in_array( $order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ) ) ) {
unset( $actions['cancel'] );
}
if ( $actions = apply_filters( 'woocommerce_my_account_my_orders_actions', $actions, $order ) ) {
foreach ( $actions as $key => $action ) {
echo '<a href="' . esc_url( $action['url'] ) . '" class="button ' . sanitize_html_class( $key ) . '">' . esc_html( $action['name'] ) . '</a>';
}
}
?>
<?php endif; ?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php do_action( 'woocommerce_before_account_orders_pagination' ); ?>
<?php if ( 1 < $customer_orders->max_num_pages ) : ?>
<div class="wc-account-orders-pagination">
<?php if ( 1 !== $current_page ) : ?>
<a class="button" href="<?php echo esc_url( wc_get_endpoint_url( 'orders', $current_page - 1 ) ); ?>"><?php _e( 'Previous', 'woocommerce' ); ?></a>
<?php endif; ?>
<?php if ( $current_page !== intval( $customer_orders->max_num_pages ) ) : ?>
<a class="button" href="<?php echo esc_url( wc_get_endpoint_url( 'orders', $current_page + 1 ) ); ?>"><?php _e( 'Next', 'woocommerce' ); ?></a>
<?php endif; ?>
</div>
<?php endif; ?>
<?php else : ?>
<div class="woocommerce-info">
<a class="button" href="<?php echo esc_url( apply_filters( 'woocommerce_return_to_shop_redirect', wc_get_page_permalink( 'shop' ) ) ); ?>">
<?php _e( 'Go Shop', 'woocommerce' ) ?>
</a>
<?php _e( 'No order has been made yet.', 'woocommerce' ); ?>
</div>
<?php endif; ?>
<?php do_action( 'woocommerce_after_account_orders', $has_orders ); ?>
</div>

View File

@ -0,0 +1,69 @@
<?php
/**
* Payment methods
*
* Shows customer payment methods on the account page.
*
* This template can be overridden by copying it to yourtheme/woocommerce/myaccount/payment-methods.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
* @version 2.6.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$saved_methods = wc_get_customer_saved_methods_list( get_current_user_id() );
$has_methods = (bool) $saved_methods;
wc_print_notices(); ?>
<?php wc_get_template( 'myaccount/navigation.php' ); ?>
<div class="my-account-content">
<?php do_action( 'woocommerce_before_account_payment_methods', $has_methods ); ?>
<?php if ( $has_methods ) : ?>
<table class="shop_table shop_table_responsive account-payment-methods-table">
<thead>
<tr>
<?php foreach ( wc_get_account_payment_methods_columns() as $column_id => $column_name ) : ?>
<th class="payment-method-<?php echo esc_attr( $column_id ); ?>"><span class="nobr"><?php echo esc_html( $column_name ); ?></span></th>
<?php endforeach; ?>
</tr>
</thead>
<?php foreach ( $saved_methods as $method ) : ?>
<tr class="method">
<?php foreach ( wc_get_account_payment_methods_columns() as $column_id => $column_name ) : ?>
<td class="payment-method-<?php echo esc_attr( $column_id ); ?>" data-title="<?php echo esc_attr( $column_name ); ?>">
<?php
// @TODO
?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>
<?php else : ?>
<p><?php esc_html_e( 'No saved method found.', 'woocommerce' ); ?></p>
<?php endif; ?>
<?php do_action( 'woocommerce_after_account_payment_methods', $has_methods ); ?>
<a class="button" href="<?php echo esc_url( wc_get_endpoint_url( 'add-payment-method' ) ); ?>"><?php esc_html_e( 'Add New Payment Method', 'woocommerce' ); ?></a>
</div>

View File

@ -12,42 +12,42 @@
* happen. When this occurs the version of the template file will be bumped and * happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes. * the readme will list any important changes.
* *
* @see http://docs.woothemes.com/document/template-structure/ * @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes * @author WooThemes
* @package WooCommerce/Templates * @package WooCommerce/Templates
* @version 2.2.0 * @version 2.6.0
*/ */
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly exit;
} }
?> wc_print_notices(); ?>
<?php wc_print_notices(); ?> <?php wc_get_template( 'myaccount/navigation.php' ); ?>
<p class="order-info"><?php printf( __( 'Order #<mark class="order-number">%s</mark> was placed on <mark class="order-date">%s</mark> and is currently <mark class="order-status">%s</mark>.', 'woocommerce' ), $order->get_order_number(), date_i18n( get_option( 'date_format' ), strtotime( $order->order_date ) ), wc_get_order_status_name( $order->get_status() ) ); ?></p> <div class="my-account-content">
<p class="order-info"><?php printf( __( 'Order #<mark class="order-number">%s</mark> was placed on <mark class="order-date">%s</mark> and is currently <mark class="order-status">%s</mark>.', 'woocommerce' ), $order->get_order_number(), date_i18n( get_option( 'date_format' ), strtotime( $order->order_date ) ), wc_get_order_status_name( $order->get_status() ) ); ?></p>
<?php if ( $notes = $order->get_customer_order_notes() ) : <?php if ( $notes = $order->get_customer_order_notes() ) : ?>
?> <h2><?php _e( 'Order Updates', 'woocommerce' ); ?></h2>
<h2><?php _e( 'Order Updates', 'woocommerce' ); ?></h2> <ol class="commentlist notes">
<ol class="commentlist notes"> <?php foreach ( $notes as $note ) : ?>
<?php foreach ( $notes as $note ) : ?> <li class="comment note">
<li class="comment note"> <div class="comment_container">
<div class="comment_container"> <div class="comment-text">
<div class="comment-text"> <p class="meta"><?php echo date_i18n( __( 'l jS \o\f F Y, h:ia', 'woocommerce' ), strtotime( $note->comment_date ) ); ?></p>
<p class="meta"><?php echo date_i18n( __( 'l jS \o\f F Y, h:ia', 'woocommerce' ), strtotime( $note->comment_date ) ); ?></p> <div class="description">
<div class="description"> <?php echo wpautop( wptexturize( $note->comment_content ) ); ?>
<?php echo wpautop( wptexturize( $note->comment_content ) ); ?> </div>
</div> <div class="clear"></div>
<div class="clear"></div> </div>
</div> <div class="clear"></div>
<div class="clear"></div> </div>
</div> </li>
</li> <?php endforeach; ?>
<?php endforeach; ?> </ol>
</ol> <?php endif; ?>
<?php
endif;
do_action( 'woocommerce_view_order', $order_id ); <?php do_action( 'woocommerce_view_order', $order_id ); ?>
</div>

View File

@ -19,18 +19,11 @@
if ( ! defined( 'ABSPATH' ) ) { if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly exit; // Exit if accessed directly
} }
?>
$order_status_text = sprintf( __( 'Order #%s which was made %s has the status &ldquo;%s&rdquo;', 'woocommerce' ), $order->get_order_number(), human_time_diff( strtotime( $order->order_date ), current_time( 'timestamp' ) ) . ' ' . __( 'ago', 'woocommerce' ), wc_get_order_status_name( $order->get_status() ) ); <p class="order-info"><?php echo wp_kses_post( apply_filters( 'woocommerce_order_tracking_status', sprintf( __( 'Order #<mark class="order-number">%s</mark> was placed on <mark class="order-date">%s</mark> and is currently <mark class="order-status">%s</mark>.', 'woocommerce' ), $order->get_order_number(), date_i18n( get_option( 'date_format' ), strtotime( $order->order_date ) ), wc_get_order_status_name( $order->get_status() ) ), $order ) ); ?></p>
if ( $order->has_status( 'completed' ) ) $order_status_text .= ' ' . __( 'and was completed', 'woocommerce' ) . ' ' . human_time_diff( strtotime( $order->completed_date ), current_time( 'timestamp' ) ) . __( ' ago', 'woocommerce' ); <?php if ( $notes = $order->get_customer_order_notes() ) : ?>
$order_status_text .= '.';
echo wpautop( esc_attr( apply_filters( 'woocommerce_order_tracking_status', $order_status_text, $order ) ) );
$notes = $order->get_customer_order_notes();
if ( $notes ) : ?>
<h2><?php _e( 'Order Updates', 'woocommerce' ); ?></h2> <h2><?php _e( 'Order Updates', 'woocommerce' ); ?></h2>
<ol class="commentlist notes"> <ol class="commentlist notes">
<?php foreach ( $notes as $note ) : ?> <?php foreach ( $notes as $note ) : ?>
@ -39,10 +32,10 @@ if ( $notes ) : ?>
<div class="comment-text"> <div class="comment-text">
<p class="meta"><?php echo date_i18n( __( 'l jS \o\f F Y, h:ia', 'woocommerce' ), strtotime( $note->comment_date ) ); ?></p> <p class="meta"><?php echo date_i18n( __( 'l jS \o\f F Y, h:ia', 'woocommerce' ), strtotime( $note->comment_date ) ); ?></p>
<div class="description"> <div class="description">
<?php echo wpautop( wptexturize( wp_kses_post( $note->comment_content ) ) ); ?> <?php echo wpautop( wptexturize( $note->comment_content ) ); ?>
</div> </div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
</li> </li>

View File

@ -0,0 +1,71 @@
<?php
namespace WooCommerce\Tests\Account;
/**
* Class Functions.
* @package WooCommerce\Tests\Account
*/
class Functions extends \WC_Unit_Test_Case {
/**
* Test wc_get_account_menu_items().
*
* @since 2.6.0
*/
public function test_wc_get_account_menu_items() {
$this->assertEquals( array(
'dashboard' => __( 'Dashboard', 'woocommerce' ),
'orders' => __( 'Orders', 'woocommerce' ),
'downloads' => __( 'Downloads', 'woocommerce' ),
'edit-address' => __( 'Addresses', 'woocommerce' ),
'payment-methods' => __( 'Payment Methods', 'woocommerce' ),
'edit-account' => __( 'Account Details', 'woocommerce' ),
'customer-logout' => __( 'Logout', 'woocommerce' ),
), wc_get_account_menu_items() );
}
/**
* Test wc_get_account_orders_columns().
*
* @since 2.6.0
*/
public function test_wc_get_account_orders_columns() {
$this->assertEquals( array(
'order-number' => __( 'Order', 'woocommerce' ),
'order-date' => __( 'Date', 'woocommerce' ),
'order-status' => __( 'Status', 'woocommerce' ),
'order-total' => __( 'Total', 'woocommerce' ),
'order-actions' => '&nbsp;',
), wc_get_account_orders_columns() );
}
/**
* Test wc_get_account_orders_query_args().
*
* @since 2.6.0
*/
public function test_wc_get_account_orders_query_args() {
$this->assertEquals( array(
'posts_per_page' => 15,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(),
'post_type' => wc_get_order_types( 'view-orders' ),
'post_status' => array_keys( wc_get_order_statuses() ),
), wc_get_account_orders_query_args() );
}
/**
* Test wc_get_account_downloads_columns().
*
* @since 2.6.0
*/
public function test_wc_get_account_downloads_columns() {
$this->assertEquals( array(
'download-file' => __( 'File', 'woocommerce' ),
'download-remaining' => __( 'Remaining', 'woocommerce' ),
'download-expires' => __( 'Expires', 'woocommerce' ),
'download-actions' => '&nbsp;',
), wc_get_account_downloads_columns() );
}
}

View File

@ -640,10 +640,10 @@ class Functions extends \WC_Unit_Test_Case {
* @since 2.2 * @since 2.2
*/ */
public function test_wc_trim_string() { public function test_wc_trim_string() {
$this->assertEquals( 'string', wc_trim_string( 'string' ) ); $this->assertEquals( 'string', wc_trim_string( 'string' ) );
$this->assertEquals( 's...', wc_trim_string( 'string', 4 ) ); $this->assertEquals( 's...', wc_trim_string( 'string', 4 ) );
$this->assertEquals( 'st.', wc_trim_string( 'string', 3, '.' ) ); $this->assertEquals( 'st.', wc_trim_string( 'string', 3, '.' ) );
$this->assertEquals( 'string¥', wc_trim_string( 'string¥', 7, '' ) );
} }
} }