Merge branch 'master' of github.com:woothemes/woocommerce

This commit is contained in:
Nicola Mustone 2015-05-26 12:08:34 +02:00
commit 918b29a1e8
99 changed files with 2789 additions and 1239 deletions

View File

@ -54,10 +54,20 @@ module.exports = function( grunt ) {
'<%= dirs.js %>/admin/jquery.flot.pie.min.js': ['<%= dirs.js %>/admin/jquery.flot.pie.js'],
'<%= dirs.js %>/admin/jquery.flot.resize.min.js': ['<%= dirs.js %>/admin/jquery.flot.resize.js'],
'<%= dirs.js %>/admin/jquery.flot.stack.min.js': ['<%= dirs.js %>/admin/jquery.flot.stack.js'],
'<%= dirs.js %>/admin/jquery.flot.time.min.js': ['<%= dirs.js %>/admin/jquery.flot.time.js'],
'<%= dirs.js %>/jquery-payment/jquery.payment.min.js': ['<%= dirs.js %>/jquery-payment/jquery.payment.js'],
'<%= dirs.js %>/admin/jquery.flot.time.min.js': ['<%= dirs.js %>/admin/jquery.flot.time.js']
}
},
jquery: {
files: {
'<%= dirs.js %>/jquery-blockui/jquery.blockUI.min.js': ['<%= dirs.js %>/jquery-blockui/jquery.blockUI.js'],
'<%= dirs.js %>/jquery-cookie/jquery.cookie.min.js': ['<%= dirs.js %>/jquery-cookie/jquery.cookie.js'],
'<%= dirs.js %>/jquery-payment/jquery.payment.min.js': ['<%= dirs.js %>/jquery-payment/jquery.payment.js'],
'<%= dirs.js %>/jquery-tiptip/jquery.tipTip.min.js': ['<%= dirs.js %>/jquery-tiptip/jquery.tipTip.js'],
'<%= dirs.js %>/prettyPhoto/jquery.prettyPhoto.init.min.js': ['<%= dirs.js %>/prettyPhoto/jquery.prettyPhoto.init.js'],
'<%= dirs.js %>/prettyPhoto/jquery.prettyPhoto.min.js': ['<%= dirs.js %>/prettyPhoto/jquery.prettyPhoto.js'],
'<%= dirs.js %>/select2/select2.min.js': ['<%= dirs.js %>/select2/select2.js'],
'<%= dirs.js %>/stupidtable/stupidtable.min.js': ['<%= dirs.js %>/stupidtable/stupidtable.js'],
'<%= dirs.js %>/zeroclipboard/jquery.zeroclipboard.min.js': ['<%= dirs.js %>/zeroclipboard/jquery.zeroclipboard.js']
}
},
frontend: {

File diff suppressed because one or more lines are too long

View File

@ -617,14 +617,51 @@ ul.wc_coupon_list_block {
float: right;
}
}
}
a.edit_address {
opacity: 0.4;
&:hover,
&:focus {
opacity: 1;
a.edit_address, .billing-same-as-shipping, .load_customer_shipping, .load_customer_billing {
width: 14px;
height: 0;
padding: 14px 0 0 0;
margin: 0 0 0 6px;
overflow: hidden;
position: relative;
color: #999;
border: 0;
float: right;
&:hover, &:focus {
color: #000;
}
&:after {
font-family: 'WooCommerce';
position: absolute;
top: 0;
left: 0;
text-align: center;
vertical-align: top;
line-height: 14px;
font-size: 14px;
font-weight: 400;
-webkit-font-smoothing: antialiased;
}
}
.billing-same-as-shipping {
&:after {
content: "\e008";
}
}
.load_customer_shipping {
&:after {
content: "\e03a";
}
}
.load_customer_billing {
&:after {
content: "\e03a";
}
}
a.edit_address {
&:after {
content: "\e603";
}
}
}
}
@ -3905,21 +3942,6 @@ table.bar_chart {
}
}
/**
* Profile Page
*/
#profile-page {
.api-keys-wrapper {
float: left;
padding-bottom: 10px;
}
.api-keys-get-qr {
float: left;
padding-left: 10px;
}
}
/**
* Small screen optimisation
*/

1
assets/css/auth.css Normal file
View File

@ -0,0 +1 @@
body{margin:100px auto 24px;box-shadow:none;background:#f1f1f1;padding:0}#wc-logo{border:0;margin:0 0 24px;padding:0;text-align:center}#wc-logo img{max-width:50%}.wc-auth-content{box-shadow:0 1px 3px rgba(0,0,0,.13);padding:24px 24px 0;background:#fff;overflow:hidden;zoom:1}.wc-auth-content h1,.wc-auth-content h2,.wc-auth-content h3,.wc-auth-content table{margin:0 0 24px;border:0;padding:0;color:#666;clear:none}.wc-auth-content p,.wc-auth-content ul{margin:0 0 24px;font-size:1em;line-height:1.75em;color:#666}.wc-auth-content p{padding:0}.wc-auth-content a{color:#A16696}.wc-auth-content a:focus,.wc-auth-content a:hover{color:#111}.wc-auth-content .wc-auth-login label{display:block;margin-bottom:.5em;color:#999}.wc-auth-content .wc-auth-login input{font-size:1.3em;padding:.5em;width:100%;box-sizing:border-box}.wc-auth-content .wc-auth-login .wc-auth-actions{padding:0}.wc-auth-content .wc-auth-login .wc-auth-actions .wc-auth-login-button{width:100%;float:none}.wc-auth-permissions{padding:0;list-style:disc inside}.wc-auth-permissions li{font-size:1em}.wc-auth-logged-in-as{border-bottom:2px solid #eee;background:#f5f5f5;padding:0 1em 0 0;margin:0 0 24px;line-height:70px}.wc-auth-logged-in-as p{margin:0;line-height:70px}.wc-auth-logged-in-as img{float:left;height:70px;margin:0 1em 0 0}.wc-auth-logged-in-as .wc-auth-logout{float:right}.wc-auth .wc-auth-actions{overflow:hidden;padding-left:24px}.wc-auth .wc-auth-actions .button{float:right;font-size:1.25em;padding:1em 2em;line-height:1em;height:auto;width:50%;box-sizing:border-box;text-align:center;background:#f7f7f7;border:1px solid #d7d7d7;color:#777;border-bottom-width:2px}.wc-auth .wc-auth-actions .button:focus,.wc-auth .wc-auth-actions .button:hover{background:#fcfcfc}.wc-auth .wc-auth-actions .button-primary{float:right;opacity:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 0 rgba(0,0,0,.15);background:#AD6EA1;border-color:#A16696;color:#fff}.wc-auth .wc-auth-actions .button-primary:focus,.wc-auth .wc-auth-actions .button-primary:hover{background:#B472A8;color:#fff}.wc-auth .wc-auth-actions .wc-auth-approve{float:right}.wc-auth .wc-auth-actions .wc-auth-deny{float:left;margin-left:-24px}

131
assets/css/auth.scss Normal file
View File

@ -0,0 +1,131 @@
body {
margin: 100px auto 24px;
box-shadow: none;
background: #f1f1f1;
padding: 0;
}
#wc-logo {
border: 0;
margin: 0 0 24px;
padding: 0;
text-align: center;
img {
max-width: 50%;
}
}
.wc-auth-content {
box-shadow: 0 1px 3px rgba(0,0,0,0.13);
padding: 24px 24px 0;
background: #fff;
overflow: hidden;
zoom: 1;
h1, h2, h3, table {
margin: 0 0 24px;
border: 0;
padding: 0;
color: #666;
clear: none;
}
p, ul {
margin: 0 0 24px;
font-size: 1em;
line-height: 1.75em;
color: #666;
}
p {
padding: 0;
}
a {
color: #A16696;
&:hover, &:focus {
color: #111;
}
}
.wc-auth-login {
label {
display: block;
margin-bottom: .5em;
color: #999;
}
input {
font-size: 1.3em;
padding: .5em;
width: 100%;
box-sizing: border-box;
}
.wc-auth-actions {
padding: 0;
.wc-auth-login-button {
width: 100%;
float: none;
}
}
}
}
.wc-auth-permissions {
padding: 0;
list-style: disc inside;
li {
font-size: 1em;
}
}
.wc-auth-logged-in-as {
border-bottom: 2px solid #eee;
background: #f5f5f5;
padding: 0 1em 0 0;
margin: 0 0 24px;
line-height: 70px;
p {
margin: 0;
line-height: 70px;
}
img {
float: left;
height: 70px;
margin: 0 1em 0 0;
}
.wc-auth-logout {
float: right;
}
}
.wc-auth .wc-auth-actions {
overflow: hidden;
padding-left: 24px;
.button {
float: right;
font-size: 1.25em;
padding: 1em 2em;
line-height: 1em;
height: auto;
width: 50%;
box-sizing: border-box;
text-align: center;
background: #f7f7f7;
border: 1px solid #d7d7d7;
color: #777;
border-bottom-width: 2px;
&:hover, &:focus {
background: #fcfcfc;
}
}
.button-primary {
float: right;
opacity: 1;
-webkit-box-shadow: inset 0 1px 0 rgba( 255, 255, 255, 0.2 ), 0 1px 0 rgba( 0, 0, 0, 0.15 );
box-shadow: inset 0 1px 0 rgba( 255, 255, 255, 0.2 ), 0 1px 0 rgba( 0, 0, 0, 0.15 );
background: #AD6EA1;
border-color: #A16696;
color: #fff;
&:hover, &:focus {
background: #B472A8;
color: #fff;
}
}
.wc-auth-approve {
float: right;
}
.wc-auth-deny {
float: left;
margin-left: -24px;
}
}

File diff suppressed because one or more lines are too long

View File

@ -115,26 +115,6 @@
/**
* Product loops
*/
.related,
.upsells.products {
@include clearfix();
clear: both;
ul.products,
ul {
float: none;
li.product {
width: 48%;
img {
width: 100%;
height: auto;
}
}
}
}
ul.products {
clear: both;
@include clearfix();

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 998 810" enable-background="new 0 0 998 810" xml:space="preserve">
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#9B5C8F" d="M160.7,331.2h199.1c12.6,0,22.8,10.2,22.8,22.8V430
c0,12.6-10.2,22.8-22.8,22.8h-71.4l9.8,24l-43.1-24h-94.3c-12.6,0-22.8-10.2-22.8-22.8V354C137.9,341.5,148.1,331.2,160.7,331.2z"
/>
<path fill="#FFFFFF" d="M150.2,351.9c1.4-1.9,3.5-2.9,6.3-3.1c5.1-0.4,8,2,8.7,7.2c3.1,20.9,6.5,38.6,10.1,53.1l21.9-41.7
c2-3.8,4.5-5.8,7.5-6c4.4-0.3,7.1,2.5,8.2,8.4c2.5,13.3,5.7,24.6,9.5,34.2c2.6-25.4,7-43.7,13.2-55c1.5-2.8,3.7-4.2,6.6-4.4
c2.3-0.2,4.4,0.5,6.3,2c1.9,1.5,2.9,3.4,3.1,5.7c0.1,1.8-0.2,3.3-1,4.8c-3.9,7.2-7.1,19.3-9.7,36.1c-2.5,16.3-3.4,29-2.8,38.1
c0.2,2.5-0.2,4.7-1.2,6.6c-1.2,2.2-3,3.4-5.3,3.6c-2.6,0.2-5.3-1-7.9-3.7c-9.3-9.5-16.7-23.7-22.1-42.6
c-6.5,12.8-11.3,22.4-14.4,28.8c-5.9,11.3-10.9,17.1-15.1,17.4c-2.7,0.2-5-2.1-7-6.9c-5.1-13.1-10.6-38.4-16.5-75.9
C148.3,356,148.8,353.7,150.2,351.9z"/>
<path fill="#FFFFFF" d="M365.2,367.6c-3.6-6.3-8.9-10.1-16-11.6c-1.9-0.4-3.7-0.6-5.4-0.6c-9.6,0-17.4,5-23.5,15
c-5.2,8.5-7.8,17.9-7.8,28.2c0,7.7,1.6,14.3,4.8,19.8c3.6,6.3,8.9,10.1,16,11.6c1.9,0.4,3.7,0.6,5.4,0.6c9.7,0,17.5-5,23.5-15
c5.2-8.6,7.8-18,7.8-28.3C370,379.5,368.4,373,365.2,367.6L365.2,367.6z M352.6,395.3c-1.4,6.6-3.9,11.5-7.6,14.8
c-2.9,2.6-5.6,3.7-8.1,3.2c-2.4-0.5-4.4-2.6-5.9-6.5c-1.2-3.1-1.8-6.2-1.8-9.1c0-2.5,0.2-5,0.7-7.3c0.9-4.1,2.6-8.1,5.3-11.9
c3.3-4.9,6.8-6.9,10.4-6.2c2.4,0.5,4.4,2.6,5.9,6.5c1.2,3.1,1.8,6.2,1.8,9.1C353.3,390.5,353,393,352.6,395.3L352.6,395.3z"/>
<path fill="#FFFFFF" d="M302.5,367.6c-3.6-6.3-9-10.1-16-11.6c-1.9-0.4-3.7-0.6-5.4-0.6c-9.6,0-17.4,5-23.5,15
c-5.2,8.5-7.8,17.9-7.8,28.2c0,7.7,1.6,14.3,4.8,19.8c3.6,6.3,8.9,10.1,16,11.6c1.9,0.4,3.7,0.6,5.4,0.6c9.7,0,17.5-5,23.5-15
c5.2-8.6,7.8-18,7.8-28.3C307.3,379.5,305.7,373,302.5,367.6L302.5,367.6z M289.9,395.3c-1.4,6.6-3.9,11.5-7.6,14.8
c-2.9,2.6-5.6,3.7-8.1,3.2c-2.4-0.5-4.4-2.6-5.9-6.5c-1.2-3.1-1.8-6.2-1.8-9.1c0-2.5,0.2-5,0.7-7.3c0.9-4.1,2.6-8.1,5.3-11.9
c3.3-4.9,6.8-6.9,10.4-6.2c2.4,0.5,4.4,2.6,5.9,6.5c1.2,3.1,1.8,6.2,1.8,9.1C290.6,390.5,290.4,393,289.9,395.3L289.9,395.3z"/>
<g>
<g>
<path d="M407.9,366.7c-6.7,6.6-10,15-10,25.2c0,10.9,3.3,19.8,9.9,26.5c6.6,6.7,15.2,10.1,25.9,10.1c3.1,0,6.6-0.5,10.4-1.6
v-16.2c-3.5,1-6.5,1.5-9.1,1.5c-5.3,0-9.5-1.8-12.7-5.3c-3.2-3.6-4.8-8.4-4.8-14.5c0-5.7,1.6-10.4,4.7-14
c3.2-3.7,7.1-5.5,11.9-5.5c3.1,0,6.4,0.5,10,1.5v-16.2c-3.3-0.9-7-1.3-10.9-1.3C423,356.8,414.6,360.1,407.9,366.7z M477.3,356.8
c-9.2,0-16.4,3.1-21.6,9.2c-5.2,6.1-7.7,14.7-7.7,25.7c0,11.9,2.6,21,7.7,27.3c5.1,6.3,12.6,9.5,22.4,9.5
c9.5,0,16.8-3.2,21.9-9.5c5.1-6.3,7.7-15.2,7.7-26.6c0-11.4-2.6-20.2-7.8-26.4C494.6,359.9,487.1,356.8,477.3,356.8z
M485.2,408.8c-1.8,2.8-4.5,4.2-7.9,4.2c-3.2,0-5.6-1.4-7.3-4.2c-1.7-2.8-2.5-8.4-2.5-16.9c0-13.1,3.3-19.6,10-19.6
c7,0,10.6,6.6,10.6,19.9C488,400.4,487,406,485.2,408.8z M557.1,358.7l-3.6,15.3c-0.9,3.9-1.8,7.9-2.6,12l-2,10.6
c-1.9-10.6-4.5-23.2-7.8-37.9h-23.2l-8.7,68.1h17.4l4.7-46.9l11.9,46.9h12.4L567,380l4.9,46.8h18.2l-9.2-68.1H557.1z
M640.4,358.7l-3.6,15.3c-0.9,3.9-1.8,7.9-2.6,12l-2,10.6c-1.9-10.6-4.5-23.2-7.8-37.9h-23.2l-8.7,68.1h17.4l4.7-46.9l11.9,46.9
h12.4l11.3-46.8l4.9,46.8h18.2l-9.2-68.1H640.4z M697,399.9h16.3v-14.1H697v-12.5h18.8v-14.5h-37.2v68.1h37.3v-14.5H697V399.9z
M767.7,389.1c1.9-3.1,2.9-6.3,2.9-9.6c0-6.4-2.5-11.5-7.5-15.2c-5-3.7-11.9-5.6-20.5-5.6h-21.4v68.1h18.4v-31h0.3l14.9,31h19.4
l-14.7-30.7C763,394.5,765.8,392.2,767.7,389.1z M739.5,388v-16.2c4.4,0.1,7.5,0.8,9.4,2.2c1.9,1.4,2.8,3.6,2.8,6.8
C751.7,385.5,747.6,387.9,739.5,388z M781.4,366.7c-6.7,6.6-10,15-10,25.2c0,10.9,3.3,19.8,9.9,26.5c6.6,6.7,15.2,10.1,25.9,10.1
c3.1,0,6.6-0.5,10.4-1.6v-16.2c-3.5,1-6.5,1.5-9.1,1.5c-5.3,0-9.5-1.8-12.7-5.3c-3.2-3.6-4.8-8.4-4.8-14.5c0-5.7,1.6-10.4,4.7-14
c3.2-3.7,7.1-5.5,11.9-5.5c3.1,0,6.4,0.5,10,1.5v-16.2c-3.3-0.9-7-1.3-10.9-1.3C796.6,356.8,788.1,360.1,781.4,366.7z
M841.1,412.2v-12.4h16.3v-14.1h-16.3v-12.5H860v-14.5h-37.2v68.1h37.3v-14.5H841.1z"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -19,9 +19,10 @@ jQuery( function ( $ ) {
window.onbeforeunload = '';
});
$( 'a.edit_address' ).click( this.edit_address );
$( 'button.billing-same-as-shipping' ).on( 'click', this.copy_billing_to_shipping );
$( 'button.load_customer_billing' ).on( 'click', this.load_billing );
$( 'button.load_customer_shipping' ).on( 'click', this.load_shipping );
$( 'a.billing-same-as-shipping' ).on( 'click', this.copy_billing_to_shipping );
$( 'a.load_customer_billing' ).on( 'click', this.load_billing );
$( 'a.load_customer_shipping' ).on( 'click', this.load_shipping );
$( '#customer_user' ).on( 'change', this.change_customer_user );
},
change_country: function( e, stickValue ) {
@ -37,7 +38,7 @@ jQuery( function ( $ ) {
var $this = $( this ),
country = $this.val(),
$state = $this.parents( '.edit_address' ).find( ':input.js_field-state' ),
$state = $this.parents( 'div.edit_address' ).find( ':input.js_field-state' ),
$parent = $state.parent(),
input_name = $state.attr( 'name' ),
input_id = $state.attr( 'id' ),
@ -77,7 +78,7 @@ jQuery( function ( $ ) {
// Here we will find if state value on a select has changed and stick it to the country data
var $this = $( this ),
state = $this.val(),
$country = $this.parents( '.edit_address' ).find( ':input.js_field-country' ),
$country = $this.parents( 'div.edit_address' ).find( ':input.js_field-country' ),
country = $country.val();
$country.data( 'woocommerce.stickState-' + country, state );
@ -97,12 +98,21 @@ jQuery( function ( $ ) {
edit_address: function( e ) {
e.preventDefault();
$( this ).hide();
$( this ).parent().find( 'a:not(.edit_address)' ).show();
$( this ).closest( '.order_data_column' ).find( 'div.address' ).hide();
$( this ).closest( '.order_data_column' ).find( 'div.edit_address' ).show();
},
load_billing: function() {
if ( window.confirm( woocommerce_admin_meta_boxes.load_billing ) ) {
change_customer_user: function( e ) {
if ( ! $( '#_billing_country' ).val() ) {
$( 'a.edit_address' ).click();
wc_meta_boxes_order.load_billing( true );
wc_meta_boxes_order.load_shipping( true );
}
},
load_billing: function( force ) {
if ( true === force || window.confirm( woocommerce_admin_meta_boxes.load_billing ) ) {
// Get user ID to load data for
var user_id = $( '#customer_user' ).val();
@ -119,7 +129,7 @@ jQuery( function ( $ ) {
security: woocommerce_admin_meta_boxes.get_customer_details_nonce
};
$( this ).closest( '.edit_address' ).block({
$( this ).closest( 'div.edit_address' ).block({
message: null,
overlayCSS: {
background: '#fff',
@ -148,15 +158,15 @@ jQuery( function ( $ ) {
$( 'input#_billing_phone' ).val( info.billing_phone ).change();
}
$( '.edit_address' ).unblock();
$( 'div.edit_address' ).unblock();
}
});
}
return false;
},
load_shipping: function() {
if ( window.confirm( woocommerce_admin_meta_boxes.load_shipping ) ) {
load_shipping: function( force ) {
if ( true === force || window.confirm( woocommerce_admin_meta_boxes.load_shipping ) ) {
// Get user ID to load data for
var user_id = $( '#customer_user' ).val();
@ -173,7 +183,7 @@ jQuery( function ( $ ) {
security: woocommerce_admin_meta_boxes.get_customer_details_nonce
};
$( this ).closest( '.edit_address' ).block({
$( this ).closest( 'div.edit_address' ).block({
message: null,
overlayCSS: {
background: '#fff',
@ -200,7 +210,7 @@ jQuery( function ( $ ) {
$( '#_shipping_state' ).val( info.shipping_state ).change();
}
$( '.edit_address' ).unblock();
$( 'div.edit_address' ).unblock();
}
});
}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
jQuery(window).load(function(){jQuery("select#woocommerce_allowed_countries, select#woocommerce_ship_to_countries").change(function(){"specific"==jQuery(this).val()?jQuery(this).parent().parent().next("tr").show():jQuery(this).parent().parent().next("tr").hide()}).change(),jQuery(".colorpick").iris({change:function(a,b){jQuery(this).css({backgroundColor:b.color.toString()})},hide:!0,border:!0}).each(function(){jQuery(this).css({backgroundColor:jQuery(this).val()})}).click(function(){jQuery(".iris-picker").hide(),jQuery(this).closest(".color_box, td").find(".iris-picker").show()}),jQuery("body").click(function(){jQuery(".iris-picker").hide()}),jQuery(".color_box, .colorpick").click(function(a){a.stopPropagation()}),jQuery(function(){var a=!1;jQuery("input, textarea, select, checkbox").change(function(){a=!0}),jQuery(".woo-nav-tab-wrapper a").click(function(){window.onbeforeunload=a?function(){return woocommerce_settings_params.i18n_nav_warning}:""}),jQuery(".submit input").click(function(){window.onbeforeunload=""})}),jQuery("table.wc_gateways tbody, table.wc_shipping tbody").sortable({items:"tr",cursor:"move",axis:"y",handle:"td.sort",scrollSensitivity:40,helper:function(a,b){return b.children().each(function(){jQuery(this).width(jQuery(this).width())}),b.css("left","0"),b},start:function(a,b){b.item.css("background-color","#f6f6f6")},stop:function(a,b){b.item.removeAttr("style")}}),jQuery(".woocommerce").on("click",".select_all",function(){return jQuery(this).closest("td").find("select option").attr("selected","selected"),jQuery(this).closest("td").find("select").trigger("change"),!1}),jQuery(".woocommerce").on("click",".select_none",function(){return jQuery(this).closest("td").find("select option").removeAttr("selected"),jQuery(this).closest("td").find("select").trigger("change"),!1})});
jQuery(window).load(function(){jQuery("select#woocommerce_allowed_countries, select#woocommerce_ship_to_countries").change(function(){"specific"===jQuery(this).val()?jQuery(this).parent().parent().next("tr").show():jQuery(this).parent().parent().next("tr").hide()}).change(),jQuery(".colorpick").iris({change:function(a,b){jQuery(this).css({backgroundColor:b.color.toString()})},hide:!0,border:!0}).each(function(){jQuery(this).css({backgroundColor:jQuery(this).val()})}).click(function(){jQuery(".iris-picker").hide(),jQuery(this).closest(".color_box, td").find(".iris-picker").show()}),jQuery("body").click(function(){jQuery(".iris-picker").hide()}),jQuery(".color_box, .colorpick").click(function(a){a.stopPropagation()}),jQuery(function(){var a=!1;jQuery("input, textarea, select, checkbox").change(function(){a=!0}),jQuery(".woo-nav-tab-wrapper a").click(function(){window.onbeforeunload=a?function(){return woocommerce_settings_params.i18n_nav_warning}:""}),jQuery(".submit input").click(function(){window.onbeforeunload=""})}),jQuery("table.wc_gateways tbody, table.wc_shipping tbody").sortable({items:"tr",cursor:"move",axis:"y",handle:"td.sort",scrollSensitivity:40,helper:function(a,b){return b.children().each(function(){jQuery(this).width(jQuery(this).width())}),b.css("left","0"),b},start:function(a,b){b.item.css("background-color","#f6f6f6")},stop:function(a,b){b.item.removeAttr("style")}}),jQuery(".woocommerce").on("click",".select_all",function(){return jQuery(this).closest("td").find("select option").attr("selected","selected"),jQuery(this).closest("td").find("select").trigger("change"),!1}),jQuery(".woocommerce").on("click",".select_none",function(){return jQuery(this).closest("td").find("select option").removeAttr("selected"),jQuery(this).closest("td").find("select").trigger("change"),!1})});

View File

@ -219,12 +219,6 @@ jQuery( function ( $ ) {
}
}).change();
// Generate QR Code
if ( typeof woocommerce_admin !== 'undefined' && typeof woocommerce_admin.qrcode_key !== 'undefined' ) {
$( '#qrcode_small' ).qrcode({
text: woocommerce_admin.qrcode_key,
width: 90,
height: 90
});
}
// Attribute term table
$( 'table.attributes-table tbody tr:nth-child(odd)' ).addClass( 'alternate' );
});

File diff suppressed because one or more lines are too long

View File

@ -322,20 +322,9 @@ jQuery( function( $ ) {
type: 'POST',
url: wc_checkout_params.checkout_url,
data: $form.serialize(),
success: function( code ) {
var result = '';
dataType: 'json',
success: function( result ) {
try {
// Get the valid JSON only from the returned string
if ( code.indexOf( '<!--WC_START-->' ) >= 0 )
code = code.split( '<!--WC_START-->' )[1]; // Strip off before after WC_START
if ( code.indexOf( '<!--WC_END-->' ) >= 0 )
code = code.split( '<!--WC_END-->' )[0]; // Strip off anything after WC_END
// Parse
result = $.parseJSON( code );
if ( result.result === 'success' ) {
if ( result.redirect.indexOf( "https://" ) != -1 || result.redirect.indexOf( "http://" ) != -1 ) {
window.location = result.redirect;
@ -347,50 +336,43 @@ jQuery( function( $ ) {
} else {
throw 'Invalid response';
}
}
catch( err ) {
} catch( err ) {
// Reload page
if ( result.reload === 'true' ) {
window.location.reload();
return;
}
// Remove old errors
$( '.woocommerce-error, .woocommerce-message' ).remove();
// Add new errors
if ( result.messages ) {
$form.prepend( result.messages );
} else {
$form.prepend( code );
}
// Cancel processing
$form.removeClass( 'processing' ).unblock();
// Lose focus for all fields
$form.find( '.input-text, select' ).blur();
// Scroll to top
$( 'html, body' ).animate({
scrollTop: ( $( 'form.checkout' ).offset().top - 100 )
}, 1000 );
// Trigger update in case we need a fresh nonce
if ( result.refresh === 'true' ) {
$( document.body ).trigger( 'update_checkout' );
}
$( document.body ).trigger( 'checkout_error' );
// Add new errors
if ( result.messages ) {
wc_checkout_form.submit_error( result.messages );
} else {
wc_checkout_form.submit_error( '<div class="woocommerce-error">' + wc_checkout_params.i18n_checkout_error + '</div>' );
}
}
},
dataType: 'html'
error: function( jqXHR, textStatus, errorThrown ) {
wc_checkout_form.submit_error( '<div class="woocommerce-error">' + errorThrown + '</div>' );
}
});
}
return false;
},
submit_error: function( error_message ) {
$( '.woocommerce-error, .woocommerce-message' ).remove();
wc_checkout_form.$checkout_form.prepend( error_message );
wc_checkout_form.$checkout_form.removeClass( 'processing' ).unblock();
wc_checkout_form.$checkout_form.find( '.input-text, select' ).blur();
$( 'html, body' ).animate({
scrollTop: ( $( 'form.checkout' ).offset().top - 100 )
}, 1000 );
$( document.body ).trigger( 'checkout_error' );
}
};

File diff suppressed because one or more lines are too long

View File

@ -1,20 +1 @@
/*
* TipTip
* Copyright 2010 Drew Wilson
* www.drewwilson.com
* code.drewwilson.com/entry/tiptip-jquery-plugin
*
* Version 1.3 - Updated: Mar. 23, 2010
*
* This Plug-In will create a custom tooltip to replace the default
* browser tooltip. It is extremely lightweight and very smart in
* that it detects the edges of the browser window and will make sure
* the tooltip stays within the current window size. As a result the
* tooltip will adjust itself to be displayed above, below, to the left
* or to the right depending on what is necessary to stay within the
* browser window. It is completely customizable as well via CSS.
*
* This TipTip jQuery plug-in is dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/(function(e){e.fn.tipTip=function(t){var n={activation:"hover",keepAlive:!1,maxWidth:"200px",edgeOffset:3,defaultPosition:"bottom",delay:400,fadeIn:200,fadeOut:200,attribute:"title",content:!1,enter:function(){},exit:function(){}},r=e.extend(n,t);if(e("#tiptip_holder").length<=0){var i=e('<div id="tiptip_holder" style="max-width:'+r.maxWidth+';"></div>'),s=e('<div id="tiptip_content"></div>'),o=e('<div id="tiptip_arrow"></div>');e("body").append(i.html(s).prepend(o.html('<div id="tiptip_arrow_inner"></div>')))}else var i=e("#tiptip_holder"),s=e("#tiptip_content"),o=e("#tiptip_arrow");return this.each(function(){var t=e(this);if(r.content)var n=r.content;else var n=t.attr(r.attribute);if(n!=""){r.content||t.removeAttr(r.attribute);var u=!1;if(r.activation=="hover"){t.hover(function(){a()},function(){r.keepAlive||f()});r.keepAlive&&i.hover(function(){},function(){f()})}else if(r.activation=="focus")t.focus(function(){a()}).blur(function(){f()});else if(r.activation=="click"){t.click(function(){a();return!1}).hover(function(){},function(){r.keepAlive||f()});r.keepAlive&&i.hover(function(){},function(){f()})}function a(){r.enter.call(this);s.html(n);i.hide().removeAttr("class").css("margin","0");o.removeAttr("style");var a=parseInt(t.offset().top),f=parseInt(t.offset().left),l=parseInt(t.outerWidth()),c=parseInt(t.outerHeight()),h=i.outerWidth(),p=i.outerHeight(),d=Math.round((l-h)/2),v=Math.round((c-p)/2),m=Math.round(f+d),g=Math.round(a+c+r.edgeOffset),y="",b="",w=Math.round(h-12)/2;r.defaultPosition=="bottom"?y="_bottom":r.defaultPosition=="top"?y="_top":r.defaultPosition=="left"?y="_left":r.defaultPosition=="right"&&(y="_right");var E=d+f<parseInt(e(window).scrollLeft()),S=h+f>parseInt(e(window).width());if(E&&d<0||y=="_right"&&!S||y=="_left"&&f<h+r.edgeOffset+5){y="_right";b=Math.round(p-13)/2;w=-12;m=Math.round(f+l+r.edgeOffset);g=Math.round(a+v)}else if(S&&d<0||y=="_left"&&!E){y="_left";b=Math.round(p-13)/2;w=Math.round(h);m=Math.round(f-(h+r.edgeOffset+5));g=Math.round(a+v)}var x=a+c+r.edgeOffset+p+8>parseInt(e(window).height()+e(window).scrollTop()),T=a+c-(r.edgeOffset+p+8)<0;if(x||y=="_bottom"&&x||y=="_top"&&!T){y=="_top"||y=="_bottom"?y="_top":y+="_top";b=p;g=Math.round(a-(p+5+r.edgeOffset))}else if(T|(y=="_top"&&T)||y=="_bottom"&&!x){y=="_top"||y=="_bottom"?y="_bottom":y+="_bottom";b=-12;g=Math.round(a+c+r.edgeOffset)}if(y=="_right_top"||y=="_left_top")g+=5;else if(y=="_right_bottom"||y=="_left_bottom")g-=5;if(y=="_left_top"||y=="_left_bottom")m+=5;o.css({"margin-left":w+"px","margin-top":b+"px"});i.css({"margin-left":m+"px","margin-top":g+"px"}).attr("class","tip"+y);u&&clearTimeout(u);u=setTimeout(function(){i.stop(!0,!0).fadeIn(r.fadeIn)},r.delay)}function f(){r.exit.call(this);u&&clearTimeout(u);i.fadeOut(r.fadeOut)}}})}})(jQuery);
!function(a){a.fn.tipTip=function(b){var c={activation:"hover",keepAlive:!1,maxWidth:"200px",edgeOffset:3,defaultPosition:"bottom",delay:400,fadeIn:200,fadeOut:200,attribute:"title",content:!1,enter:function(){},exit:function(){}},d=a.extend(c,b);if(a("#tiptip_holder").length<=0){var e=a('<div id="tiptip_holder" style="max-width:'+d.maxWidth+';"></div>'),f=a('<div id="tiptip_content"></div>'),g=a('<div id="tiptip_arrow"></div>');a("body").append(e.html(f).prepend(g.html('<div id="tiptip_arrow_inner"></div>')))}else var e=a("#tiptip_holder"),f=a("#tiptip_content"),g=a("#tiptip_arrow");return this.each(function(){function b(){d.enter.call(this),f.html(i),e.hide().removeAttr("class").css("margin","0"),g.removeAttr("style");var b=parseInt(h.offset().top),c=parseInt(h.offset().left),k=parseInt(h.outerWidth()),l=parseInt(h.outerHeight()),m=e.outerWidth(),n=e.outerHeight(),o=Math.round((k-m)/2),p=Math.round((l-n)/2),q=Math.round(c+o),r=Math.round(b+l+d.edgeOffset),s="",t="",u=Math.round(m-12)/2;"bottom"==d.defaultPosition?s="_bottom":"top"==d.defaultPosition?s="_top":"left"==d.defaultPosition?s="_left":"right"==d.defaultPosition&&(s="_right");var v=o+c<parseInt(a(window).scrollLeft()),w=m+c>parseInt(a(window).width());v&&0>o||"_right"==s&&!w||"_left"==s&&c<m+d.edgeOffset+5?(s="_right",t=Math.round(n-13)/2,u=-12,q=Math.round(c+k+d.edgeOffset),r=Math.round(b+p)):(w&&0>o||"_left"==s&&!v)&&(s="_left",t=Math.round(n-13)/2,u=Math.round(m),q=Math.round(c-(m+d.edgeOffset+5)),r=Math.round(b+p));var x=b+l+d.edgeOffset+n+8>parseInt(a(window).height()+a(window).scrollTop()),y=b+l-(d.edgeOffset+n+8)<0;x||"_bottom"==s&&x||"_top"==s&&!y?("_top"==s||"_bottom"==s?s="_top":s+="_top",t=n,r=Math.round(b-(n+5+d.edgeOffset))):(y|("_top"==s&&y)||"_bottom"==s&&!x)&&("_top"==s||"_bottom"==s?s="_bottom":s+="_bottom",t=-12,r=Math.round(b+l+d.edgeOffset)),"_right_top"==s||"_left_top"==s?r+=5:("_right_bottom"==s||"_left_bottom"==s)&&(r-=5),("_left_top"==s||"_left_bottom"==s)&&(q+=5),g.css({"margin-left":u+"px","margin-top":t+"px"}),e.css({"margin-left":q+"px","margin-top":r+"px"}).attr("class","tip"+s),j&&clearTimeout(j),j=setTimeout(function(){e.stop(!0,!0).fadeIn(d.fadeIn)},d.delay)}function c(){d.exit.call(this),j&&clearTimeout(j),e.fadeOut(d.fadeOut)}var h=a(this);if(d.content)var i=d.content;else var i=h.attr(d.attribute);if(""!=i){d.content||h.removeAttr(d.attribute);var j=!1;"hover"==d.activation?(h.hover(function(){b()},function(){d.keepAlive||c()}),d.keepAlive&&e.hover(function(){},function(){c()})):"focus"==d.activation?h.focus(function(){b()}).blur(function(){c()}):"click"==d.activation&&(h.click(function(){return b(),!1}).hover(function(){},function(){d.keepAlive||c()}),d.keepAlive&&e.hover(function(){},function(){c()}))}})}}(jQuery);

View File

@ -1 +1 @@
(function(e){e(function(){e("a.zoom").prettyPhoto({hook:"data-rel",social_tools:!1,theme:"pp_woocommerce",horizontal_padding:20,opacity:.8,deeplinking:!1});e("a[data-rel^='prettyPhoto']").prettyPhoto({hook:"data-rel",social_tools:!1,theme:"pp_woocommerce",horizontal_padding:20,opacity:.8,deeplinking:!1})})})(jQuery);
!function(a){a(function(){a("a.zoom").prettyPhoto({hook:"data-rel",social_tools:!1,theme:"pp_woocommerce",horizontal_padding:20,opacity:.8,deeplinking:!1}),a("a[data-rel^='prettyPhoto']").prettyPhoto({hook:"data-rel",social_tools:!1,theme:"pp_woocommerce",horizontal_padding:20,opacity:.8,deeplinking:!1})})}(jQuery);

8
assets/js/prettyPhoto/jquery.prettyPhoto.js Normal file → Executable file
View File

@ -2,10 +2,10 @@
Class: prettyPhoto
Use: Lightbox clone for jQuery
Author: Stephane Caron (http://www.no-margin-for-errors.com)
Version: 3.1.5
Version: 3.1.6
------------------------------------------------------------------------- */
(function($) {
$.prettyPhoto = {version: '3.1.5'};
$.prettyPhoto = {version: '3.1.6'};
$.fn.prettyPhoto = function(pp_settings) {
pp_settings = jQuery.extend({
@ -751,7 +751,7 @@
settings.markup = settings.markup.replace('{pp_social}','');
$(document.body).append(settings.markup); // Inject the markup
$('body').append(settings.markup); // Inject the markup
$pp_pic_holder = $('.pp_pic_holder') , $ppt = $('.ppt'), $pp_overlay = $('div.pp_overlay'); // Set my global selectors
@ -885,7 +885,7 @@
function getHashtag(){
var url = location.href;
hashtag = (url.indexOf('#prettyPhoto') !== -1) ? decodeURI(url.substring(url.indexOf('#prettyPhoto')+1,url.length)) : false;
if(hashtag){ hashtag = hashtag.replace(/<|>/g,''); }
return hashtag;
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -10,7 +10,7 @@
global $states;
$states['IN'] = array(
'AP' => __( 'Andra Pradesh', 'woocommerce' ),
'AP' => __( 'Andhra Pradesh', 'woocommerce' ),
'AR' => __( 'Arunachal Pradesh', 'woocommerce' ),
'AS' => __( 'Assam', 'woocommerce' ),
'BR' => __( 'Bihar', 'woocommerce' ),

View File

@ -15,6 +15,7 @@ $states['NZ'] = array(
'WA' => __( 'Waikato', 'woocommerce' ),
'BP' => __( 'Bay of Plenty', 'woocommerce' ),
'TK' => __( 'Taranaki', 'woocommerce' ),
'GI' => __( 'Gisborne', 'woocommerce' ),
'HB' => __( 'Hawke&rsquo;s Bay', 'woocommerce' ),
'MW' => __( 'Manawatu-Wanganui', 'woocommerce' ),
'WE' => __( 'Wellington', 'woocommerce' ),
@ -25,6 +26,5 @@ $states['NZ'] = array(
'CT' => __( 'Canterbury', 'woocommerce' ),
'OT' => __( 'Otago', 'woocommerce' ),
'SL' => __( 'Southland', 'woocommerce'),
'GI' => __( 'Gisborne', 'woocommerce' ),
);

94
i18n/states/PH.php Normal file
View File

@ -0,0 +1,94 @@
<?php
/**
* Philippines Provinces
*
* @category i18n
* @package WooCommerce/i18n
* @version 2.4.0
*/
global $states;
$states['PH'] = array(
'ABR' => __( 'Abra', 'woocommerce' ),
'AGN' => __( 'Agusan del Norte', 'woocommerce' ),
'AGS' => __( 'Agusan del Sur', 'woocommerce' ),
'AKL' => __( 'Aklan', 'woocommerce' ),
'ALB' => __( 'Albay', 'woocommerce' ),
'ANT' => __( 'Antique', 'woocommerce' ),
'APA' => __( 'Apayao', 'woocommerce' ),
'AUR' => __( 'Aurora', 'woocommerce' ),
'BAS' => __( 'Basilan', 'woocommerce' ),
'BAN' => __( 'Bataan', 'woocommerce' ),
'BTN' => __( 'Batanes', 'woocommerce' ),
'BTG' => __( 'Batangas', 'woocommerce' ),
'BEN' => __( 'Benguet', 'woocommerce' ),
'BIL' => __( 'Biliran', 'woocommerce' ),
'BOH' => __( 'Bohol', 'woocommerce' ),
'BUK' => __( 'Bukidnon', 'woocommerce' ),
'BUL' => __( 'Bulacan', 'woocommerce' ),
'CAG' => __( 'Cagayan', 'woocommerce' ),
'CAN' => __( 'Camarines Norte', 'woocommerce' ),
'CAS' => __( 'Camarines Sur', 'woocommerce' ),
'CAM' => __( 'Camiguin', 'woocommerce' ),
'CAP' => __( 'Capiz', 'woocommerce' ),
'CAT' => __( 'Catanduanes', 'woocommerce' ),
'CAV' => __( 'Cavite', 'woocommerce' ),
'CEB' => __( 'Cebu', 'woocommerce' ),
'COM' => __( 'Compostela Valley', 'woocommerce' ),
'NCO' => __( 'Cotabato', 'woocommerce' ),
'DAV' => __( 'Davao del Norte', 'woocommerce' ),
'DAS' => __( 'Davao del Sur', 'woocommerce' ),
'DAC' => __( 'Davao Occidental', 'woocommerce' ), // TODO: Needs to be updated when ISO code is assigned
'DAO' => __( 'Davao Oriental', 'woocommerce' ),
'DIN' => __( 'Dinagat Islands', 'woocommerce' ),
'EAS' => __( 'Eastern Samar', 'woocommerce' ),
'GUI' => __( 'Guimaras', 'woocommerce' ),
'IFU' => __( 'Ifugao', 'woocommerce' ),
'ILN' => __( 'Ilocos Norte', 'woocommerce' ),
'ILS' => __( 'Ilocos Sur', 'woocommerce' ),
'ILI' => __( 'Iloilo', 'woocommerce' ),
'ISA' => __( 'Isabela', 'woocommerce' ),
'KAL' => __( 'Kalinga', 'woocommerce' ),
'LUN' => __( 'La Union', 'woocommerce' ),
'LAG' => __( 'Laguna', 'woocommerce' ),
'LAN' => __( 'Lanao del Norte', 'woocommerce' ),
'LAS' => __( 'Lanao del Sur', 'woocommerce' ),
'LEY' => __( 'Leyte', 'woocommerce' ),
'MAG' => __( 'Maguindanao', 'woocommerce' ),
'MAD' => __( 'Marinduque', 'woocommerce' ),
'MAS' => __( 'Masbate', 'woocommerce' ),
'MSC' => __( 'Misamis Occidental', 'woocommerce' ),
'MSR' => __( 'Misamis Oriental', 'woocommerce' ),
'MOU' => __( 'Mountain Province', 'woocommerce' ),
'NEC' => __( 'Negros Occidental', 'woocommerce' ),
'NER' => __( 'Negros Oriental', 'woocommerce' ),
'NSA' => __( 'Northern Samar', 'woocommerce' ),
'NUE' => __( 'Nueva Ecija', 'woocommerce' ),
'NUV' => __( 'Nueva Vizcaya', 'woocommerce' ),
'MDC' => __( 'Occidental Mindoro', 'woocommerce' ),
'MDR' => __( 'Oriental Mindoro', 'woocommerce' ),
'PLW' => __( 'Palawan', 'woocommerce' ),
'PAM' => __( 'Pampanga', 'woocommerce' ),
'PAN' => __( 'Pangasinan', 'woocommerce' ),
'QUE' => __( 'Quezon', 'woocommerce' ),
'QUI' => __( 'Quirino', 'woocommerce' ),
'RIZ' => __( 'Rizal', 'woocommerce' ),
'ROM' => __( 'Romblon', 'woocommerce' ),
'WSA' => __( 'Samar', 'woocommerce' ),
'SAR' => __( 'Sarangani', 'woocommerce' ),
'SIQ' => __( 'Siquijor', 'woocommerce' ),
'SOR' => __( 'Sorsogon', 'woocommerce' ),
'SCO' => __( 'South Cotabato', 'woocommerce' ),
'SLE' => __( 'Southern Leyte', 'woocommerce' ),
'SUK' => __( 'Sultan Kudarat', 'woocommerce' ),
'SLU' => __( 'Sulu', 'woocommerce' ),
'SUN' => __( 'Surigao del Norte', 'woocommerce' ),
'SUR' => __( 'Surigao del Sur', 'woocommerce' ),
'TAR' => __( 'Tarlac', 'woocommerce' ),
'TAW' => __( 'Tawi-Tawi', 'woocommerce' ),
'ZMB' => __( 'Zambales', 'woocommerce' ),
'ZAN' => __( 'Zamboanga del Norte', 'woocommerce' ),
'ZAS' => __( 'Zamboanga del Sur', 'woocommerce' ),
'ZSI' => __( 'Zamboanga Sibugay', 'woocommerce' ),
'00' => __( 'Metro Manila', 'woocommerce' ),
);

View File

@ -1050,28 +1050,33 @@ class WC_Product {
* @return int
*/
public function get_rating_count( $value = null ) {
$value = intval( $value );
$value_suffix = $value ? '_' . $value : '';
$transient_name = 'wc_rating_count_' . $this->id . $value_suffix . WC_Cache_Helper::get_transient_version( 'product' );
if ( false === ( $count = get_transient( $transient_name ) ) ) {
$transient_name = 'wc_rating_count_' . $this->id . WC_Cache_Helper::get_transient_version( 'product' );
if ( ! is_array( $counts = get_transient( $transient_name ) ) ) {
global $wpdb;
$where_meta_value = $value ? $wpdb->prepare( " AND meta_value = %d", $value ) : " AND meta_value > 0";
$count = $wpdb->get_var( $wpdb->prepare("
SELECT COUNT(meta_value) FROM $wpdb->commentmeta
$counts = array();
$raw_counts = $wpdb->get_results( $wpdb->prepare("
SELECT meta_value, COUNT( * ) as meta_value_count FROM $wpdb->commentmeta
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
WHERE meta_key = 'rating'
AND comment_post_ID = %d
AND comment_approved = '1'
", $this->id ) . $where_meta_value );
AND meta_value > 0
GROUP BY meta_value
", $this->id ) );
set_transient( $transient_name, $count, DAY_IN_SECONDS * 30 );
foreach ( $raw_counts as $count ) {
$counts[ $count->meta_value ] = $count->meta_value_count;
}
set_transient( $transient_name, $counts, DAY_IN_SECONDS * 30 );
}
return $count;
if ( is_null( $value ) ) {
return array_sum( $counts );
} else {
return isset( $counts[ $value ] ) ? $counts[ $value ] : 0;
}
}
/**
@ -1221,25 +1226,33 @@ class WC_Product {
* @return array Array of post IDs
*/
public function get_related( $limit = 5 ) {
global $wpdb;
$transient_name = 'wc_related_' . $limit . '_' . $this->id . WC_Cache_Helper::get_transient_version( 'product' );
// Related products are found from category and tag
$tags_array = $this->get_related_terms( 'product_tag' );
$cats_array = $this->get_related_terms( 'product_cat' );
if ( false === ( $related_posts = get_transient( $transient_name ) ) ) {
global $wpdb;
// Don't bother if none are set
if ( sizeof( $cats_array ) == 1 && sizeof( $tags_array ) == 1 ) {
return array();
// Related products are found from category and tag
$tags_array = $this->get_related_terms( 'product_tag' );
$cats_array = $this->get_related_terms( 'product_cat' );
// Don't bother if none are set
if ( sizeof( $cats_array ) == 1 && sizeof( $tags_array ) == 1 ) {
$related_posts = array();
} else {
// Sanitize
$exclude_ids = array_map( 'absint', array_merge( array( 0, $this->id ), $this->get_upsells() ) );
// Generate query
$query = $this->build_related_query( $cats_array, $tags_array, $exclude_ids, $limit );
// Get the posts
$related_posts = $wpdb->get_col( implode( ' ', $query ) );
}
set_transient( $transient_name, $related_posts, DAY_IN_SECONDS * 30 );
}
// Sanitize
$exclude_ids = array_map( 'absint', array_merge( array( 0, $this->id ), $this->get_upsells() ) );
// Generate query
$query = $this->build_related_query( $cats_array, $tags_array, $exclude_ids, $limit );
// Get the posts
$related_posts = $wpdb->get_col( implode( ' ', $query ) );
shuffle( $related_posts );
return $related_posts;
}
@ -1507,21 +1520,8 @@ class WC_Product {
$query['where'] .= " AND p.ID NOT IN ( " . implode( ',', $exclude_ids ) . " ) )";
}
$query = apply_filters( 'woocommerce_product_related_posts_query', $query, $this->id );
// How many rows total?
$max_related_posts_transient_name = 'wc_max_related_' . $this->id . WC_Cache_Helper::get_transient_version( 'product' );
if ( false === ( $max_related_posts = get_transient( $max_related_posts_transient_name ) ) ) {
$max_related_posts_query = $query;
$max_related_posts_query['fields'] = "SELECT COUNT(DISTINCT ID) FROM {$wpdb->posts} p";
$max_related_posts = absint( $wpdb->get_var( implode( ' ', apply_filters( 'woocommerce_product_max_related_posts_query', $max_related_posts_query, $this->id ) ) ) );
set_transient( $max_related_posts_transient_name, $max_related_posts, DAY_IN_SECONDS * 30 );
}
// Generate limit
$offset = $max_related_posts < $limit ? 0 : absint( rand( 0, $max_related_posts - $limit ) );
$query['limits'] = " LIMIT {$offset}, {$limit} ";
$query['limits'] = " LIMIT {$limit} ";
$query = apply_filters( 'woocommerce_product_related_posts_query', $query, $this->id );
return $query;
}

View File

@ -89,14 +89,13 @@ abstract class WC_Settings_API {
* Add an array of fields to be displayed
* on the gateway's settings screen.
*
* @since 1.0.0
* @since 1.0.0
* @return string
*/
public function init_form_fields() {}
/**
* Get the form fields after they are initialized
*
* @return array of options
*/
public function get_form_fields() {
@ -170,9 +169,9 @@ abstract class WC_Settings_API {
*
* Gets and option from the settings API, using defaults if necessary to prevent undefined notices.
*
* @param string $key
* @param mixed $empty_value
* @return mixed The value specified for the option or a default value for the option
* @param string $key
* @param mixed $empty_value
* @return mixed The value specified for the option or a default value for the option
*/
public function get_option( $key, $empty_value = null ) {
@ -193,10 +192,20 @@ abstract class WC_Settings_API {
return $this->settings[ $key ];
}
/**
* Prefix key for settings.
*
* @param mixed $key
* @return string
*/
public function get_field_key( $key ) {
return $this->plugin_id . $this->id . '_' . $key;
}
/**
* Decode values for settings.
*
* @param mixed $value
* @param mixed $value
* @return array
*/
public function format_settings( $value ) {
@ -208,9 +217,9 @@ abstract class WC_Settings_API {
*
* Generate the HTML for the fields on the "settings" screen.
*
* @param array $form_fields (default: array())
* @since 1.0.0
* @uses method_exists()
* @param array $form_fields (default: array())
* @since 1.0.0
* @uses method_exists()
* @return string the html for the settings
*/
public function generate_settings_html( $form_fields = array() ) {
@ -298,14 +307,14 @@ abstract class WC_Settings_API {
/**
* Generate Text Input HTML.
*
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @return string
*/
public function generate_text_html( $key, $data ) {
$field = $this->plugin_id . $this->id . '_' . $key;
$field = $this->get_field_key( $key );
$defaults = array(
'title' => '',
'disabled' => false,
@ -343,14 +352,14 @@ abstract class WC_Settings_API {
/**
* Generate Price Input HTML.
*
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @return string
*/
public function generate_price_html( $key, $data ) {
$field = $this->plugin_id . $this->id . '_' . $key;
$field = $this->get_field_key( $key );
$defaults = array(
'title' => '',
'disabled' => false,
@ -388,14 +397,14 @@ abstract class WC_Settings_API {
/**
* Generate Decimal Input HTML.
*
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @return string
*/
public function generate_decimal_html( $key, $data ) {
$field = $this->plugin_id . $this->id . '_' . $key;
$field = $this->get_field_key( $key );
$defaults = array(
'title' => '',
'disabled' => false,
@ -433,9 +442,9 @@ abstract class WC_Settings_API {
/**
* Generate Password Input HTML.
*
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @return string
*/
public function generate_password_html( $key, $data ) {
@ -446,13 +455,14 @@ abstract class WC_Settings_API {
/**
* Generate Color Picker Input HTML.
*
* @param mixed $key
* @param mixed $data
* @since 2.3.0
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @return string
*/
public function generate_color_html( $key, $data ) {
$field = $this->plugin_id . $this->id . '_' . $key;
$field = $this->get_field_key( $key );
$defaults = array(
'title' => '',
'disabled' => false,
@ -492,14 +502,14 @@ abstract class WC_Settings_API {
/**
* Generate Textarea HTML.
*
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @return string
*/
public function generate_textarea_html( $key, $data ) {
$field = $this->plugin_id . $this->id . '_' . $key;
$field = $this->get_field_key( $key );
$defaults = array(
'title' => '',
'disabled' => false,
@ -537,14 +547,14 @@ abstract class WC_Settings_API {
/**
* Generate Checkbox HTML.
*
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @return string
*/
public function generate_checkbox_html( $key, $data ) {
$field = $this->plugin_id . $this->id . '_' . $key;
$field = $this->get_field_key( $key );
$defaults = array(
'title' => '',
'label' => '',
@ -587,14 +597,14 @@ abstract class WC_Settings_API {
/**
* Generate Select HTML.
*
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @return string
*/
public function generate_select_html( $key, $data ) {
$field = $this->plugin_id . $this->id . '_' . $key;
$field = $this->get_field_key( $key );
$defaults = array(
'title' => '',
'disabled' => false,
@ -637,14 +647,14 @@ abstract class WC_Settings_API {
/**
* Generate Multiselect HTML.
*
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @return string
*/
public function generate_multiselect_html( $key, $data ) {
$field = $this->plugin_id . $this->id . '_' . $key;
$field = $this->get_field_key( $key );
$defaults = array(
'title' => '',
'disabled' => false,
@ -688,13 +698,14 @@ abstract class WC_Settings_API {
/**
* Generate Title HTML.
*
* @param mixed $key
* @param mixed $data
* @since 1.6.2
* @param mixed $key
* @param mixed $data
* @since 1.0.0
* @return string
*/
public function generate_title_html( $key, $data ) {
$field = $this->get_field_key( $key );
$defaults = array(
'title' => '',
'class' => ''
@ -705,7 +716,7 @@ abstract class WC_Settings_API {
ob_start();
?>
</table>
<h3 class="wc-settings-sub-title <?php echo esc_attr( $data['class'] ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></h3>
<h3 class="wc-settings-sub-title <?php echo esc_attr( $data['class'] ); ?>" id="<?php echo esc_attr( $field ); ?>"><?php echo wp_kses_post( $data['title'] ); ?></h3>
<?php if ( ! empty( $data['description'] ) ) : ?>
<p><?php echo wp_kses_post( $data['description'] ); ?></p>
<?php endif; ?>
@ -721,7 +732,7 @@ abstract class WC_Settings_API {
* Validate the data on the "Settings" form.
*
* @since 1.0.0
* @uses method_exists()
* @uses method_exists()
* @param array $form_fields (default: array())
*/
public function validate_settings_fields( $form_fields = array() ) {
@ -756,40 +767,21 @@ abstract class WC_Settings_API {
}
}
/**
* Validate Checkbox Field.
*
* If not set, return "no", otherwise return "yes".
*
* @param mixed $key
* @since 1.0.0
* @return string
*/
public function validate_checkbox_field( $key ) {
$status = 'no';
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) && ( 1 == $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
$status = 'yes';
}
return $status;
}
/**
* Validate Text Field.
*
* Make sure the data is escaped correctly, etc.
*
* @param mixed $key
* @param mixed $key
* @return string
*/
public function validate_text_field( $key ) {
$text = $this->get_option( $key );
$text = $this->get_option( $key );
$field = $this->get_field_key( $key );
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
$text = wp_kses_post( trim( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) );
if ( isset( $_POST[ $field ] ) ) {
$text = wp_kses_post( trim( stripslashes( $_POST[ $field ] ) ) );
}
return $text;
@ -800,17 +792,18 @@ abstract class WC_Settings_API {
*
* Make sure the data is escaped correctly, etc.
*
* @param mixed $key
* @param mixed $key
* @return string
*/
public function validate_price_field( $key ) {
$text = $this->get_option( $key );
$text = $this->get_option( $key );
$field = $this->get_field_key( $key );
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
if ( isset( $_POST[ $field ] ) ) {
if ( $_POST[ $this->plugin_id . $this->id . '_' . $key ] !== '' ) {
$text = wc_format_decimal( trim( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) );
if ( $_POST[ $field ] !== '' ) {
$text = wc_format_decimal( trim( stripslashes( $_POST[ $field ] ) ) );
} else {
$text = '';
}
@ -824,17 +817,18 @@ abstract class WC_Settings_API {
*
* Make sure the data is escaped correctly, etc.
*
* @param mixed $key
* @param mixed $key
* @return string
*/
public function validate_decimal_field( $key ) {
$text = $this->get_option( $key );
$text = $this->get_option( $key );
$field = $this->get_field_key( $key );
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
if ( isset( $_POST[ $field ] ) ) {
if ( $_POST[ $this->plugin_id . $this->id . '_' . $key ] !== '' ) {
$text = wc_format_decimal( trim( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) );
if ( $_POST[ $field ] !== '' ) {
$text = wc_format_decimal( trim( stripslashes( $_POST[ $field ] ) ) );
} else {
$text = '';
}
@ -848,16 +842,17 @@ abstract class WC_Settings_API {
*
* Make sure the data is escaped correctly, etc.
*
* @param mixed $key
* @since 1.0.0
* @param mixed $key
* @since 1.0.0
* @return string
*/
public function validate_password_field( $key ) {
$text = $this->get_option( $key );
$text = $this->get_option( $key );
$field = $this->get_field_key( $key );
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
$text = wc_clean( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) );
if ( isset( $_POST[ $field ] ) ) {
$text = wc_clean( stripslashes( $_POST[ $field ] ) );
}
return $text;
@ -868,17 +863,18 @@ abstract class WC_Settings_API {
*
* Make sure the data is escaped correctly, etc.
*
* @param mixed $key
* @since 1.0.0
* @param mixed $key
* @since 1.0.0
* @return string
*/
public function validate_textarea_field( $key ) {
$text = $this->get_option( $key );
$text = $this->get_option( $key );
$field = $this->get_field_key( $key );
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
if ( isset( $_POST[ $field ] ) ) {
$text = wp_kses( trim( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ),
$text = wp_kses( trim( stripslashes( $_POST[ $field ] ) ),
array_merge(
array(
'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true )
@ -891,21 +887,43 @@ abstract class WC_Settings_API {
return $text;
}
/**
* Validate Checkbox Field.
*
* If not set, return "no", otherwise return "yes".
*
* @param mixed $key
* @since 1.0.0
* @return string
*/
public function validate_checkbox_field( $key ) {
$status = 'no';
$field = $this->get_field_key( $key );
if ( isset( $_POST[ $field ] ) && ( 1 == $_POST[ $field ] ) ) {
$status = 'yes';
}
return $status;
}
/**
* Validate Select Field.
*
* Make sure the data is escaped correctly, etc.
*
* @param mixed $key
* @since 1.0.0
* @param mixed $key
* @since 1.0.0
* @return string
*/
public function validate_select_field( $key ) {
$value = $this->get_option( $key );
$field = $this->get_field_key( $key );
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
$value = wc_clean( stripslashes( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) );
if ( isset( $_POST[ $field ] ) ) {
$value = wc_clean( stripslashes( $_POST[ $field ] ) );
}
return $value;
@ -916,14 +934,16 @@ abstract class WC_Settings_API {
*
* Make sure the data is escaped correctly, etc.
*
* @param mixed $key
* @since 1.0.0
* @param mixed $key
* @since 1.0.0
* @return string
*/
public function validate_multiselect_field( $key ) {
if ( isset( $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) ) {
$value = array_map( 'wc_clean', array_map( 'stripslashes', (array) $_POST[ $this->plugin_id . $this->id . '_' . $key ] ) );
$field = $this->get_field_key( $key );
if ( isset( $_POST[ $field ] ) ) {
$value = array_map( 'wc_clean', array_map( 'stripslashes', (array) $_POST[ $field ] ) );
} else {
$value = '';
}

View File

@ -0,0 +1,194 @@
<?php
/**
* WooCommerce API Keys Table List
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WP_List_Table' ) ) {
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
}
class WC_Admin_API_Keys_Table_List extends WP_List_Table {
/**
* Initialize the webhook table list
*/
public function __construct() {
parent::__construct( array(
'singular' => __( 'key', 'woocommerce' ),
'plural' => __( 'keys', 'woocommerce' ),
'ajax' => false
) );
}
/**
* Get list columns
*
* @return array
*/
public function get_columns() {
return array(
'cb' => '<input type="checkbox" />',
'description' => __( 'Description', 'woocommerce' ),
'user' => __( 'User', 'woocommerce' ),
'permissions' => __( 'Permissions', 'woocommerce' )
);
}
/**
* Column cb
*
* @param array $key
* @return string
*/
public function column_cb( $key ) {
return sprintf( '<input type="checkbox" name="%1$s[]" value="%2$s" />', $this->_args['singular'], $key['key_id'] );
}
/**
* Return description column
*
* @param array $key
* @return string
*/
public function column_description( $key ) {
$url = admin_url( 'admin.php?page=wc-settings&tab=api&section=keys&edit-key=' . $key['key_id'] );
$output = '<strong>';
$output .= '<a href="' . esc_url( $url ) . '">';
if ( empty( $key['description'] ) ) {
$output .= esc_html__( 'API Key', 'woocommerce' );
} else {
$output .= esc_html( $key['description'] );
}
$output .= '</a>';
$output .= '</strong>';
// Get actions
$actions = array(
'id' => sprintf( __( 'ID: %d', 'woocommerce' ), $key['key_id'] ),
'edit' => '<a href="' . esc_url( $url ) . '">' . __( 'View/Edit', 'woocommerce' ) . '</a>',
'trash' => '<a class="submitdelete" title="' . esc_attr__( 'Revoke API Key', 'woocommerce' ) . '" href="' . esc_url( wp_nonce_url( add_query_arg( array( 'revoke-key' => $key['key_id'] ), admin_url( 'admin.php?page=wc-settings&tab=api&section=keys' ) ), 'revoke' ) ) . '">' . __( 'Revoke', 'woocommerce' ) . '</a>'
);
$row_actions = array();
foreach ( $actions as $action => $link ) {
$row_actions[] = '<span class="' . esc_attr( $action ) . '">' . $link . '</span>';
}
$output .= '<div class="row-actions">' . implode( ' | ', $row_actions ) . '</div>';
return $output;
}
/**
* Return user column
*
* @param array $key
* @return string
*/
public function column_user( $key ) {
$user = get_user_by( 'id', $key['user_id'] );
if ( ! $user ) {
return '';
}
$user_name = ! empty( $user->data->display_name ) ? $user->data->display_name : $user->data->user_login;
if ( current_user_can( 'edit_user' ) ) {
return '<a href="' . esc_url( add_query_arg( array( 'user_id' => $user->ID ), admin_url( 'user-edit.php' ) ) ) . '">' . esc_html( $user_name ) . '</a>';
}
return esc_html( $user_name );
}
/**
* Return permissions column
*
* @param array $key
* @return string
*/
public function column_permissions( $key ) {
$permission_key = $key['permissions'];
$permissions = array(
'read' => __( 'Read', 'woocommerce' ),
'write' => __( 'Write', 'woocommerce' ),
'read_write' => __( 'Read/Write', 'woocommerce' )
);
if ( isset( $permissions[ $permission_key ] ) ) {
return esc_html( $permissions[ $permission_key ] );
} else {
return '';
}
}
/**
* Get bulk actions
*
* @return array
*/
protected function get_bulk_actions() {
return array(
'revoke' => __( 'Revoke', 'woocommerce' )
);
}
/**
* Prepare table list items.
*/
public function prepare_items() {
global $wpdb;
$per_page = apply_filters( 'woocommerce_api_keys_settings_items_per_page', 10 );
$columns = $this->get_columns();
$hidden = array();
$sortable = $this->get_sortable_columns();
// Column headers
$this->_column_headers = array( $columns, $hidden, $sortable );
$current_page = $this->get_pagenum();
if ( 1 < $current_page ) {
$offset = $per_page * ( $current_page - 1 );
} else {
$offset = 0;
}
$search = '';
if ( ! empty( $_REQUEST['s'] ) ) {
$search = "AND description LIKE '" . $wpdb->esc_like( $_REQUEST['s'] ) . "'";
}
// Get the API keys
$keys = $wpdb->get_results( $wpdb->prepare( "
SELECT *
FROM {$wpdb->prefix}woocommerce_api_keys
WHERE 1 = 1
$search
LIMIT %d
OFFSET %d
", $per_page, $offset ), ARRAY_A );
$count = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}woocommerce_api_keys WHERE 1 = 1 $search" );
$this->items = $keys;
// Set the pagination
$this->set_pagination_args( array(
'total_items' => $count,
'per_page' => $per_page,
'total_pages' => $count / $per_page
) );
}
}

View File

@ -0,0 +1,303 @@
<?php
/**
* WooCommerce Admin API Keys Class.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* WC_Admin_API_Keys
*/
class WC_Admin_API_Keys {
/**
* Initialize the API Keys admin actions
*/
public function __construct() {
add_action( 'admin_init', array( $this, 'actions' ) );
}
/**
* Check if is API Keys settings page
*
* @return bool
*/
private function is_api_keys_settings_page() {
return isset( $_GET['page'] )
&& 'wc-settings' == $_GET['page']
&& isset( $_GET['tab'] )
&& 'api' == $_GET['tab']
&& isset( $_GET['section'] )
&& 'keys' == isset( $_GET['section'] );
}
/**
* Page output
*/
public static function page_output() {
// Hide the save button
$GLOBALS['hide_save_button'] = true;
if ( isset( $_GET['create-key'] ) || isset( $_GET['edit-key'] ) ) {
$key_id = isset( $_GET['edit-key'] ) ? absint( $_GET['edit-key'] ) : 0;
$key_data = self::get_key_data( $key_id );
include( 'settings/views/html-keys-edit.php' );
} else {
self::table_list_output();
}
}
/**
* 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>';
$keys_table_list = new WC_Admin_API_Keys_Table_List();
$keys_table_list->prepare_items();
echo '<input type="hidden" name="page" value="wc-settings" />';
echo '<input type="hidden" name="tab" value="api" />';
echo '<input type="hidden" name="section" value="keys" />';
$keys_table_list->views();
$keys_table_list->search_box( __( 'Search Key', 'woocommerce' ), 'key' );
$keys_table_list->display();
}
/**
* Get key data
*
* @param int $key_id
* @return array
*/
private static function get_key_data( $key_id ) {
global $wpdb;
$empty = array(
'key_id' => 0,
'user_id' => '',
'description' => '',
'permissions' => '',
'consumer_key' => '',
'consumer_secret' => ''
);
if ( 0 == $key_id ) {
return $empty;
}
$key = $wpdb->get_row( $wpdb->prepare( "
SELECT key_id, user_id, description, permissions, consumer_key, consumer_secret
FROM {$wpdb->prefix}woocommerce_api_keys
WHERE key_id = %d
", $key_id ), ARRAY_A );
if ( is_null( $key ) ) {
return $empty;
}
return $key;
}
/**
* API Keys admin actions
*/
public function actions() {
if ( $this->is_api_keys_settings_page() ) {
// Generate Key / Edit Key
if ( isset( $_POST['update_api_key'] ) && isset( $_POST['key_id'] ) ) {
$this->update_key();
}
// Revoke key
if ( isset( $_GET['revoke-key'] ) ) {
$this->revoke_key();
}
// Bulk actions
if ( isset( $_GET['action'] ) && isset( $_GET['key'] ) ) {
$this->bulk_actions();
}
}
}
/**
* Notices.
*/
public static function notices() {
if ( isset( $_GET['status'] ) ) {
switch ( intval( $_GET['status'] ) ) {
case 2 :
WC_Admin_Settings::add_message( __( 'API Key generated successfully.', 'woocommerce' ) );
break;
case 3 :
WC_Admin_Settings::add_message( __( 'API Key revoked successfully.', 'woocommerce' ) );
break;
case -1 :
WC_Admin_Settings::add_error( __( 'Description is missing.', 'woocommerce' ) );
break;
case -2 :
WC_Admin_Settings::add_error( __( 'User is missing.', 'woocommerce' ) );
break;
case -3 :
WC_Admin_Settings::add_error( __( 'Description is missing.', 'woocommerce' ) );
break;
default :
WC_Admin_Settings::add_message( __( 'API Key updated successfully.', 'woocommerce' ) );
break;
}
}
}
/**
* Update Key
*/
private function update_key() {
global $wpdb;
if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'woocommerce-settings' ) ) {
wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
}
if ( ! current_user_can( 'manage_woocommerce' ) ) {
return;
}
$url = admin_url( 'admin.php?page=wc-settings&tab=api&section=keys' );
$key_id = absint( $_POST['key_id'] );
$status = 1;
try {
if ( empty( $_POST['key_description'] ) ) {
throw new Exception( 'Description is missing', -1 );
}
if ( empty( $_POST['key_user'] ) ) {
throw new Exception( 'User is missing', -2 );
}
if ( empty( $_POST['key_permissions'] ) ) {
throw new Exception( 'permissions is missing', -3 );
}
$description = sanitize_text_field( $_POST['key_description'] );
$permissions = ( in_array( $_POST['key_permissions'], array( 'read', 'write', 'read_write' ) ) ) ? sanitize_text_field( $_POST['key_permissions'] ) : 'read';
$user_id = absint( $_POST['key_user'] );
if ( 0 < $key_id ) {
$wpdb->update(
$wpdb->prefix . 'woocommerce_api_keys',
array(
'user_id' => $user_id,
'description' => $description,
'permissions' => $permissions
),
array( 'key_id' => $key_id ),
array(
'%d',
'%s',
'%s'
),
array( '%d' )
);
} else {
$status = 2;
$user = get_userdata( $user_id );
$consumer_key = 'ck_' . hash( 'md5', $user->user_login . date( 'U' ) . mt_rand() );
$consumer_secret = 'cs_' . hash( 'md5', $user->ID . date( 'U' ) . mt_rand() );
$wpdb->insert(
$wpdb->prefix . 'woocommerce_api_keys',
array(
'user_id' => $user_id,
'description' => $description,
'permissions' => $permissions,
'consumer_key' => $consumer_key,
'consumer_secret' => $consumer_secret
),
array(
'%d',
'%s',
'%s',
'%s',
'%s'
)
);
$key_id = $wpdb->insert_id;
}
wp_redirect( esc_url_raw( add_query_arg( array( 'edit-key' => $key_id, 'status' => $status ), $url ) ) );
exit();
} catch ( Exception $e ) {
wp_redirect( esc_url_raw( add_query_arg( array( 'edit-key' => $key_id, 'status' => $e->getCode() ), $url ) ) );
exit();
}
}
/**
* Revoke key
*/
private function revoke_key() {
if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'revoke' ) ) {
wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
}
$key_id = absint( $_GET['revoke-key'] );
$this->remove_key( $key_id );
wp_redirect( esc_url_raw( add_query_arg( array( 'status' => 3 ), admin_url( 'admin.php?page=wc-settings&tab=api&section=keys' ) ) ) );
exit();
}
/**
* Bulk actions
*/
private function bulk_actions() {
if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'woocommerce-settings' ) ) {
wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
}
$keys = array_map( 'absint', (array) $_GET['key'] );
if ( 'revoke' == $_GET['action'] ) {
$this->bulk_revoke_key( $keys );
}
}
/**
* Bulk revoke key
*
* @param array $keys
*/
private function bulk_revoke_key( $keys ) {
foreach ( $keys as $key_id ) {
$this->remove_key( $key_id );
}
}
/**
* Remove key
*
* @param int $key_id
* @return bool
*/
private function remove_key( $key_id ) {
global $wpdb;
$delete = $wpdb->delete( $wpdb->prefix . 'woocommerce_api_keys', array( 'key_id' => $key_id ), array( '%d' ) );
return $delete;
}
}
new WC_Admin_API_Keys();

View File

@ -82,11 +82,12 @@ class WC_Admin_Assets {
// Register scripts
wp_register_script( 'woocommerce_admin', WC()->plugin_url() . '/assets/js/admin/woocommerce_admin' . $suffix . '.js', array( 'jquery', 'jquery-blockui', 'jquery-ui-sortable', 'jquery-ui-widget', 'jquery-ui-core', 'jquery-tiptip' ), WC_VERSION );
wp_register_script( 'jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.66', true );
wp_register_script( 'jquery-blockui', WC()->plugin_url() . '/assets/js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.70', true );
wp_register_script( 'jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip' . $suffix . '.js', array( 'jquery' ), WC_VERSION, true );
wp_register_script( 'accounting', WC()->plugin_url() . '/assets/js/admin/accounting' . $suffix . '.js', array( 'jquery' ), '0.3.2' );
wp_register_script( 'round', WC()->plugin_url() . '/assets/js/admin/round' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
wp_register_script( 'wc-admin-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes' . $suffix . '.js', array( 'jquery', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'accounting', 'round', 'wc-enhanced-select', 'plupload-all', 'stupidtable' ), WC_VERSION );
wp_register_script( 'zeroclipboard', WC()->plugin_url() . '/assets/js/zeroclipboard/jquery.zeroclipboard' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
wp_register_script( 'qrcode', WC()->plugin_url() . '/assets/js/admin/jquery.qrcode.min.js', array( 'jquery' ), WC_VERSION );
wp_register_script( 'stupidtable', WC()->plugin_url() . '/assets/js/stupidtable/stupidtable' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
wp_register_script( 'wc-admin-notices', WC()->plugin_url() . '/assets/js/admin/woocommerce_notices' . $suffix . '.js', array( 'jquery' ), WC_VERSION, true );
@ -142,14 +143,6 @@ class WC_Admin_Assets {
'mon_decimal_point' => wc_get_price_decimal_separator()
);
// If we're on the profile page and the current user has generated API keys, enqueue and add to $params array
if ( $screen->id == 'profile' && $current_user->woocommerce_api_consumer_key ) {
wp_enqueue_script( 'qrcode' );
$params['qrcode_key'] = $current_user->woocommerce_api_consumer_key . '|' . $current_user->woocommerce_api_consumer_secret;
}
wp_localize_script( 'woocommerce_admin', 'woocommerce_admin', $params );
}
@ -298,9 +291,15 @@ class WC_Admin_Assets {
wp_enqueue_script( 'flot-stack', WC()->plugin_url() . '/assets/js/admin/jquery.flot.stack' . $suffix . '.js', array( 'jquery', 'flot' ), WC_VERSION );
}
// API settings
if ( 'woocommerce_page_wc-settings' === $screen->id && isset( $_GET['section'] ) && 'keys' == $_GET['section'] ) {
wp_enqueue_script( 'qrcode' );
wp_enqueue_script( 'zeroclipboard' );
}
// System status
if ( 'woocommerce_page_wc-status' === $screen->id ) {
wp_enqueue_script( 'zeroclipboard', WC()->plugin_url() . '/assets/js/zeroclipboard/jquery.zeroclipboard' . $suffix . '.js', array( 'jquery' ), WC_VERSION );
wp_enqueue_script( 'zeroclipboard' );
}
if ( in_array( $screen->id, array( 'user-edit', 'profile' ) ) ) {

View File

@ -167,7 +167,7 @@ class WC_Admin_Notices {
* Show the Theme Check notice
*/
public function theme_check_notice() {
if ( ! current_theme_supports( 'woocommerce' ) ) {
if ( ! current_theme_supports( 'woocommerce' ) && ! in_array( get_option( 'template' ), wc_get_core_supported_themes() ) ) {
include( 'views/html-notice-theme-support.php' );
}
}

View File

@ -1430,7 +1430,7 @@ class WC_Admin_Post_Types {
$post_ids = array_unique( array_merge(
$wpdb->get_col(
$wpdb->prepare( "
SELECT p1.post_id
SELECT DISTINCT p1.post_id
FROM {$wpdb->postmeta} p1
INNER JOIN {$wpdb->postmeta} p2 ON p1.post_id = p2.post_id
WHERE

View File

@ -2,10 +2,10 @@
/**
* Add extra profile fields for users in admin.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 2.1.0
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -28,12 +28,6 @@ class WC_Admin_Profile {
add_action( 'personal_options_update', array( $this, 'save_customer_meta_fields' ) );
add_action( 'edit_user_profile_update', array( $this, 'save_customer_meta_fields' ) );
add_action( 'show_user_profile', array( $this, 'add_api_key_field' ) );
add_action( 'edit_user_profile', array( $this, 'add_api_key_field' ) );
add_action( 'personal_options_update', array( $this, 'generate_api_key' ) );
add_action( 'edit_user_profile_update', array( $this, 'generate_api_key' ) );
}
/**
@ -141,14 +135,14 @@ class WC_Admin_Profile {
)
)
)
));
) );
return $show_fields;
}
/**
* Show Address Fields on edit user pages.
*
* @param mixed $user User (object) being displayed
* @param WP_User $user
*/
public function add_customer_meta_fields( $user ) {
if ( ! current_user_can( 'manage_woocommerce' ) ) {
@ -193,14 +187,14 @@ class WC_Admin_Profile {
/**
* Save Address Fields on edit user pages
*
* @param mixed $user_id User ID of the user being saved
* @param int $user_id User ID of the user being saved
*/
public function save_customer_meta_fields( $user_id ) {
$save_fields = $this->get_customer_meta_fields();
foreach( $save_fields as $fieldset ) {
foreach ( $save_fields as $fieldset ) {
foreach( $fieldset['fields'] as $key => $field ) {
foreach ( $fieldset['fields'] as $key => $field ) {
if ( isset( $_POST[ $key ] ) ) {
update_user_meta( $user_id, $key, wc_clean( $_POST[ $key ] ) );
@ -208,133 +202,6 @@ class WC_Admin_Profile {
}
}
}
/**
* Display the API key info for a user
*
* @since 2.1
* @param WP_User $user
*/
public function add_api_key_field( $user ) {
if ( ! current_user_can( 'manage_woocommerce' ) ) {
return;
}
$permissions = array(
'read' => __( 'Read', 'woocommerce' ),
'write' => __( 'Write', 'woocommerce' ),
'read_write' => __( 'Read/Write', 'woocommerce' ),
);
if ( current_user_can( 'edit_user', $user->ID ) ) {
?>
<table class="form-table">
<tbody>
<tr>
<th><label for="woocommerce_api_keys"><?php _e( 'WooCommerce API Keys', 'woocommerce' ); ?></label></th>
<td>
<?php if ( empty( $user->woocommerce_api_consumer_key ) ) : ?>
<label for="woocommerce_generate_api_key">
<input name="woocommerce_generate_api_key" type="checkbox" id="woocommerce_generate_api_key" value="0" />
<?php _e( 'Generate API Key', 'woocommerce' ); ?>
</label>
<?php else : ?>
<div class="api-keys-wrapper">
<strong><?php _e( 'Consumer Key:', 'woocommerce' ); ?></strong><br /><code id="woocommerce_api_consumer_key"><?php echo $user->woocommerce_api_consumer_key; ?></code><br/><br />
<strong><?php _e( 'Consumer Secret:', 'woocommerce' ); ?></strong><br /><code id="woocommerce_api_consumer_secret"><?php echo $user->woocommerce_api_consumer_secret; ?></code><br/>
</div>
<div class="api-keys-get-qr">
<div id="qrcode_small"></div>
</div>
<div class="clear"></div>
<strong><?php _e( 'Permissions:', 'woocommerce' ); ?>&nbsp;</strong><span id="woocommerce_api_key_permissions"><select name="woocommerce_api_key_permissions" id="woocommerce_api_key_permissions"><?php
foreach ( $permissions as $permission_key => $permission_name ) { echo '<option value="' . esc_attr( $permission_key ) . '" '.selected($permission_key, $user->woocommerce_api_key_permissions, false).'>'.esc_html( $permission_name ) . '</option>';} ?>
</select></span><br/>
<label for="woocommerce_generate_api_key">
<input name="woocommerce_generate_api_key" type="checkbox" id="woocommerce_generate_api_key" value="0" />
<?php _e( 'Revoke API Key', 'woocommerce' ); ?>
</label>
<?php endif; ?>
</td>
</tr>
</tbody>
</table>
<?php
}
}
/**
* Generate and save (or delete) the API keys for a user
*
* @since 2.1
* @param int $user_id
*/
public function generate_api_key( $user_id ) {
if ( current_user_can( 'edit_user', $user_id ) ) {
$user = get_userdata( $user_id );
// creating/deleting key
if ( isset( $_POST['woocommerce_generate_api_key'] ) ) {
// consumer key
if ( empty( $user->woocommerce_api_consumer_key ) ) {
$consumer_key = 'ck_' . hash( 'md5', $user->user_login . date( 'U' ) . mt_rand() );
update_user_meta( $user_id, 'woocommerce_api_consumer_key', $consumer_key );
} else {
delete_user_meta( $user_id, 'woocommerce_api_consumer_key' );
}
// consumer secret
if ( empty( $user->woocommerce_api_consumer_secret ) ) {
$consumer_secret = 'cs_' . hash( 'md5', $user->ID . date( 'U' ) . mt_rand() );
update_user_meta( $user_id, 'woocommerce_api_consumer_secret', $consumer_secret );
} else {
delete_user_meta( $user_id, 'woocommerce_api_consumer_secret' );
}
// permissions
if ( empty( $user->woocommerce_api_key_permissions ) ) {
if ( isset( $_POST['woocommerce_api_key_permissions'] ) ) {
$permissions = ( in_array( $_POST['woocommerce_api_key_permissions'], array( 'read', 'write', 'read_write' ) ) ) ? $_POST['woocommerce_api_key_permissions'] : 'read';
} else {
$permissions = 'read';
}
update_user_meta( $user_id, 'woocommerce_api_key_permissions', $permissions );
} else {
delete_user_meta( $user_id, 'woocommerce_api_key_permissions' );
}
} else {
// updating permissions for key
if ( ! empty( $_POST['woocommerce_api_key_permissions'] ) && $user->woocommerce_api_key_permissions !== $_POST['woocommerce_api_key_permissions'] ) {
$permissions = ( ! in_array( $_POST['woocommerce_api_key_permissions'], array( 'read', 'write', 'read_write' ) ) ) ? 'read' : $_POST['woocommerce_api_key_permissions'];
update_user_meta( $user_id, 'woocommerce_api_key_permissions', $permissions );
}
}
}
}
}
endif;

View File

@ -2,10 +2,10 @@
/**
* WooCommerce Admin Settings Class.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 2.2.0
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -40,7 +40,7 @@ class WC_Admin_Settings {
$settings[] = include( 'settings/class-wc-settings-accounts.php' );
$settings[] = include( 'settings/class-wc-settings-emails.php' );
$settings[] = include( 'settings/class-wc-settings-integrations.php' );
$settings[] = include( 'settings/class-wc-settings-webhooks.php' );
$settings[] = include( 'settings/class-wc-settings-api.php' );
self::$settings = apply_filters( 'woocommerce_get_settings_pages', $settings );
}

View File

@ -58,8 +58,8 @@ class WC_Admin_Status {
FROM
{$wpdb->options} a, {$wpdb->options} b
WHERE
a.option_name LIKE '_transient_%' AND
a.option_name NOT LIKE '_transient_timeout_%' AND
a.option_name LIKE '\_transient\_%' AND
a.option_name NOT LIKE '\_transient\_timeout\_%' AND
b.option_name = CONCAT(
'_transient_timeout_',
SUBSTRING(
@ -76,8 +76,8 @@ class WC_Admin_Status {
FROM
{$wpdb->options} a, {$wpdb->options} b
WHERE
a.option_name LIKE '_site_transient_%' AND
a.option_name NOT LIKE '_site_transient_timeout_%' AND
a.option_name LIKE '\_site\_transient\_%' AND
a.option_name NOT LIKE '\_site\_transient\_timeout\_%' AND
b.option_name = CONCAT(
'_site_transient_timeout_',
SUBSTRING(

View File

@ -5,7 +5,7 @@
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 2.3.0
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -76,7 +76,7 @@ class WC_Admin_Webhooks_Table_List extends WP_List_Table {
*/
public function column_title( $webhook ) {
$the_webhook = $this->get_webbook_object( $webhook );
$edit_link = admin_url( 'admin.php?page=wc-settings&amp;tab=webhooks&amp;edit-webhook=' . $the_webhook->id );
$edit_link = admin_url( 'admin.php?page=wc-settings&amp;tab=api&amp;section=webhooks&amp;edit-webhook=' . $the_webhook->id );
$title = _draft_or_post_title( $the_webhook->get_post_data() );
$post_type_object = get_post_type_object( $the_webhook->get_post_data()->post_type );
$post_status = $the_webhook->get_post_data()->post_status;
@ -86,7 +86,7 @@ class WC_Admin_Webhooks_Table_List extends WP_List_Table {
if ( 'trash' == $post_status ) {
$output .= esc_html( $title );
} else {
$output .= '<a href="' . esc_attr( $edit_link ) . '">' . esc_html( $title ) . '</a>';
$output .= '<a href="' . esc_url( $edit_link ) . '">' . esc_html( $title ) . '</a>';
}
$output .= '</strong>';
@ -96,12 +96,12 @@ class WC_Admin_Webhooks_Table_List extends WP_List_Table {
);
if ( current_user_can( $post_type_object->cap->edit_post, $the_webhook->id ) && 'trash' !== $post_status ) {
$actions['edit'] = '<a href="' . esc_attr( $edit_link ) . '">' . __( 'Edit', 'woocommerce' ) . '</a>';
$actions['edit'] = '<a href="' . esc_url( $edit_link ) . '">' . __( 'Edit', 'woocommerce' ) . '</a>';
}
if ( current_user_can( $post_type_object->cap->delete_post, $the_webhook->id ) ) {
if ( 'trash' == $post_status ) {
$actions['untrash'] = '<a title="' . esc_attr( __( 'Restore this item from the Trash', 'woocommerce' ) ) . '" href="' . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $the_webhook->id ) ), 'untrash-post_' . $the_webhook->id ) . '">' . __( 'Restore', 'woocommerce' ) . '</a>';
$actions['untrash'] = '<a title="' . esc_attr__( 'Restore this item from the Trash', 'woocommerce' ) . '" href="' . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=untrash', $the_webhook->id ) ), 'untrash-post_' . $the_webhook->id ) . '">' . __( 'Restore', 'woocommerce' ) . '</a>';
} elseif ( EMPTY_TRASH_DAYS ) {
$actions['trash'] = '<a class="submitdelete" title="' . esc_attr( __( 'Move this item to the Trash', 'woocommerce' ) ) . '" href="' . get_delete_post_link( $the_webhook->id ) . '">' . __( 'Trash', 'woocommerce' ) . '</a>';
}
@ -209,7 +209,7 @@ class WC_Admin_Webhooks_Table_List extends WP_List_Table {
}
$class = empty( $class ) && empty( $_REQUEST['status'] ) ? ' class="current"' : '';
$status_links['all'] = "<a href='admin.php?page=wc-settings&amp;tab=webhooks'$class>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_posts, 'posts', 'woocommerce' ), number_format_i18n( $total_posts ) ) . '</a>';
$status_links['all'] = "<a href='admin.php?page=wc-settings&amp;tab=api&amp;section=webhooks'$class>" . sprintf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $total_posts, 'posts', 'woocommerce' ), number_format_i18n( $total_posts ) ) . '</a>';
foreach ( get_post_stati( array( 'show_in_admin_status_list' => true ), 'objects' ) as $status ) {
$class = '';
@ -229,7 +229,7 @@ class WC_Admin_Webhooks_Table_List extends WP_List_Table {
$label = $this->get_status_label( $status_name, $status );
$status_links[ $status_name ] = "<a href='admin.php?page=wc-settings&amp;tab=webhooks&amp;status=$status_name'$class>" . sprintf( translate_nooped_plural( $label, $num_posts->$status_name ), number_format_i18n( $num_posts->$status_name ) ) . '</a>';
$status_links[ $status_name ] = "<a href='admin.php?page=wc-settings&amp;tab=api&amp;section=webhooks&amp;status=$status_name'$class>" . sprintf( translate_nooped_plural( $label, $num_posts->$status_name ), number_format_i18n( $num_posts->$status_name ) ) . '</a>';
}
return $status_links;
@ -260,7 +260,7 @@ class WC_Admin_Webhooks_Table_List extends WP_List_Table {
*/
protected function extra_tablenav( $which ) {
if ( 'top' == $which && isset( $_GET['status'] ) && 'trash' == $_GET['status'] && current_user_can( 'delete_shop_webhooks' ) ) {
echo '<div class="alignleft actions"><a class="button apply" href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=webhooks&status=trash&empty_trash=1' ) ) . '">' . __( 'Empty Trash', 'woocommerce' ) . '</a></div>';
echo '<div class="alignleft actions"><a class="button apply" href="' . esc_url( wp_nonce_url( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&status=trash&empty_trash=1' ), 'empty_trash' ) ) . '">' . __( 'Empty Trash', 'woocommerce' ) . '</a></div>';
}
}

View File

@ -5,7 +5,7 @@
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 2.3.0
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -30,7 +30,12 @@ class WC_Admin_Webhooks {
* @return bool
*/
private function is_webhook_settings_page() {
return isset( $_GET['page'] ) && 'wc-settings' == $_GET['page'] && isset( $_GET['tab'] ) && 'webhooks' == $_GET['tab'];
return isset( $_GET['page'] )
&& 'wc-settings' == $_GET['page']
&& isset( $_GET['tab'] )
&& 'api' == $_GET['tab']
&& isset( $_GET['section'] )
&& 'webhooks' == isset( $_GET['section'] );
}
/**
@ -120,7 +125,7 @@ class WC_Admin_Webhooks {
*/
private function save() {
if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'woocommerce-settings' ) ) {
die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
}
$webhook_id = absint( $_POST['webhook_id'] );
@ -157,7 +162,7 @@ class WC_Admin_Webhooks {
delete_transient( 'woocommerce_webhook_ids' );
// Redirect to webhook edit page to avoid settings save actions
wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=webhooks&edit-webhook=' . $webhook->id . '&updated=1' ) );
wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook->id . '&updated=1' ) );
exit();
}
@ -165,6 +170,10 @@ class WC_Admin_Webhooks {
* Create Webhook
*/
private function create() {
if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'create-webhook' ) ) {
wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
}
if ( ! current_user_can( 'publish_shop_webhooks' ) ) {
wp_die( __( 'You don\'t have permissions to create Webhooks!', 'woocommerce' ) );
}
@ -188,7 +197,7 @@ class WC_Admin_Webhooks {
delete_transient( 'woocommerce_webhook_ids' );
// Redirect to edit page
wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=webhooks&edit-webhook=' . $webhook_id . '&created=1' ) );
wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook_id . '&created=1' ) );
exit();
}
@ -211,8 +220,10 @@ class WC_Admin_Webhooks {
$qty = count( $webhooks );
$status = isset( $_GET['status'] ) ? '&status=' . sanitize_text_field( $_GET['status'] ) : '';
delete_transient( 'woocommerce_webhook_ids' );
// Redirect to webhooks page
wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=webhooks' . $status . '&' . $type . '=' . $qty ) );
wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks' . $status . '&' . $type . '=' . $qty ) );
exit();
}
@ -228,23 +239,27 @@ class WC_Admin_Webhooks {
$qty = count( $webhooks );
delete_transient( 'woocommerce_webhook_ids' );
// Redirect to webhooks page
wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=webhooks&status=trash&untrashed=' . $qty ) );
wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&status=trash&untrashed=' . $qty ) );
exit();
}
/**
* Webhook bulk actions
* Bulk actions
*/
private function bulk_actions() {
if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'woocommerce-settings' ) ) {
wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
}
if ( ! current_user_can( 'edit_shop_webhooks' ) ) {
wp_die( __( 'You don\'t have permissions to edit Webhooks!', 'woocommerce' ) );
}
$webhooks = array_map( 'absint', (array) $_GET['webhook'] );
delete_transient( 'woocommerce_webhook_ids' );
switch ( $_GET['action'] ) {
case 'trash' :
$this->bulk_trash( $webhooks );
@ -263,7 +278,11 @@ class WC_Admin_Webhooks {
/**
* Empty Trash
*/
public function empty_trash() {
private function empty_trash() {
if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], 'empty_trash' ) ) {
wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
}
if ( ! current_user_can( 'delete_shop_webhooks' ) ) {
wp_die( __( 'You don\'t have permissions to delete Webhooks!', 'woocommerce' ) );
}
@ -283,7 +302,7 @@ class WC_Admin_Webhooks {
$qty = count( $webhooks );
// Redirect to webhooks page
wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=webhooks&deleted=' . $qty ) );
wp_redirect( admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&deleted=' . $qty ) );
exit();
}
@ -307,12 +326,177 @@ class WC_Admin_Webhooks {
$this->bulk_actions();
}
// Bulk actions
// Empty trash
if ( isset( $_GET['empty_trash'] ) ) {
$this->empty_trash();
}
}
}
/**
* Page output
*/
public static function page_output() {
// Hide the save button
$GLOBALS['hide_save_button'] = true;
if ( isset( $_GET['edit-webhook'] ) ) {
$webhook_id = absint( $_GET['edit-webhook'] );
$webhook = new WC_Webhook( $webhook_id );
if ( 'trash' != $webhook->post_data->post_status ) {
include( 'settings/views/html-webhooks-edit.php' );
return;
}
}
self::table_list_output();
}
/**
* Notices.
*/
public static function notices() {
if ( isset( $_GET['trashed'] ) ) {
$trashed = absint( $_GET['trashed'] );
WC_Admin_Settings::add_message( sprintf( _n( '1 webhook moved to the Trash.', '%d webhooks moved to the Trash.', $trashed, 'woocommerce' ), $trashed ) );
}
if ( isset( $_GET['untrashed'] ) ) {
$untrashed = absint( $_GET['untrashed'] );
WC_Admin_Settings::add_message( sprintf( _n( '1 webhook restored from the Trash.', '%d webhooks restored from the Trash.', $untrashed, 'woocommerce' ), $untrashed ) );
}
if ( isset( $_GET['deleted'] ) ) {
$deleted = absint( $_GET['deleted'] );
WC_Admin_Settings::add_message( sprintf( _n( '1 webhook permanently deleted.', '%d webhooks permanently deleted.', $deleted, 'woocommerce' ), $deleted ) );
}
if ( isset( $_GET['updated'] ) ) {
WC_Admin_Settings::add_message( __( 'Webhook updated successfully.', 'woocommerce' ) );
}
if ( isset( $_GET['created'] ) ) {
WC_Admin_Settings::add_message( __( 'Webhook created successfully.', 'woocommerce' ) );
}
}
/**
* 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>';
$webhooks_table_list = new WC_Admin_Webhooks_Table_List();
$webhooks_table_list->prepare_items();
echo '<input type="hidden" name="page" value="wc-settings" />';
echo '<input type="hidden" name="tab" value="api" />';
echo '<input type="hidden" name="section" value="webhooks" />';
$webhooks_table_list->views();
$webhooks_table_list->search_box( __( 'Search Webhooks', 'woocommerce' ), 'webhook' );
$webhooks_table_list->display();
}
/**
* Logs output
*
* @param WC_Webhook $webhook
*/
public static function logs_output( $webhook ) {
$current = isset( $_GET['log_page'] ) ? absint( $_GET['log_page'] ) : 1;
$args = array(
'post_id' => $webhook->id,
'status' => 'approve',
'type' => 'webhook_delivery',
'number' => 10
);
if ( 1 < $current ) {
$args['offset'] = ( $current - 1 ) * 10;
}
remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_webhook_comments' ), 10, 1 );
$logs = get_comments( $args );
add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_webhook_comments' ), 10, 1 );
if ( $logs ) {
include_once( 'settings/views/html-webhook-logs.php' );
} else {
echo '<p>' . __( 'This Webhook has no log yet.', 'woocommerce' ) . '</p>';
}
}
/**
* Get the webhook topic data
*
* @return array
*/
public static function get_topic_data( $webhook ) {
$topic = $webhook->get_topic();
$event = '';
$resource = '';
if ( $topic ) {
list( $resource, $event ) = explode( '.', $topic );
if ( 'action' === $resource ) {
$topic = 'action';
} else if ( ! in_array( $resource, array( 'coupon', 'customer', 'order', 'product' ) ) ) {
$topic = 'custom';
}
}
return array(
'topic' => $topic,
'event' => $event,
'resource' => $resource
);
}
/**
* Get the logs navigation.
*
* @param int $total
*
* @return string
*/
public static function get_logs_navigation( $total, $webhook ) {
$pages = ceil( $total / 10 );
$current = isset( $_GET['log_page'] ) ? absint( $_GET['log_page'] ) : 1;
$html = '<div class="webhook-logs-navigation">';
$html .= '<p class="info" style="float: left;"><strong>';
$html .= sprintf( '%s &ndash; Page %d of %d', _n( '1 item', sprintf( '%d items', $total ), $total, 'woocommerce' ), $current, $pages );
$html .= '</strong></p>';
if ( 1 < $pages ) {
$html .= '<p class="tools" style="float: right;">';
if ( 1 == $current ) {
$html .= '<button class="button-primary" disabled="disabled">' . __( '&lsaquo; Previous', 'woocommerce' ) . '</button> ';
} else {
$html .= '<a class="button-primary" href="' . admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook->id . '&log_page=' . ( $current - 1 ) ) . '#webhook-logs">' . __( '&lsaquo; Previous', 'woocommerce' ) . '</a> ';
}
if ( $pages == $current ) {
$html .= '<button class="button-primary" disabled="disabled">' . __( 'Next &rsaquo;', 'woocommerce' ) . '</button>';
} else {
$html .= '<a class="button-primary" href="' . admin_url( 'admin.php?page=wc-settings&tab=api&section=webhooks&edit-webhook=' . $webhook->id . '&log_page=' . ( $current + 1 ) ) . '#webhook-logs">' . __( 'Next &rsaquo;', 'woocommerce' ) . '</a>';
}
$html .= '</p>';
}
$html .= '<div class="clear"></div></div>';
return $html;
}
}
new WC_Admin_Webhooks();

View File

@ -23,7 +23,7 @@ class WC_Admin {
*/
public function __construct() {
add_action( 'init', array( $this, 'includes' ) );
add_action( 'current_screen', array( $this, 'conditonal_includes' ) );
add_action( 'current_screen', array( $this, 'conditional_includes' ) );
add_action( 'admin_init', array( $this, 'prevent_admin_access' ) );
add_action( 'admin_init', array( $this, 'preview_emails' ) );
add_action( 'admin_footer', 'wc_print_js', 25 );
@ -48,6 +48,7 @@ class WC_Admin {
include_once( 'class-wc-admin-welcome.php' );
include_once( 'class-wc-admin-notices.php' );
include_once( 'class-wc-admin-assets.php' );
include_once( 'class-wc-admin-api-keys.php' );
include_once( 'class-wc-admin-webhooks.php' );
// Help
@ -65,7 +66,7 @@ class WC_Admin {
/**
* Include admin files conditionally
*/
public function conditonal_includes() {
public function conditional_includes() {
$screen = get_current_screen();

View File

@ -230,7 +230,11 @@ class WC_Meta_Box_Order_Data {
<?php do_action( 'woocommerce_admin_order_data_after_order_details', $order ); ?>
</div>
<div class="order_data_column">
<h4><?php _e( 'Billing Details', 'woocommerce' ); ?> <a class="edit_address" href="#"><img src="<?php echo WC()->plugin_url(); ?>/assets/images/icons/edit.png" alt="<?php _e( 'Edit', 'woocommerce' ); ?>" width="14" /></a></h4>
<h4>
<?php _e( 'Billing Details', 'woocommerce' ); ?>
<a href="#" class="edit_address"><?php _e( 'Edit', 'woocommerce' ); ?></a>
<a href="#" class="tips load_customer_billing" data-tip="<?php _e( 'Load billing address', 'woocommerce' ); ?>" style="display:none;"><?php _e( 'Load billing address', 'woocommerce' ); ?></a>
</h4>
<?php
// Display values
echo '<div class="address">';
@ -256,7 +260,7 @@ class WC_Meta_Box_Order_Data {
echo '</div>';
// Display form
echo '<div class="edit_address"><p><button class="button load_customer_billing">' . __( 'Load billing address', 'woocommerce' ) . '</button></p>';
echo '<div class="edit_address">';
foreach ( self::$billing_fields as $key => $field ) {
if ( ! isset( $field['type'] ) ) {
@ -310,7 +314,12 @@ class WC_Meta_Box_Order_Data {
</div>
<div class="order_data_column">
<h4><?php _e( 'Shipping Details', 'woocommerce' ); ?> <a class="edit_address" href="#"><img src="<?php echo WC()->plugin_url(); ?>/assets/images/icons/edit.png" alt="<?php _e( 'Edit', 'woocommerce' ); ?>" width="14" /></a></h4>
<h4>
<?php _e( 'Shipping Details', 'woocommerce' ); ?>
<a href="#" class="edit_address"><?php _e( 'Edit', 'woocommerce' ); ?></a>
<a href="#" class="tips billing-same-as-shipping" data-tip="<?php _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 _e( 'Load shipping address', 'woocommerce' ); ?>" style="display:none;"><?php _e( 'Load shipping address', 'woocommerce' ); ?></a>
</h4>
<?php
// Display values
echo '<div class="address">';
@ -342,7 +351,7 @@ class WC_Meta_Box_Order_Data {
echo '</div>';
// Display form
echo '<div class="edit_address"><p><button class="button load_customer_shipping">' . __( 'Load shipping address', 'woocommerce' ) . '</button> <button class="button billing-same-as-shipping">' . __( 'Copy from billing', 'woocommerce' ) . '</button></p>';
echo '<div class="edit_address">';
if ( ! empty( self::$shipping_fields ) ) {
foreach ( self::$shipping_fields as $key => $field ) {

View File

@ -978,13 +978,12 @@ class WC_Meta_Box_Product_Data {
$attribute_variation = $_POST['attribute_variation'];
}
$attribute_is_taxonomy = $_POST['attribute_is_taxonomy'];
$attribute_position = $_POST['attribute_position'];
$attribute_names_count = sizeof( $attribute_names );
$attribute_is_taxonomy = $_POST['attribute_is_taxonomy'];
$attribute_position = $_POST['attribute_position'];
$attribute_names_max_key = max( $attribute_names );
for ( $i = 0; $i < $attribute_names_count; $i++ ) {
if ( ! $attribute_names[ $i ] ) {
for ( $i = 0; $i <= $attribute_names_max_key; $i++ ) {
if ( empty( $attribute_names[ $i ] ) ) {
continue;
}

View File

@ -0,0 +1,161 @@
<?php
/**
* WooCommerce API Settings
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( ! class_exists( 'WC_Settings_Rest_API' ) ) :
/**
* WC_Settings_Rest_API
*/
class WC_Settings_Rest_API extends WC_Settings_Page {
/**
* Constructor
*/
public function __construct() {
$this->id = 'api';
$this->label = __( 'API', 'woocommerce' );
add_filter( 'woocommerce_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
add_action( 'woocommerce_settings_' . $this->id, array( $this, 'output' ) );
add_action( 'woocommerce_sections_' . $this->id, array( $this, 'output_sections' ) );
add_action( 'woocommerce_settings_form_method_tab_' . $this->id, array( $this, 'form_method' ) );
add_action( 'woocommerce_settings_save_' . $this->id, array( $this, 'save' ) );
$this->notices();
}
/**
* Get sections
*
* @return array
*/
public function get_sections() {
$sections = array(
'' => __( 'Settings', 'woocommerce' ),
'keys' => __( 'Keys/Apps', 'woocommerce' ),
'webhooks' => __( 'Webhooks', 'woocommerce' )
);
return apply_filters( 'woocommerce_get_sections_' . $this->id, $sections );
}
/**
* Get settings array
*
* @return array
*/
public function get_settings() {
$settings = apply_filters( 'woocommerce_settings_rest_api', array(
array(
'title' => __( 'General Options', 'woocommerce' ),
'type' => 'title',
'desc' => '',
'id' => 'general_options'
),
array(
'title' => __( 'API', 'woocommerce' ),
'desc' => __( 'Enable the REST API', 'woocommerce' ),
'id' => 'woocommerce_api_enabled',
'type' => 'checkbox',
'default' => 'yes',
),
array(
'type' => 'sectionend',
'id' => 'general_options'
),
) );
return apply_filters( 'woocommerce_get_settings_' . $this->id, $settings );
}
/**
* Form method
*
* @param string $method
*
* @return string
*/
public function form_method( $method ) {
global $current_section;
if ( 'webhooks' == $current_section ) {
if ( isset( $_GET['edit-webhook'] ) ) {
$webhook_id = absint( $_GET['edit-webhook'] );
$webhook = new WC_Webhook( $webhook_id );
if ( 'trash' != $webhook->post_data->post_status ) {
return 'post';
}
}
return 'get';
}
if ( 'keys' == $current_section ) {
if ( isset( $_GET['create-key'] ) || isset( $_GET['edit-key'] ) ) {
return 'post';
}
return 'get';
}
return 'post';
}
/**
* Notices.
*/
private function notices() {
if ( isset( $_GET['section'] ) && 'webhooks' == $_GET['section'] ) {
WC_Admin_Webhooks::notices();
}
if ( isset( $_GET['section'] ) && 'keys' == $_GET['section'] ) {
WC_Admin_API_Keys::notices();
}
}
/**
* Output the settings
*/
public function output() {
global $current_section;
if ( 'webhooks' == $current_section ) {
WC_Admin_Webhooks::page_output();
} else if ( 'keys' == $current_section ) {
WC_Admin_API_Keys::page_output();
} else {
$settings = $this->get_settings( $current_section );
WC_Admin_Settings::output_fields( $settings );
}
}
/**
* Save settings
*/
public function save() {
global $current_section;
if ( apply_filters( 'woocommerce_rest_api_valid_to_save', ! in_array( $current_section, array( 'keys', 'webhooks' ) ) ) ) {
$settings = $this->get_settings();
WC_Admin_Settings::save_fields( $settings );
}
}
}
endif;
return new WC_Settings_Rest_API();

View File

@ -106,7 +106,7 @@ class WC_Settings_Payment_Gateways extends WC_Settings_Page {
'type' => 'checkbox',
'checkboxgroup' => '',
'show_if_checked' => 'option',
'desc_tip' => __( 'Force SSL (HTTPS) on the checkout pages (an SSL Certificate is required).', 'woocommerce' ),
'desc_tip' => __( 'Force SSL (HTTPS) on the checkout pages (a SSL Certificate is required).', 'woocommerce' ),
),
array(

View File

@ -116,14 +116,6 @@ class WC_Settings_General extends WC_Settings_Page {
'autoload' => false
),
array(
'title' => __( 'API', 'woocommerce' ),
'desc' => __( 'Enable the REST API', 'woocommerce' ),
'id' => 'woocommerce_api_enabled',
'type' => 'checkbox',
'default' => 'yes',
),
array( 'type' => 'sectionend', 'id' => 'general_options'),
array( 'title' => __( 'Currency Options', 'woocommerce' ), 'type' => 'title', 'desc' => __( 'The following options affect how prices are displayed on the frontend.', 'woocommerce' ), 'id' => 'pricing_options' ),

View File

@ -58,7 +58,7 @@ class WC_Settings_Products extends WC_Settings_Page {
$settings = $this->get_settings( $current_section );
WC_Admin_Settings::output_fields( $settings );
WC_Admin_Settings::output_fields( $settings );
}
/**

View File

@ -1,234 +0,0 @@
<?php
/**
* WooCommerce Webhooks Settings
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( ! class_exists( 'WC_Settings_Webhooks' ) ) :
/**
* WC_Settings_Webhooks
*/
class WC_Settings_Webhooks extends WC_Settings_Page {
/**
* Constructor
*/
public function __construct() {
$this->id = 'webhooks';
$this->label = __( 'Webhooks', 'woocommerce' );
add_filter( 'woocommerce_settings_tabs_array', array( $this, 'add_settings_page' ), 20 );
add_action( 'woocommerce_settings_' . $this->id, array( $this, 'output' ) );
add_action( 'woocommerce_settings_form_method_tab_' . $this->id, array( $this, 'form_method' ) );
$this->notices();
}
/**
* Form method
*
* @param string $method
*
* @return string
*/
public function form_method( $method ) {
if ( isset( $_GET['edit-webhook'] ) ) {
$webhook_id = absint( $_GET['edit-webhook'] );
$webhook = new WC_Webhook( $webhook_id );
if ( 'trash' != $webhook->post_data->post_status ) {
return 'post';
}
}
return 'get';
}
/**
* Notices.
*/
private function notices() {
if ( isset( $_GET['trashed'] ) ) {
$trashed = absint( $_GET['trashed'] );
WC_Admin_Settings::add_message( sprintf( _n( '1 webhook moved to the Trash.', '%d webhooks moved to the Trash.', $trashed, 'woocommerce' ), $trashed ) );
}
if ( isset( $_GET['untrashed'] ) ) {
$untrashed = absint( $_GET['untrashed'] );
WC_Admin_Settings::add_message( sprintf( _n( '1 webhook restored from the Trash.', '%d webhooks restored from the Trash.', $untrashed, 'woocommerce' ), $untrashed ) );
}
if ( isset( $_GET['deleted'] ) ) {
$deleted = absint( $_GET['deleted'] );
WC_Admin_Settings::add_message( sprintf( _n( '1 webhook permanently deleted.', '%d webhooks permanently deleted.', $deleted, 'woocommerce' ), $deleted ) );
}
if ( isset( $_GET['updated'] ) ) {
WC_Admin_Settings::add_message( __( 'Webhook updated successfully.', 'woocommerce' ) );
}
if ( isset( $_GET['created'] ) ) {
WC_Admin_Settings::add_message( __( 'Webhook created successfully.', 'woocommerce' ) );
}
}
/**
* Table list output
*/
private function table_list_output() {
echo '<h3>' . __( 'Webhooks', 'woocommerce' ) . ' <a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=webhooks&create-webhook=1' ) ) . '" class="add-new-h2">' . __( 'Add Webhook', 'woocommerce' ) . '</a></h3>';
$webhooks_table_list = new WC_Admin_Webhooks_Table_List();
$webhooks_table_list->prepare_items();
echo '<input type="hidden" name="page" value="wc-settings" />';
echo '<input type="hidden" name="tab" value="webhooks" />';
$webhooks_table_list->views();
$webhooks_table_list->search_box( __( 'Search Webhooks', 'woocommerce' ), 'webhook' );
$webhooks_table_list->display();
}
/**
* Edit webhook output
*
* @param WC_Webhook $webhook
*/
private function edit_output( $webhook ) {
include_once( 'views/html-webhooks-edit.php' );
}
/**
* Logs output
*
* @param WC_Webhook $webhook
*/
private function logs_output( $webhook ) {
$current = isset( $_GET['log_page'] ) ? absint( $_GET['log_page'] ) : 1;
$args = array(
'post_id' => $webhook->id,
'status' => 'approve',
'type' => 'webhook_delivery',
'number' => 10
);
if ( 1 < $current ) {
$args['offset'] = ( $current - 1 ) * 10;
}
remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_webhook_comments' ), 10, 1 );
$logs = get_comments( $args );
add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_webhook_comments' ), 10, 1 );
if ( $logs ) {
include_once( 'views/html-webhook-logs.php' );
} else {
echo '<p>' . __( 'This Webhook has no log yet.', 'woocommerce' ) . '</p>';
}
}
/**
* Output the settings
*/
public function output() {
global $current_section;
// Hide the save button
$GLOBALS['hide_save_button'] = true;
if ( isset( $_GET['edit-webhook'] ) ) {
$webhook_id = absint( $_GET['edit-webhook'] );
$webhook = new WC_Webhook( $webhook_id );
if ( 'trash' != $webhook->post_data->post_status ) {
$this->edit_output( $webhook );
return;
}
}
$this->table_list_output();
}
/**
* Get the webhook topic data
*
* @return array
*/
private function get_topic_data( $webhook ) {
$topic = $webhook->get_topic();
$event = '';
$resource = '';
if ( $topic ) {
list( $resource, $event ) = explode( '.', $topic );
if ( 'action' === $resource ) {
$topic = 'action';
} else if ( ! in_array( $resource, array( 'coupon', 'customer', 'order', 'product' ) ) ) {
$topic = 'custom';
}
}
return array(
'topic' => $topic,
'event' => $event,
'resource' => $resource
);
}
/**
* Get the logs navigation.
*
* @param int $total
*
* @return string
*/
private function get_logs_navigation( $total, $webhook ) {
$pages = ceil( $total / 10 );
$current = isset( $_GET['log_page'] ) ? absint( $_GET['log_page'] ) : 1;
$html = '<div class="webhook-logs-navigation">';
$html .= '<p class="info" style="float: left;"><strong>';
$html .= sprintf( '%s &ndash; Page %d of %d', _n( '1 item', sprintf( '%d items', $total ), $total, 'woocommerce' ), $current, $pages );
$html .= '</strong></p>';
if ( 1 < $pages ) {
$html .= '<p class="tools" style="float: right;">';
if ( 1 == $current ) {
$html .= '<button class="button-primary" disabled="disabled">' . __( '&lsaquo; Previous', 'woocommerce' ) . '</button> ';
} else {
$html .= '<a class="button-primary" href="' . admin_url( 'admin.php?page=wc-settings&tab=webhooks&edit-webhook=' . $webhook->id . '&log_page=' . ( $current - 1 ) ) . '#webhook-logs">' . __( '&lsaquo; Previous', 'woocommerce' ) . '</a> ';
}
if ( $pages == $current ) {
$html .= '<button class="button-primary" disabled="disabled">' . __( 'Next &rsaquo;', 'woocommerce' ) . '</button>';
} else {
$html .= '<a class="button-primary" href="' . admin_url( 'admin.php?page=wc-settings&tab=webhooks&edit-webhook=' . $webhook->id . '&log_page=' . ( $current + 1 ) ) . '#webhook-logs">' . __( 'Next &rsaquo;', 'woocommerce' ) . '</a>';
}
$html .= '</p>';
}
$html .= '<div class="clear"></div></div>';
return $html;
}
}
endif;
return new WC_Settings_Webhooks();

View File

@ -0,0 +1,127 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<input type="hidden" name="key_id" value="<?php echo esc_attr( $key_id ); ?>" />
<div id="key-fields" class="settings-panel">
<h3><?php _e( 'Key Details', 'woocommerce' ); ?></h3>
<table class="form-table">
<tbody>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="key_description"><?php _e( 'Description', 'woocommerce' ); ?></label>
<img class="help_tip" data-tip="<?php esc_attr_e( 'Friendly name for identifying this key.', 'woocommerce' ); ?>" src="<?php echo WC()->plugin_url(); ?>/assets/images/help.png" height="16" width="16" />
</th>
<td class="forminp">
<input name="key_description" id="key_description" type="text" class="input-text regular-input" value="<?php echo esc_attr( $key_data['description'] ); ?>" />
</td>
</tr>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="key_user"><?php _e( 'User', 'woocommerce' ); ?></label>
<img class="help_tip" data-tip="<?php _e( 'Owner of these keys.', 'woocommerce' ); ?>" src="<?php echo WC()->plugin_url(); ?>/assets/images/help.png" height="16" width="16" />
</th>
<td class="forminp">
<?php
$curent_user_id = get_current_user_id();
$user_id = ! empty( $key_data['user_id'] ) ? absint( $key_data['user_id'] ) : $curent_user_id;
$user = get_user_by( 'id', $user_id );
$user_string = esc_html( $user->display_name ) . ' (#' . absint( $user->ID ) . ' &ndash; ' . esc_html( $user->user_email );
?>
<input type="hidden" class="wc-customer-search" name="key_user" data-placeholder="<?php esc_html_e( 'Search for a customer&hellip;', 'woocommerce' ); ?>" data-selected="<?php echo esc_attr( $user_string ); ?>" value="<?php echo esc_attr( $user_id ); ?>" data-allow_clear="true" />
</td>
</tr>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="key_permissions"><?php _e( 'Permissons', 'woocommerce' ); ?></label>
<img class="help_tip" data-tip="<?php _e( 'Select the access type of these keys.', 'woocommerce' ); ?>" src="<?php echo WC()->plugin_url(); ?>/assets/images/help.png" height="16" width="16" />
</th>
<td class="forminp">
<select name="key_permissions" id="key_permissions" class="wc-enhanced-select">
<?php
$permissions = array(
'read' => __( 'Read', 'woocommerce' ),
'write' => __( 'Write', 'woocommerce' ),
'read_write' => __( 'Read/Write', 'woocommerce' ),
);
foreach ( $permissions as $permission_id => $permission_name ) : ?>
<option value="<?php echo esc_attr( $permission_id ); ?>" <?php selected( $key_data['permissions'], $permission_id, true ); ?>><?php echo esc_html( $permission_name ); ?></option>
<?php endforeach; ?>
</select>
</td>
</tr>
<?php if ( ! empty( $key_data['consumer_key'] ) && ! empty( $key_data['consumer_secret'] ) ) : ?>
<tr valign="top" id="webhook-action-event-wrap">
<th scope="row" class="titledesc">
<?php _e( 'Consumer Key', 'woocommerce' ); ?>
</th>
<td class="forminp">
<code id="key_consumer_key"><?php echo esc_html( $key_data['consumer_key'] ); ?></code> <button type="button" class="button-secondary copy-key" data-tip="<?php _e( 'Copied!', 'woocommerce' ); ?>"><?php _e( 'Copy', 'woocommerce' ); ?></button>
</td>
</tr>
<tr valign="top" id="webhook-action-event-wrap">
<th scope="row" class="titledesc">
<label for="key_consumer_secret"><?php _e( 'Consumer Secret', 'woocommerce' ); ?></label>
</th>
<td class="forminp">
<code id="key_consumer_secret"><?php echo esc_html( $key_data['consumer_secret'] ); ?></code> <button type="button" class="button-secondary copy-key" data-tip="<?php _e( 'Copied!', 'woocommerce' ); ?>"><?php _e( 'Copy', 'woocommerce' ); ?></button>
</td>
</tr>
<tr valign="top" id="webhook-action-event-wrap">
<th scope="row" class="titledesc">
<?php _e( 'QRCode', 'woocommerce' ); ?>
</th>
<td class="forminp">
<div id="qrcode_wrap" data-consumer_key="<?php echo esc_attr( $key_data['consumer_key'] ); ?>" data-consumer_secret="<?php echo esc_attr( $key_data['consumer_secret'] ); ?>"></div>
<script>
jQuery( function( $ ) {
// Copy to clipboard
$( '.copy-key' ).tipTip({
'attribute': 'data-tip',
'activation': 'click',
'fadeIn': 50,
'fadeOut': 50,
'delay': 0
});
$( document.body ).on( 'copy', '.copy-key', function( e ) {
e.clipboardData.clearData();
e.clipboardData.setData( 'text/plain', $.trim( $( this ).prev( 'code' ).html() ) );
e.preventDefault();
});
// Generate QR Code
var qrcodeWrap = $( '#qrcode_wrap' );
qrcodeWrap.qrcode({
text: qrcodeWrap.data( 'consumer_key' ) + '|' + qrcodeWrap.data( 'consumer_secret' ),
width: 120,
height: 120
});
});
</script>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
<?php do_action( 'woocommerce_admin_key_fields', $key_data ); ?>
<?php
if ( 0 == $key_id ) {
submit_button( __( 'Generate API Key', 'woocommerce' ), 'primary', 'update_api_key' );
} else {
?>
<p class="submit">
<?php submit_button( __( 'Save Changes', 'woocommerce' ), 'primary', 'update_api_key', false ); ?>
<a style="color: #a00; text-decoration: none; margin-left: 10px;" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'revoke-key' => $key_id ), admin_url( 'admin.php?page=wc-settings&tab=api&section=keys' ) ), 'revoke' ) ); ?>"><?php _e( 'Revoke Key', 'woocommerce' ); ?></a>
</p>
<?php
}
?>
</div>

View File

@ -1,7 +1,7 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
exit;
}
?>

View File

@ -1,7 +1,7 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
exit;
}
$count_comments = wp_count_comments( $webhook->id );
@ -9,7 +9,7 @@ $total = $count_comments->approved;
?>
<?php echo $this->get_logs_navigation( $total, $webhook ); ?>
<?php echo WC_Admin_Webhooks::get_logs_navigation( $total, $webhook ); ?>
<table id="webhook-logs-table" class="widefat">
<thead>
@ -39,4 +39,4 @@ $total = $count_comments->approved;
</tbody>
</table>
<?php echo $this->get_logs_navigation( $total, $webhook ); ?>
<?php echo WC_Admin_Webhooks::get_logs_navigation( $total, $webhook ); ?>

View File

@ -44,7 +44,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<td class="forminp">
<select name="webhook_topic" id="webhook_topic" class="wc-enhanced-select">
<?php
$topic_data = $this->get_topic_data( $webhook );
$topic_data = WC_Admin_Webhooks::get_topic_data( $webhook );
$topics = apply_filters( 'woocommerce_webhook_topics', array(
'' => __( 'Select an option&hellip;', 'woocommerce' ),
@ -162,7 +162,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<div id="webhook-logs" class="settings-panel">
<h3><?php _e( 'Webhook Logs', 'woocommerce' ); ?></h3>
<?php $this->logs_output( $webhook ); ?>
<?php WC_Admin_Webhooks::logs_output( $webhook ); ?>
</div>
<script type="text/javascript">

View File

@ -19,6 +19,7 @@ $theme = wp_get_theme();
<h2>
<?php _e( 'WooCommerce Add-ons/Extensions', 'woocommerce' ); ?>
<a href="http://www.woothemes.com/product-category/woocommerce-extensions/" class="add-new-h2"><?php _e( 'Browse all extensions', 'woocommerce' ); ?></a>
<a href="http://www.woothemes.com/storefront/" class="add-new-h2"><?php _e( 'Need a theme? Try Storefront', 'woocommerce' ); ?></a>
</h2>
<?php if ( $addons ) : ?>
<ul class="subsubsub">

View File

@ -41,11 +41,6 @@ if ( ! defined( 'ABSPATH' ) ) {
<td class="help"><?php echo '<a href="#" class="help_tip" data-tip="' . esc_attr__( 'The version of WooCommerce installed on your site.', 'woocommerce' ) . '">[?]</a>'; ?></td>
<td><?php echo esc_html( WC()->version ); ?></td>
</tr>
<tr>
<td data-export-label="WC Database Version"><?php _e( 'WC Database Version', 'woocommerce' ); ?>:</td>
<td class="help"><?php echo '<a href="#" class="help_tip" data-tip="' . esc_attr__( 'The version of WooCommerce that the database is formatted for. This should be the same as your WooCommerce Version.', 'woocommerce' ) . '">[?]</a>'; ?></td>
<td><?php echo esc_html( get_option( 'woocommerce_db_version' ) ); ?></td>
</tr>
<tr>
<td data-export-label="Log Directory Writable"><?php _e( 'Log Directory Writable', 'woocommerce' ); ?>:</td>
<td class="help"><?php echo '<a href="#" class="help_tip" data-tip="' . esc_attr__( 'Several WooCommerce extensions can write logs which makes debugging problems easier. The directory must be writable for this to happen.', 'woocommerce' ) . '">[?]</a>'; ?></td>
@ -281,6 +276,43 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
</tbody>
</table>
<table class="wc_status_table widefat" cellspacing="0">
<thead>
<tr>
<th colspan="3" data-export-label="Database"><?php _e( 'Database', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<tr>
<td data-export-label="WC Database Version"><?php _e( 'WC Database Version', 'woocommerce' ); ?>:</td>
<td class="help"><?php echo '<a href="#" class="help_tip" data-tip="' . esc_attr__( 'The version of WooCommerce that the database is formatted for. This should be the same as your WooCommerce Version.', 'woocommerce' ) . '">[?]</a>'; ?></td>
<td><?php echo esc_html( get_option( 'woocommerce_db_version' ) ); ?></td>
</tr>
<tr>
<?php
$tables = array(
'woocommerce_attribute_taxonomies',
'woocommerce_termmeta',
'woocommerce_downloadable_product_permissions',
'woocommerce_order_items',
'woocommerce_order_itemmeta',
'woocommerce_tax_rates',
'woocommerce_tax_rate_locations'
);
foreach ( $tables as $table ) {
?>
<tr>
<td><?php echo esc_html( $table ); ?></td>
<td class="help">&nbsp;</td>
<td><?php echo $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s;", $wpdb->prefix . $table ) ) !== $wpdb->prefix . $table ? '<mark class="error">' . __( 'Table does not exist', 'woocommerce' ) . '</mark>' : '&#10004'; ?></td>
</tr>
<?php
}
?>
</tr>
</tbody>
</table>
<table class="wc_status_table widefat" cellspacing="0">
<thead>
<tr>

View File

@ -2,10 +2,11 @@
/**
* WooCommerce API Authentication Class
*
* @author WooThemes
* @category API
* @package WooCommerce/API
* @since 2.1
* @author WooThemes
* @category API
* @package WooCommerce/API
* @since 2.1.0
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -22,7 +23,7 @@ class WC_API_Authentication {
*/
public function __construct() {
// to disable authentication, hook into this filter at a later priority and return a valid WP_User
// To disable authentication, hook into this filter at a later priority and return a valid WP_User
add_filter( 'woocommerce_api_check_authentication', array( $this, 'authenticate' ), 0 );
}
@ -35,7 +36,7 @@ class WC_API_Authentication {
*/
public function authenticate( $user ) {
// allow access to the index by default
// Allow access to the index by default
if ( '/' === WC()->api->server->path ) {
return new WP_User( 0 );
}
@ -43,16 +44,17 @@ class WC_API_Authentication {
try {
if ( is_ssl() ) {
$user = $this->perform_ssl_authentication();
$keys = $this->perform_ssl_authentication();
} else {
$user = $this->perform_oauth_authentication();
$keys = $this->perform_oauth_authentication();
}
// check API key-specific permission
$this->check_api_key_permissions( $user );
// Check API key-specific permission
$this->check_api_key_permissions( $keys['permissions'] );
$user = $this->get_user_by_id( $keys['user_id'] );
} catch ( Exception $e ) {
$user = new WP_Error( 'woocommerce_api_authentication_error', $e->getMessage(), array( 'status' => $e->getCode() ) );
}
@ -66,22 +68,22 @@ class WC_API_Authentication {
* provided is valid
*
* @since 2.1
* @return WP_User
* @return array
* @throws Exception
*/
private function perform_ssl_authentication() {
$params = WC()->api->server->params['GET'];
// get consumer key
// Get consumer key
if ( ! empty( $_SERVER['PHP_AUTH_USER'] ) ) {
// should be in HTTP Auth header by default
// Should be in HTTP Auth header by default
$consumer_key = $_SERVER['PHP_AUTH_USER'];
} elseif ( ! empty( $params['consumer_key'] ) ) {
// allow a query string parameter as a fallback
// Allow a query string parameter as a fallback
$consumer_key = $params['consumer_key'];
} else {
@ -89,15 +91,15 @@ class WC_API_Authentication {
throw new Exception( __( 'Consumer Key is missing', 'woocommerce' ), 404 );
}
// get consumer secret
// Get consumer secret
if ( ! empty( $_SERVER['PHP_AUTH_PW'] ) ) {
// should be in HTTP Auth header by default
// Should be in HTTP Auth header by default
$consumer_secret = $_SERVER['PHP_AUTH_PW'];
} elseif ( ! empty( $params['consumer_secret'] ) ) {
// allow a query string parameter as a fallback
// Allow a query string parameter as a fallback
$consumer_secret = $params['consumer_secret'];
} else {
@ -105,13 +107,13 @@ class WC_API_Authentication {
throw new Exception( __( 'Consumer Secret is missing', 'woocommerce' ), 404 );
}
$user = $this->get_user_by_consumer_key( $consumer_key );
$keys = $this->get_keys_by_consumer_key( $consumer_key );
if ( ! $this->is_consumer_secret_valid( $user, $consumer_secret ) ) {
if ( ! $this->is_consumer_secret_valid( $keys['consumer_secret'], $consumer_secret ) ) {
throw new Exception( __( 'Consumer Secret is invalid', 'woocommerce' ), 401 );
}
return $user;
return $keys;
}
/**
@ -128,7 +130,7 @@ class WC_API_Authentication {
*
* @link http://tools.ietf.org/html/rfc5849 for the full spec
* @since 2.1
* @return WP_User
* @return array
* @throws Exception
*/
private function perform_oauth_authentication() {
@ -137,81 +139,97 @@ class WC_API_Authentication {
$param_names = array( 'oauth_consumer_key', 'oauth_timestamp', 'oauth_nonce', 'oauth_signature', 'oauth_signature_method' );
// check for required OAuth parameters
// Check for required OAuth parameters
foreach ( $param_names as $param_name ) {
if ( empty( $params[ $param_name ] ) )
if ( empty( $params[ $param_name ] ) ) {
throw new Exception( sprintf( __( '%s parameter is missing', 'woocommerce' ), $param_name ), 404 );
}
}
// fetch WP user by consumer key
$user = $this->get_user_by_consumer_key( $params['oauth_consumer_key'] );
// Fetch WP user by consumer key
$keys = $this->get_keys_by_consumer_key( $params['oauth_consumer_key'] );
// perform OAuth validation
$this->check_oauth_signature( $user, $params );
$this->check_oauth_timestamp_and_nonce( $user, $params['oauth_timestamp'], $params['oauth_nonce'] );
// Perform OAuth validation
$this->check_oauth_signature( $keys, $params );
$this->check_oauth_timestamp_and_nonce( $keys, $params['oauth_timestamp'], $params['oauth_nonce'] );
// authentication successful, return user
return $user;
// Authentication successful, return user
return $keys;
}
/**
* Return the user for the given consumer key
* Return the keys for the given consumer key
*
* @since 2.1
* @since 2.4.0
* @param string $consumer_key
* @return WP_User
* @return array
* @throws Exception
*/
private function get_user_by_consumer_key( $consumer_key ) {
private function get_keys_by_consumer_key( $consumer_key ) {
global $wpdb;
$user_query = new WP_User_Query(
array(
'meta_key' => 'woocommerce_api_consumer_key',
'meta_value' => $consumer_key,
)
);
$keys = $wpdb->get_row( $wpdb->prepare( "
SELECT *
FROM {$wpdb->prefix}woocommerce_api_keys
WHERE consumer_key = '%s'
", sanitize_text_field( $consumer_key ) ), ARRAY_A );
$users = $user_query->get_results();
if ( empty( $users[0] ) )
if ( empty( $keys ) ) {
throw new Exception( __( 'Consumer Key is invalid', 'woocommerce' ), 401 );
}
return $users[0];
return $keys;
}
/**
* Get user by ID
*
* @since 2.4.0
* @param int $user_id
* @return WC_User
*/
private function get_user_by_id( $user_id ) {
$user = get_user_by( 'id', $user_id );
if ( ! $user ) {
throw new Exception( __( 'API user is invalid', 'woocommerce' ), 401 );
}
return $user;
}
/**
* Check if the consumer secret provided for the given user is valid
*
* @since 2.1
* @param WP_User $user
* @param string $keys_consumer_secret
* @param string $consumer_secret
* @return bool
*/
private function is_consumer_secret_valid( WP_User $user, $consumer_secret ) {
return hash_equals( $user->woocommerce_api_consumer_secret, $consumer_secret );
private function is_consumer_secret_valid( $keys_consumer_secret, $consumer_secret ) {
return hash_equals( $keys_consumer_secret, $consumer_secret );
}
/**
* Verify that the consumer-provided request signature matches our generated signature, this ensures the consumer
* has a valid key/secret
*
* @param WP_User $user
* @param array $keys
* @param array $params the request parameters
* @throws Exception
*/
private function check_oauth_signature( $user, $params ) {
private function check_oauth_signature( $keys, $params ) {
$http_method = strtoupper( WC()->api->server->method );
$base_request_uri = rawurlencode( untrailingslashit( get_woocommerce_api_url( '' ) ) . WC()->api->server->path );
// get the signature provided by the consumer and remove it from the parameters prior to checking the signature
// Get the signature provided by the consumer and remove it from the parameters prior to checking the signature
$consumer_signature = rawurldecode( $params['oauth_signature'] );
unset( $params['oauth_signature'] );
// remove filters and convert them from array to strings to void normalize issues
// Remove filters and convert them from array to strings to void normalize issues
if ( isset( $params['filter'] ) ) {
$filters = $params['filter'];
unset( $params['filter'] );
@ -220,15 +238,15 @@ class WC_API_Authentication {
}
}
// normalize parameter key/values
// Normalize parameter key/values
$params = $this->normalize_parameters( $params );
// sort parameters
// Sort parameters
if ( ! uksort( $params, 'strcmp' ) ) {
throw new Exception( __( 'Invalid Signature - failed to sort parameters', 'woocommerce' ), 401 );
}
// form query string
// Form query string
$query_params = array();
foreach ( $params as $param_key => $param_value ) {
@ -244,7 +262,7 @@ class WC_API_Authentication {
$hash_algorithm = strtolower( str_replace( 'HMAC-', '', $params['oauth_signature_method'] ) );
$signature = base64_encode( hash_hmac( $hash_algorithm, $string_to_sign, $user->woocommerce_api_consumer_secret, true ) );
$signature = base64_encode( hash_hmac( $hash_algorithm, $string_to_sign, $keys['consumer_secret'], true ) );
if ( ! hash_equals( $signature, $consumer_signature ) ) {
throw new Exception( __( 'Invalid Signature - provided signature does not match', 'woocommerce' ), 401 );
@ -277,7 +295,7 @@ class WC_API_Authentication {
foreach ( $parameters as $key => $value ) {
// percent symbols (%) must be double-encoded
// Percent symbols (%) must be double-encoded
$key = str_replace( '%', '%25', rawurlencode( rawurldecode( $key ) ) );
$value = str_replace( '%', '%25', rawurlencode( rawurldecode( $value ) ) );
@ -294,48 +312,57 @@ class WC_API_Authentication {
* - A timestamp is valid if it is within 15 minutes of now
* - A nonce is valid if it has not been used within the last 15 minutes
*
* @param WP_User $user
* @param array $keys
* @param int $timestamp the unix timestamp for when the request was made
* @param string $nonce a unique (for the given user) 32 alphanumeric string, consumer-generated
* @throws Exception
*/
private function check_oauth_timestamp_and_nonce( $user, $timestamp, $nonce ) {
private function check_oauth_timestamp_and_nonce( $keys, $timestamp, $nonce ) {
global $wpdb;
$valid_window = 15 * 60; // 15 minute window
if ( ( $timestamp < time() - $valid_window ) || ( $timestamp > time() + $valid_window ) )
if ( ( $timestamp < time() - $valid_window ) || ( $timestamp > time() + $valid_window ) ) {
throw new Exception( __( 'Invalid timestamp', 'woocommerce' ) );
}
$used_nonces = $user->woocommerce_api_nonces;
$used_nonces = maybe_unserialize( $keys['nonces'] );
if ( empty( $used_nonces ) )
if ( empty( $used_nonces ) ) {
$used_nonces = array();
}
if ( in_array( $nonce, $used_nonces ) )
if ( in_array( $nonce, $used_nonces ) ) {
throw new Exception( __( 'Invalid nonce - nonce has already been used', 'woocommerce' ), 401 );
}
$used_nonces[ $timestamp ] = $nonce;
// remove expired nonces
foreach( $used_nonces as $nonce_timestamp => $nonce ) {
if ( $nonce_timestamp < ( time() - $valid_window ) )
// Remove expired nonces
foreach ( $used_nonces as $nonce_timestamp => $nonce ) {
if ( $nonce_timestamp < ( time() - $valid_window ) ) {
unset( $used_nonces[ $nonce_timestamp ] );
}
}
update_user_meta( $user->ID, 'woocommerce_api_nonces', $used_nonces );
$used_nonces = maybe_serialize( $used_nonces );
$wpdb->update(
$wpdb->prefix . 'woocommerce_api_keys',
array( 'nonces' => $used_nonces ),
array( 'key_id' => $keys['key_id'] ),
array( '%s' ),
array( '%d' )
);
}
/**
* Check that the API keys provided have the proper key-specific permissions to either read or write API resources
*
* @param WP_User $user
* @param string $key_permissions
* @throws Exception if the permission check fails
*/
public function check_api_key_permissions( $user ) {
$key_permissions = $user->woocommerce_api_key_permissions;
public function check_api_key_permissions( $key_permissions ) {
switch ( WC()->api->server->method ) {
case 'HEAD':

View File

@ -540,10 +540,13 @@ class WC_API_Orders extends WC_API_Resource {
return $id;
}
$data = apply_filters( 'woocommerce_api_edit_order_data', $data, $id, $this );
$data = apply_filters( 'woocommerce_api_edit_order_data', $data, $id, $this );
$order = wc_get_order( $id );
if ( empty( $order ) ) {
throw new WC_API_Exception( 'woocommerce_api_invalid_order_id', __( 'Order ID is invalid', 'woocommerce' ), 400 );
}
$order_args = array( 'order_id' => $order->id );
// customer note
@ -1045,10 +1048,14 @@ class WC_API_Orders extends WC_API_Resource {
throw new WC_API_Exception( 'woocommerce_invalid_fee_item', __( 'Fee title is required', 'woocommerce' ), 400 );
}
$order_fee = new stdClass();
$order_fee->id = sanitize_title( $fee['title'] );
$order_fee->name = $fee['title'];
$order_fee->amount = isset( $fee['total'] ) ? floatval( $fee['total'] ) : 0;
$order_fee = new stdClass();
$order_fee->id = sanitize_title( $fee['title'] );
$order_fee->name = $fee['title'];
$order_fee->amount = isset( $fee['total'] ) ? floatval( $fee['total'] ) : 0;
$order_fee->taxable = false;
$order_fee->tax = 0;
$order_fee->tax_data = array();
$order_fee->tax_class = '';
// if taxable, tax class and total are required
if ( isset( $fee['taxable'] ) && $fee['taxable'] ) {
@ -1059,8 +1066,6 @@ class WC_API_Orders extends WC_API_Resource {
$order_fee->taxable = true;
$order_fee->tax_class = $fee['tax_class'];
$order_fee->tax = 0;
$order_fee->tax_data = array();
if ( isset( $fee['total_tax'] ) ) {
$order_fee->tax = isset( $fee['total_tax'] ) ? wc_format_refund_total( $fee['total_tax'] ) : 0;

View File

@ -85,10 +85,7 @@ class WC_API_Products extends WC_API_Resource {
);
# GET /products/sku/<product sku>
/**
* Deprecated since 2.4.0
*/
$routes[ $this->base . '/sku/(?P<sku>\w+)' ] = array(
$routes[ $this->base . '/sku/(?P<sku>\w[\w\s\-]*)' ] = array(
array( array( $this, 'get_product_by_sku' ), WC_API_Server::READABLE ),
);

View File

@ -2,11 +2,11 @@
/**
* WooCommerce API Authentication Class
*
* @author WooThemes
* @category API
* @package WooCommerce/API
* @since 2.1
* @version 2.1
* @author WooThemes
* @category API
* @package WooCommerce/API
* @since 2.1.0
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -23,7 +23,7 @@ class WC_API_Authentication {
*/
public function __construct() {
// to disable authentication, hook into this filter at a later priority and return a valid WP_User
// To disable authentication, hook into this filter at a later priority and return a valid WP_User
add_filter( 'woocommerce_api_check_authentication', array( $this, 'authenticate' ), 0 );
}
@ -36,22 +36,25 @@ class WC_API_Authentication {
*/
public function authenticate( $user ) {
// allow access to the index by default
if ( '/' === WC()->api->server->path )
return new WP_User(0);
// Allow access to the index by default
if ( '/' === WC()->api->server->path ) {
return new WP_User( 0 );
}
try {
if ( is_ssl() )
$user = $this->perform_ssl_authentication();
else
$user = $this->perform_oauth_authentication();
if ( is_ssl() ) {
$keys = $this->perform_ssl_authentication();
} else {
$keys = $this->perform_oauth_authentication();
}
// check API key-specific permission
$this->check_api_key_permissions( $user );
// Check API key-specific permission
$this->check_api_key_permissions( $keys['permissions'] );
$user = $this->get_user_by_id( $keys['user_id'] );
} catch ( Exception $e ) {
$user = new WP_Error( 'woocommerce_api_authentication_error', $e->getMessage(), array( 'status' => $e->getCode() ) );
}
@ -65,22 +68,22 @@ class WC_API_Authentication {
* provided is valid
*
* @since 2.1
* @return WP_User
* @return array
* @throws Exception
*/
private function perform_ssl_authentication() {
$params = WC()->api->server->params['GET'];
// get consumer key
// Get consumer key
if ( ! empty( $_SERVER['PHP_AUTH_USER'] ) ) {
// should be in HTTP Auth header by default
// Should be in HTTP Auth header by default
$consumer_key = $_SERVER['PHP_AUTH_USER'];
} elseif ( ! empty( $params['consumer_key'] ) ) {
// allow a query string parameter as a fallback
// Allow a query string parameter as a fallback
$consumer_key = $params['consumer_key'];
} else {
@ -88,15 +91,15 @@ class WC_API_Authentication {
throw new Exception( __( 'Consumer Key is missing', 'woocommerce' ), 404 );
}
// get consumer secret
// Get consumer secret
if ( ! empty( $_SERVER['PHP_AUTH_PW'] ) ) {
// should be in HTTP Auth header by default
// Should be in HTTP Auth header by default
$consumer_secret = $_SERVER['PHP_AUTH_PW'];
} elseif ( ! empty( $params['consumer_secret'] ) ) {
// allow a query string parameter as a fallback
// Allow a query string parameter as a fallback
$consumer_secret = $params['consumer_secret'];
} else {
@ -104,13 +107,13 @@ class WC_API_Authentication {
throw new Exception( __( 'Consumer Secret is missing', 'woocommerce' ), 404 );
}
$user = $this->get_user_by_consumer_key( $consumer_key );
$keys = $this->get_keys_by_consumer_key( $consumer_key );
if ( ! $this->is_consumer_secret_valid( $user, $consumer_secret ) ) {
if ( ! $this->is_consumer_secret_valid( $keys['consumer_secret'], $consumer_secret ) ) {
throw new Exception( __( 'Consumer Secret is invalid', 'woocommerce' ), 401 );
}
return $user;
return $keys;
}
/**
@ -127,7 +130,7 @@ class WC_API_Authentication {
*
* @link http://tools.ietf.org/html/rfc5849 for the full spec
* @since 2.1
* @return WP_User
* @return array
* @throws Exception
*/
private function perform_oauth_authentication() {
@ -136,81 +139,97 @@ class WC_API_Authentication {
$param_names = array( 'oauth_consumer_key', 'oauth_timestamp', 'oauth_nonce', 'oauth_signature', 'oauth_signature_method' );
// check for required OAuth parameters
// Check for required OAuth parameters
foreach ( $param_names as $param_name ) {
if ( empty( $params[ $param_name ] ) )
if ( empty( $params[ $param_name ] ) ) {
throw new Exception( sprintf( __( '%s parameter is missing', 'woocommerce' ), $param_name ), 404 );
}
}
// fetch WP user by consumer key
$user = $this->get_user_by_consumer_key( $params['oauth_consumer_key'] );
// Fetch WP user by consumer key
$keys = $this->get_keys_by_consumer_key( $params['oauth_consumer_key'] );
// perform OAuth validation
$this->check_oauth_signature( $user, $params );
$this->check_oauth_timestamp_and_nonce( $user, $params['oauth_timestamp'], $params['oauth_nonce'] );
// Perform OAuth validation
$this->check_oauth_signature( $keys, $params );
$this->check_oauth_timestamp_and_nonce( $keys, $params['oauth_timestamp'], $params['oauth_nonce'] );
// authentication successful, return user
return $user;
// Authentication successful, return user
return $keys;
}
/**
* Return the user for the given consumer key
* Return the keys for the given consumer key
*
* @since 2.1
* @since 2.4.0
* @param string $consumer_key
* @return WP_User
* @return array
* @throws Exception
*/
private function get_user_by_consumer_key( $consumer_key ) {
private function get_keys_by_consumer_key( $consumer_key ) {
global $wpdb;
$user_query = new WP_User_Query(
array(
'meta_key' => 'woocommerce_api_consumer_key',
'meta_value' => $consumer_key,
)
);
$keys = $wpdb->get_row( $wpdb->prepare( "
SELECT *
FROM {$wpdb->prefix}woocommerce_api_keys
WHERE consumer_key = '%s'
", sanitize_text_field( $consumer_key ) ), ARRAY_A );
$users = $user_query->get_results();
if ( empty( $users[0] ) )
if ( empty( $keys ) ) {
throw new Exception( __( 'Consumer Key is invalid', 'woocommerce' ), 401 );
}
return $users[0];
return $keys;
}
/**
* Get user by ID
*
* @since 2.4.0
* @param int $user_id
* @return WC_User
*/
private function get_user_by_id( $user_id ) {
$user = get_user_by( 'id', $user_id );
if ( ! $user ) {
throw new Exception( __( 'API user is invalid', 'woocommerce' ), 401 );
}
return $user;
}
/**
* Check if the consumer secret provided for the given user is valid
*
* @since 2.1
* @param WP_User $user
* @param string $keys_consumer_secret
* @param string $consumer_secret
* @return bool
*/
private function is_consumer_secret_valid( WP_User $user, $consumer_secret ) {
return $user->woocommerce_api_consumer_secret === $consumer_secret;
private function is_consumer_secret_valid( $keys_consumer_secret, $consumer_secret ) {
return hash_equals( $keys_consumer_secret, $consumer_secret );
}
/**
* Verify that the consumer-provided request signature matches our generated signature, this ensures the consumer
* has a valid key/secret
*
* @param WP_User $user
* @param array $keys
* @param array $params the request parameters
* @throws Exception
*/
private function check_oauth_signature( $user, $params ) {
private function check_oauth_signature( $keys, $params ) {
$http_method = strtoupper( WC()->api->server->method );
$base_request_uri = rawurlencode( untrailingslashit( get_woocommerce_api_url( '' ) ) . WC()->api->server->path );
// get the signature provided by the consumer and remove it from the parameters prior to checking the signature
// Get the signature provided by the consumer and remove it from the parameters prior to checking the signature
$consumer_signature = rawurldecode( $params['oauth_signature'] );
unset( $params['oauth_signature'] );
// remove filters and convert them from array to strings to void normalize issues
// Remove filters and convert them from array to strings to void normalize issues
if ( isset( $params['filter'] ) ) {
$filters = $params['filter'];
unset( $params['filter'] );
@ -219,15 +238,15 @@ class WC_API_Authentication {
}
}
// normalize parameter key/values
// Normalize parameter key/values
$params = $this->normalize_parameters( $params );
// sort parameters
// Sort parameters
if ( ! uksort( $params, 'strcmp' ) ) {
throw new Exception( __( 'Invalid Signature - failed to sort parameters', 'woocommerce' ), 401 );
}
// form query string
// Form query string
$query_params = array();
foreach ( $params as $param_key => $param_value ) {
@ -243,9 +262,9 @@ class WC_API_Authentication {
$hash_algorithm = strtolower( str_replace( 'HMAC-', '', $params['oauth_signature_method'] ) );
$signature = base64_encode( hash_hmac( $hash_algorithm, $string_to_sign, $user->woocommerce_api_consumer_secret, true ) );
$signature = base64_encode( hash_hmac( $hash_algorithm, $string_to_sign, $keys['consumer_secret'], true ) );
if ( $signature !== $consumer_signature ) {
if ( ! hash_equals( $signature, $consumer_signature ) ) {
throw new Exception( __( 'Invalid Signature - provided signature does not match', 'woocommerce' ), 401 );
}
}
@ -276,7 +295,7 @@ class WC_API_Authentication {
foreach ( $parameters as $key => $value ) {
// percent symbols (%) must be double-encoded
// Percent symbols (%) must be double-encoded
$key = str_replace( '%', '%25', rawurlencode( rawurldecode( $key ) ) );
$value = str_replace( '%', '%25', rawurlencode( rawurldecode( $value ) ) );
@ -293,48 +312,57 @@ class WC_API_Authentication {
* - A timestamp is valid if it is within 15 minutes of now
* - A nonce is valid if it has not been used within the last 15 minutes
*
* @param WP_User $user
* @param array $keys
* @param int $timestamp the unix timestamp for when the request was made
* @param string $nonce a unique (for the given user) 32 alphanumeric string, consumer-generated
* @throws Exception
*/
private function check_oauth_timestamp_and_nonce( $user, $timestamp, $nonce ) {
private function check_oauth_timestamp_and_nonce( $keys, $timestamp, $nonce ) {
global $wpdb;
$valid_window = 15 * 60; // 15 minute window
if ( ( $timestamp < time() - $valid_window ) || ( $timestamp > time() + $valid_window ) )
if ( ( $timestamp < time() - $valid_window ) || ( $timestamp > time() + $valid_window ) ) {
throw new Exception( __( 'Invalid timestamp', 'woocommerce' ) );
}
$used_nonces = $user->woocommerce_api_nonces;
$used_nonces = maybe_unserialize( $keys['nonces'] );
if ( empty( $used_nonces ) )
if ( empty( $used_nonces ) ) {
$used_nonces = array();
}
if ( in_array( $nonce, $used_nonces ) )
if ( in_array( $nonce, $used_nonces ) ) {
throw new Exception( __( 'Invalid nonce - nonce has already been used', 'woocommerce' ), 401 );
}
$used_nonces[ $timestamp ] = $nonce;
// remove expired nonces
foreach( $used_nonces as $nonce_timestamp => $nonce ) {
if ( $nonce_timestamp < ( time() - $valid_window ) )
// Remove expired nonces
foreach ( $used_nonces as $nonce_timestamp => $nonce ) {
if ( $nonce_timestamp < ( time() - $valid_window ) ) {
unset( $used_nonces[ $nonce_timestamp ] );
}
}
update_user_meta( $user->ID, 'woocommerce_api_nonces', $used_nonces );
$used_nonces = maybe_serialize( $used_nonces );
$wpdb->update(
$wpdb->prefix . 'woocommerce_api_keys',
array( 'nonces' => $used_nonces ),
array( 'key_id' => $keys['key_id'] ),
array( '%s' ),
array( '%d' )
);
}
/**
* Check that the API keys provided have the proper key-specific permissions to either read or write API resources
*
* @param WP_User $user
* @param string $key_permissions
* @throws Exception if the permission check fails
*/
public function check_api_key_permissions( $user ) {
$key_permissions = $user->woocommerce_api_key_permissions;
public function check_api_key_permissions( $key_permissions ) {
switch ( WC()->api->server->method ) {
case 'HEAD':

View File

@ -250,7 +250,7 @@ class WC_AJAX {
define( 'WOOCOMMERCE_CHECKOUT', true );
}
if ( 0 == sizeof( WC()->cart->get_cart() ) ) {
if ( WC()->cart->is_empty() ) {
$data = array(
'fragments' => apply_filters( 'woocommerce_update_order_review_fragments', array(
'form.woocommerce-checkout' => '<div class="woocommerce-error">' . __( 'Sorry, your session has expired.', 'woocommerce' ) . ' <a href="' . home_url() . '" class="wc-backward">' . __( 'Return to homepage', 'woocommerce' ) . '</a></div>'
@ -586,12 +586,12 @@ class WC_AJAX {
$attribute_variation = $data['attribute_variation'];
}
$attribute_is_taxonomy = $data['attribute_is_taxonomy'];
$attribute_position = $data['attribute_position'];
$attribute_names_count = sizeof( $attribute_names );
$attribute_is_taxonomy = $data['attribute_is_taxonomy'];
$attribute_position = $data['attribute_position'];
$attribute_names_max_key = max( $attribute_names );
for ( $i = 0; $i < $attribute_names_count; $i++ ) {
if ( ! $attribute_names[ $i ] ) {
for ( $i = 0; $i <= $attribute_names_max_key; $i++ ) {
if ( empty( $attribute_names[ $i ] ) ) {
continue;
}

373
includes/class-wc-auth.php Normal file
View File

@ -0,0 +1,373 @@
<?php
/**
* WooCommerce Auth
*
* Handles wc-auth endpoint requests
*
* @author WooThemes
* @category API
* @package WooCommerce/API
* @since 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'WC_Auth' ) ) :
class WC_Auth {
/**
* Version
*/
const VERSION = 1;
/**
* Setup class
*
* @since 2.4.0
*/
public function __construct() {
// Add query vars
add_filter( 'query_vars', array( $this, 'add_query_vars' ), 0 );
// Register auth endpoint
add_action( 'init', array( __CLASS__, 'add_endpoint' ), 0 );
// Handle auth requests
add_action( 'parse_request', array( $this, 'handle_auth_requests' ), 0 );
}
/**
* Add query vars
*
* @since 2.4.0
*
* @param $vars
*
* @return string[]
*/
public function add_query_vars( $vars ) {
$vars[] = 'wc-auth-version';
$vars[] = 'wc-auth-route';
return $vars;
}
/**
* Add auth endpoint
*
* @since 2.4.0
*/
public static function add_endpoint() {
add_rewrite_rule( '^wc-auth/v([1]{1})/(.*)?', 'index.php?wc-auth-version=$matches[1]&wc-auth-route=$matches[2]', 'top' );
}
/**
* Get scope name.
*
* @since 2.4.0
*
* @param string $scope
*
* @return string
*/
protected function get_i18n_scope( $scope ) {
$permissions = array(
'read' => __( 'Read', 'woocommerce' ),
'write' => __( 'Write', 'woocommerce' ),
'read_write' => __( 'Read/Write', 'woocommerce' ),
);
return $permissions[ $scope ];
}
/**
* Return a list of permissions a scope allows
*
* @since 2.4.0
*
* @param string $scope
*
* @return array
*/
protected function get_permissions_in_scope( $scope ) {
$permissions = array();
switch ( $scope ) {
case 'read' :
$permissions[] = __( 'View coupons', 'woocommerce' );
$permissions[] = __( 'View customers', 'woocommerce' );
$permissions[] = __( 'View orders and sales reports', 'woocommerce' );
$permissions[] = __( 'View products', 'woocommerce' );
break;
case 'write' :
$permissions[] = __( 'Create webhooks', 'woocommerce' );
$permissions[] = __( 'Create coupons', 'woocommerce' );
$permissions[] = __( 'Create customers', 'woocommerce' );
$permissions[] = __( 'Create orders', 'woocommerce' );
$permissions[] = __( 'Create products', 'woocommerce' );
break;
case 'read_write' :
$permissions[] = __( 'Create webhooks', 'woocommerce' );
$permissions[] = __( 'View and manage coupons', 'woocommerce' );
$permissions[] = __( 'View and manage customers', 'woocommerce' );
$permissions[] = __( 'View and manage orders and sales reports', 'woocommerce' );
$permissions[] = __( 'View and manage products', 'woocommerce' );
break;
}
return $permissions;
}
/**
* Build auth urls
*
* @since 2.4.0
*
* @param array $data
* @param string $endpoint
*
* @return string
*/
protected function build_url( $data, $endpoint ) {
$url = wc_get_endpoint_url( 'wc-auth/v' . self::VERSION, $endpoint, get_home_url( '/' ) );
return add_query_arg( array(
'app_name' => wc_clean( $data['app_name'] ),
'user_id' => wc_clean( $data['user_id'] ),
'return_url' => urlencode( $data['return_url'] ),
'callback_url' => urlencode( $data['callback_url'] ),
'scope' => wc_clean( $data['scope'] ),
), $url );
}
/**
* Make validation
*
* @since 2.4.0
*/
protected function make_validation() {
$params = array(
'app_name',
'user_id',
'return_url',
'callback_url',
'scope'
);
foreach ( $params as $param ) {
if ( empty( $_REQUEST[ $param ] ) ) {
throw new Exception( sprintf( __( 'Missing parameter %s', 'woocommerce' ), $param ) );
}
}
if ( ! in_array( $_REQUEST['scope'], array( 'read', 'write', 'read_write' ) ) ) {
throw new Exception( sprintf( __( 'Invalid scope %s', 'woocommerce' ), wc_clean( $_REQUEST['scope'] ) ) );
}
foreach ( array( 'return_url', 'callback_url' ) as $param ) {
if ( false === filter_var( urldecode( $_REQUEST[ $param ] ), FILTER_VALIDATE_URL ) ) {
throw new Exception( sprintf( __( 'The %s is not a valid URL', 'woocommerce' ), $param ) );
}
}
if ( 0 !== stripos( urldecode( $_REQUEST['callback_url'] ), 'https://' ) ) {
throw new Exception( __( 'The callback_url need to be over SSL', 'woocommerce' ) );
}
}
/**
* Create keys.
*
* @since 2.4.0
*
* @param string $app_name
* @param string $app_user_id
* @param string $scope
*
* @return array
*/
protected function create_keys( $app_name, $app_user_id, $scope ) {
global $wpdb;
$description = sprintf( __( '%s - API %s (created on %s at %s).', 'woocommerce' ), wc_clean( $app_name ), $this->get_i18n_scope( $scope ), date_i18n( wc_date_format() ), date_i18n( wc_time_format() ) );
$user = wp_get_current_user();
// Created API keys.
$permissions = ( in_array( $scope, array( 'read', 'write', 'read_write' ) ) ) ? sanitize_text_field( $scope ) : 'read';
$consumer_key = 'ck_' . hash( 'md5', $user->user_login . date( 'U' ) . mt_rand() );
$consumer_secret = 'cs_' . hash( 'md5', $user->ID . date( 'U' ) . mt_rand() );
$wpdb->insert(
$wpdb->prefix . 'woocommerce_api_keys',
array(
'user_id' => $user->ID,
'description' => $description,
'permissions' => $permissions,
'consumer_key' => $consumer_key,
'consumer_secret' => $consumer_secret
),
array(
'%d',
'%s',
'%s',
'%s',
'%s'
)
);
return array(
'key_id' => $wpdb->insert_id,
'user_id' => $app_user_id,
'consumer_key' => $consumer_key,
'consumer_secret' => $consumer_secret,
'key_permissions' => $permissions
);
}
/**
* Post consumer data.
*
* @since 2.4.0
*
* @param array $consumer_data
* @param string $url
*
* @return bool
*/
protected function post_consumer_data( $consumer_data, $url ) {
$params = array(
'body' => json_encode( $consumer_data ),
'timeout' => 60,
'headers' => array(
'Content-Type' => 'application/xml;charset=' . get_bloginfo( 'charset' ),
)
);
$response = wp_safe_remote_post( esc_url_raw( urldecode( $url ) ), $params );
if ( is_wp_error( $response ) ) {
throw new Exception( $response->get_error_message() );
} else if ( 200 != $response['response']['code'] ) {
throw new Exception( __( 'An error occurred in the request and at the time were unable to send the consumer data', 'woocommerce' ) );
}
return true;
}
/**
* Handle auth requests
*
* @since 2.4.0
*/
public function handle_auth_requests() {
global $wp;
if ( ! empty( $_GET['wc-auth-version'] ) ) {
$wp->query_vars['wc-auth-version'] = $_GET['wc-auth-version'];
}
if ( ! empty( $_GET['wc-auth-route'] ) ) {
$wp->query_vars['wc-auth-route'] = $_GET['wc-auth-route'];
}
// wc-auth endpoint requests
if ( ! empty( $wp->query_vars['wc-auth-version'] ) && ! empty( $wp->query_vars['wc-auth-route'] ) ) {
$this->auth_endpoint( $wp->query_vars['wc-auth-route'] );
}
}
/**
* Auth endpoint
*
* @since 2.4.0
*
* @param string $route
*/
protected function auth_endpoint( $route ) {
ob_start();
$consumer_data = array();
try {
if ( 'yes' !== get_option( 'woocommerce_api_enabled' ) ) {
throw new Exception( __( 'API disabled!', 'woocommerce' ) );
}
$route = strtolower( wc_clean( $route ) );
$this->make_validation();
// Login endpoint
if ( 'login' == $route && ! is_user_logged_in() ) {
wc_get_template( 'auth/form-login.php', array(
'app_name' => $_REQUEST['app_name'],
'return_url' => add_query_arg( array( 'success' => 0, 'user_id' => wc_clean( $_REQUEST['user_id'] ) ), urldecode( $_REQUEST['return_url'] ) ),
'redirect_url' => $this->build_url( $_REQUEST, 'authorize' ),
) );
exit;
// Redirect with user is logged in
} else if ( 'login' == $route && is_user_logged_in() ) {
wp_redirect( esc_url_raw( $this->build_url( $_REQUEST, 'authorize' ) ) );
exit;
// Redirect with user is not logged in and trying to access the authorize endpoint
} else if ( 'authorize' == $route && ! is_user_logged_in() ) {
wp_redirect( esc_url_raw( $this->build_url( $_REQUEST, 'login' ) ) );
exit;
// Authorize endpoint
} else if ( 'authorize' == $route && current_user_can( 'manage_woocommerce' ) ) {
wc_get_template( 'auth/form-grant-access.php', array(
'app_name' => $_REQUEST['app_name'],
'return_url' => add_query_arg( array( 'success' => 0, 'user_id' => wc_clean( $_REQUEST['user_id'] ) ), urldecode( $_REQUEST['return_url'] ) ),
'scope' => $this->get_i18n_scope( wc_clean( $_REQUEST['scope'] ) ),
'permissions' => $this->get_permissions_in_scope( wc_clean( $_REQUEST['scope'] ) ),
'granted_url' => wp_nonce_url( $this->build_url( $_REQUEST, 'access_granted' ), 'wc_auth_grant_access', 'wc_auth_nonce' ),
'logout_url' => wp_logout_url( $this->build_url( $_REQUEST, 'login' ) ),
'user' => wp_get_current_user()
) );
exit;
// Granted access endpoint
} else if ( 'access_granted' == $route && current_user_can( 'manage_woocommerce' ) ) {
if ( ! isset( $_GET['wc_auth_nonce'] ) || ! wp_verify_nonce( $_GET['wc_auth_nonce'], 'wc_auth_grant_access' ) ) {
throw new Exception( __( 'Invalid nonce verification', 'woocommerce' ) );
}
$consumer_data = $this->create_keys( $_REQUEST['app_name'], $_REQUEST['user_id'], $_REQUEST['scope'] );
$response = $this->post_consumer_data( $consumer_data, $_REQUEST['callback_url'] );
if ( $response ) {
wp_redirect( esc_url_raw( add_query_arg( array( 'success' => 1, 'user_id' => wc_clean( $_REQUEST['user_id'] ) ), urldecode( $_REQUEST['return_url'] ) ) ) );
exit;
}
} else {
throw new Exception( __( 'You do not have permissions to access this page!', 'woocommerce' ) );
}
} catch ( Exception $e ) {
$this->maybe_delete_key( $consumer_data );
wp_die( sprintf( __( 'Error: %s', 'woocommerce' ), $e->getMessage() ), __( 'Access Denied', 'woocommerce' ), array( 'response' => 401 ) );
}
}
/**
* Maybe delete key
*
* @since 2.4.0
*
* @param array $key
*/
private function maybe_delete_key( $key ) {
global $wpdb;
if ( isset( $key['key_id'] ) ) {
$wpdb->delete( $wpdb->prefix . 'woocommerce_api_keys', array( 'key_id' => $key['key_id'] ), array( '%d' ) );
}
}
}
endif;
return new WC_Auth();

View File

@ -48,12 +48,52 @@ class WC_Cache_Helper {
$transient_value = get_transient( $transient_name );
if ( false === $transient_value || true === $refresh ) {
$transient_value = time();
set_transient( $transient_name, $transient_value );
self::delete_version_transients( $transient_value );
set_transient( $transient_name, $transient_value = time() );
}
return $transient_value;
}
/**
* When the transient version increases, this is used to remove all past transients to avoid filling the DB.
*
* Note; this only works on transients appended with the transient version, and when object caching is not being used.
*
* @since 2.3.10
*/
private static function delete_version_transients( $version ) {
if ( ! wp_using_ext_object_cache() ) {
global $wpdb;
$wpdb->query( $wpdb->prepare( "
DELETE a, b
FROM {$wpdb->options} a, {$wpdb->options} b
WHERE
( a.option_name LIKE %s OR a.option_name LIKE %s ) AND
a.option_name NOT LIKE '\_transient\_timeout\_%%' AND
a.option_name NOT LIKE '\_site\_transient\_timeout\_%%' AND
(
b.option_name = CONCAT(
'_transient_timeout_',
SUBSTRING(
a.option_name,
CHAR_LENGTH('_transient_') + 1
)
) OR
b.option_name = CONCAT(
'_site_transient_timeout_',
SUBSTRING(
a.option_name,
CHAR_LENGTH('_site_transient_') + 1
)
)
)
",
"\_transient\_%" . $version,
"\_site\_transient\_%" . $version
) );
}
}
/**
* Get the page name/id for a WC page
* @param string $wc_page

View File

@ -170,7 +170,7 @@ class WC_Cart {
*/
public function maybe_set_cart_cookies() {
if ( ! headers_sent() ) {
if ( sizeof( $this->cart_contents ) > 0 ) {
if ( ! $this->is_empty() ) {
$this->set_cart_cookies( true );
} elseif ( isset( $_COOKIE['woocommerce_items_in_cart'] ) ) {
$this->set_cart_cookies( false );
@ -256,7 +256,7 @@ class WC_Cart {
}
// Queue re-calc if subtotal is not set
if ( ( ! $this->subtotal && sizeof( $this->cart_contents ) > 0 ) || $update_cart_session ) {
if ( ( ! $this->subtotal && ! $this->is_empty() ) || $update_cart_session ) {
$this->calculate_totals();
}
}
@ -345,6 +345,15 @@ class WC_Cart {
return apply_filters( 'woocommerce_cart_contents_count', $this->cart_contents_count );
}
/**
* Checks if the cart is empty.
*
* @return bool
*/
public function is_empty() {
return 0 === sizeof( $this->get_cart() );
}
/**
* Check all cart items for errors.
*/
@ -603,7 +612,7 @@ class WC_Cart {
public function get_cross_sells() {
$cross_sells = array();
$in_cart = array();
if ( sizeof( $this->get_cart() ) > 0 ) {
if ( ! $this->is_empty() ) {
foreach ( $this->get_cart() as $cart_item_key => $values ) {
if ( $values['quantity'] > 0 ) {
$cross_sells = array_merge( $values['data']->get_cross_sells(), $cross_sells );
@ -947,7 +956,7 @@ class WC_Cart {
}
if ( did_action( 'wp' ) ) {
$this->set_cart_cookies( sizeof( $this->cart_contents ) > 0 );
$this->set_cart_cookies( ! $this->is_empty() );
}
do_action( 'woocommerce_add_to_cart', $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data );
@ -971,8 +980,9 @@ class WC_Cart {
*/
public function remove_cart_item( $cart_item_key ) {
if ( isset( $this->cart_contents[ $cart_item_key ] ) ) {
$remove = $this->cart_contents[ $cart_item_key ];
$this->removed_cart_contents[ $cart_item_key ] = $remove;
$this->removed_cart_contents[ $cart_item_key ] = $this->cart_contents[ $cart_item_key ];
do_action( 'woocommerce_remove_cart_item', $cart_item_key, $this );
unset( $this->cart_contents[ $cart_item_key ] );
@ -994,8 +1004,9 @@ class WC_Cart {
*/
public function restore_cart_item( $cart_item_key ) {
if ( isset( $this->removed_cart_contents[ $cart_item_key ] ) ) {
$restore = $this->removed_cart_contents[ $cart_item_key ];
$this->cart_contents[ $cart_item_key ] = $restore;
$this->cart_contents[ $cart_item_key ] = $this->removed_cart_contents[ $cart_item_key ];
do_action( 'woocommerce_restore_cart_item', $cart_item_key, $this );
unset( $this->removed_cart_contents[ $cart_item_key ] );
@ -1064,7 +1075,7 @@ class WC_Cart {
do_action( 'woocommerce_before_calculate_totals', $this );
if ( sizeof( $this->get_cart() ) == 0 ) {
if ( $this->is_empty() ) {
$this->set_session();
return;
}

View File

@ -363,7 +363,7 @@ class WC_Checkout {
do_action( 'woocommerce_before_checkout_process' );
if ( 0 === sizeof( WC()->cart->get_cart() ) ) {
if ( WC()->cart->is_empty() ) {
throw new Exception( sprintf( __( 'Sorry, your session has expired. <a href="%s" class="wc-backward">Return to homepage</a>', 'woocommerce' ), home_url() ) );
}
@ -652,8 +652,7 @@ class WC_Checkout {
$result = apply_filters( 'woocommerce_payment_successful_result', $result, $order_id );
if ( is_ajax() ) {
echo '<!--WC_START-->' . json_encode( $result ) . '<!--WC_END-->';
exit;
wp_send_json( $result );
} else {
wp_redirect( $result['redirect'] );
exit;
@ -678,13 +677,10 @@ class WC_Checkout {
// Redirect to success/confirmation/payment page
if ( is_ajax() ) {
echo '<!--WC_START-->' . json_encode(
array(
'result' => 'success',
'redirect' => apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', $return_url, $order )
)
) . '<!--WC_END-->';
exit;
wp_send_json( array(
'result' => 'success',
'redirect' => apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', $return_url, $order )
) );
} else {
wp_safe_redirect(
apply_filters( 'woocommerce_checkout_no_payment_needed_redirect', $return_url, $order )
@ -712,17 +708,16 @@ class WC_Checkout {
$messages = ob_get_clean();
}
echo '<!--WC_START-->' . json_encode(
array(
'result' => 'failure',
'messages' => isset( $messages ) ? $messages : '',
'refresh' => isset( WC()->session->refresh_totals ) ? 'true' : 'false',
'reload' => isset( WC()->session->reload_checkout ) ? 'true' : 'false'
)
) . '<!--WC_END-->';
$response = array(
'result' => 'failure',
'messages' => isset( $messages ) ? $messages : '',
'refresh' => isset( WC()->session->refresh_totals ) ? 'true' : 'false',
'reload' => isset( WC()->session->reload_checkout ) ? 'true' : 'false'
);
unset( WC()->session->refresh_totals, WC()->session->reload_checkout );
exit;
wp_send_json( $response );
}
}

View File

@ -21,10 +21,10 @@ class WC_Comments {
* Hook in methods.
*/
public static function init() {
// Rating posts
add_filter( 'preprocess_comment', array( __CLASS__, 'check_comment_rating' ), 0 );
add_action( 'comment_post', array( __CLASS__, 'add_comment_rating' ), 1 );
add_action( 'comment_moderation_recipients', array( __CLASS__, 'comment_moderation_recipients' ), 10, 2 );
// Clear transients
add_action( 'wp_update_comment_count', array( __CLASS__, 'clear_transients' ) );
@ -197,11 +197,24 @@ class WC_Comments {
if ( ! $_POST['rating'] || $_POST['rating'] > 5 || $_POST['rating'] < 0 ) {
return;
}
add_comment_meta( $comment_id, 'rating', (int) esc_attr( $_POST['rating'] ), true );
}
}
/**
* Modify recipient of review email.
* @return array
*/
public static function comment_moderation_recipients( $emails, $comment_id ) {
$comment = get_comment( $comment_id );
if ( $comment && 'product' === get_post_type( $comment->comment_post_ID ) ) {
$emails = array( get_option( 'admin_email' ) );
}
return $emails;
}
/**
* Clear transients for a review.
* @param int $post_id
@ -209,14 +222,8 @@ class WC_Comments {
public static function clear_transients( $post_id ) {
$post_id = absint( $post_id );
$transient_version = WC_Cache_Helper::get_transient_version( 'product' );
delete_transient( 'wc_average_rating_' . $post_id . $transient_version );
delete_transient( 'wc_rating_count_' . $post_id . $transient_version );
delete_transient( 'wc_rating_count_' . $post_id . '_1' . $transient_version );
delete_transient( 'wc_rating_count_' . $post_id . '_2' . $transient_version );
delete_transient( 'wc_rating_count_' . $post_id . '_3' . $transient_version );
delete_transient( 'wc_rating_count_' . $post_id . '_4' . $transient_version );
delete_transient( 'wc_rating_count_' . $post_id . '_5' . $transient_version );
delete_transient( 'wc_review_count_' . $post_id . $transient_version );
}

View File

@ -361,7 +361,7 @@ class WC_Coupon {
private function validate_product_ids() {
if ( sizeof( $this->product_ids ) > 0 ) {
$valid_for_cart = false;
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
if ( ! WC()->cart->is_empty() ) {
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( in_array( $cart_item['product_id'], $this->product_ids ) || in_array( $cart_item['variation_id'], $this->product_ids ) || in_array( $cart_item['data']->get_parent(), $this->product_ids ) ) {
$valid_for_cart = true;
@ -380,7 +380,7 @@ class WC_Coupon {
private function validate_product_categories() {
if ( sizeof( $this->product_categories ) > 0 ) {
$valid_for_cart = false;
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
if ( ! WC()->cart->is_empty() ) {
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product_cats = wp_get_post_terms( $cart_item['product_id'], 'product_cat', array( "fields" => "ids" ) );
if ( sizeof( array_intersect( $product_cats, $this->product_categories ) ) > 0 ) {
@ -401,7 +401,7 @@ class WC_Coupon {
if ( 'yes' === $this->exclude_sale_items && $this->is_type( array( 'fixed_product', 'percent_product' ) ) ) {
$valid_for_cart = false;
$product_ids_on_sale = wc_get_product_ids_on_sale();
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
if ( ! WC()->cart->is_empty() ) {
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( sizeof( array_intersect( array( absint( $cart_item['product_id'] ), absint( $cart_item['variation_id'] ), $cart_item['data']->get_parent() ), $product_ids_on_sale ) ) === 0 ) {
// not on sale
@ -433,7 +433,7 @@ class WC_Coupon {
// Exclude Products
if ( sizeof( $this->exclude_product_ids ) > 0 ) {
$valid_for_cart = true;
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
if ( ! WC()->cart->is_empty() ) {
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( in_array( $cart_item['product_id'], $this->exclude_product_ids ) || in_array( $cart_item['variation_id'], $this->exclude_product_ids ) || in_array( $cart_item['data']->get_parent(), $this->exclude_product_ids ) ) {
$valid_for_cart = false;
@ -452,7 +452,7 @@ class WC_Coupon {
private function validate_cart_excluded_product_categories() {
if ( sizeof( $this->exclude_product_categories ) > 0 ) {
$valid_for_cart = true;
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
if ( ! WC()->cart->is_empty() ) {
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product_cats = wp_get_post_terms( $cart_item['product_id'], 'product_cat', array( "fields" => "ids" ) );
@ -475,7 +475,7 @@ class WC_Coupon {
if ( $this->exclude_sale_items == 'yes' ) {
$valid_for_cart = true;
$product_ids_on_sale = wc_get_product_ids_on_sale();
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
if ( ! WC()->cart->is_empty() ) {
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( ! empty( $cart_item['variation_id'] ) ) {
if ( in_array( $cart_item['variation_id'], $product_ids_on_sale, true ) ) {
@ -734,7 +734,7 @@ class WC_Coupon {
case self::E_WC_COUPON_EXCLUDED_PRODUCTS:
// Store excluded products that are in cart in $products
$products = array();
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
if ( ! WC()->cart->is_empty() ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( in_array( $cart_item['product_id'], $this->exclude_product_ids ) || in_array( $cart_item['variation_id'], $this->exclude_product_ids ) || in_array( $cart_item['data']->get_parent(), $this->exclude_product_ids ) ) {
$products[] = $cart_item['data']->get_title();
@ -747,7 +747,7 @@ class WC_Coupon {
case self::E_WC_COUPON_EXCLUDED_CATEGORIES:
// Store excluded categories that are in cart in $categories
$categories = array();
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
if ( ! WC()->cart->is_empty() ) {
foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product_cats = wp_get_post_terms( $cart_item['product_id'], 'product_cat', array( "fields" => "ids" ) );

View File

@ -237,7 +237,7 @@ class WC_Form_Handler {
public static function checkout_action() {
if ( isset( $_POST['woocommerce_checkout_place_order'] ) || isset( $_POST['woocommerce_checkout_update_totals'] ) ) {
if ( sizeof( WC()->cart->get_cart() ) == 0 ) {
if ( WC()->cart->is_empty() ) {
wp_redirect( wc_get_page_permalink( 'cart' ) );
exit;
}
@ -385,7 +385,7 @@ class WC_Form_Handler {
$product = wc_get_product( $cart_item['product_id'] );
$undo = WC()->cart->get_undo_url( $cart_item_key );
wc_add_notice( sprintf( __( '%s removed. %sUndo?%s', 'woocommerce' ), $product ? $product->get_title() : __( 'Item', 'woocommerce' ), '<a href="' . esc_url( $undo ) . '">', '</a>' ) );
wc_add_notice( sprintf( __( '%s removed. %sUndo?%s', 'woocommerce' ), apply_filters( 'woocommerce_cart_item_removed_title', $product ? $product->get_title() : __( 'Item', 'woocommerce' ), $cart_item ), '<a href="' . esc_url( $undo ) . '">', '</a>' ) );
}
$referer = wp_get_referer() ? remove_query_arg( array( 'remove_item', 'add-to-cart', 'added-to-cart' ), add_query_arg( 'removed_item', '1', wp_get_referer() ) ) : WC()->cart->get_cart_url();
@ -410,7 +410,7 @@ class WC_Form_Handler {
$cart_updated = false;
$cart_totals = isset( $_POST['cart'] ) ? $_POST['cart'] : '';
if ( sizeof( WC()->cart->get_cart() ) > 0 && is_array( $cart_totals ) ) {
if ( ! WC()->cart->is_empty() && is_array( $cart_totals ) ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];

View File

@ -118,7 +118,7 @@ class WC_Frontend_Scripts {
self::register_script( 'select2', $assets_path . 'js/select2/select2' . $suffix . '.js', array( 'jquery' ), '3.5.2' );
// Register any scripts for later use, or used as dependencies
self::register_script( 'jquery-blockui', $assets_path . 'js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.60' );
self::register_script( 'jquery-blockui', $assets_path . 'js/jquery-blockui/jquery.blockUI' . $suffix . '.js', array( 'jquery' ), '2.70' );
self::register_script( 'jquery-payment', $assets_path . 'js/jquery-payment/jquery.payment' . $suffix . '.js', array( 'jquery' ), '1.2.1' );
self::register_script( 'jquery-cookie', $assets_path . 'js/jquery-cookie/jquery.cookie' . $suffix . '.js', array( 'jquery' ), '1.4.1' );
self::register_script( 'wc-credit-card-form', $frontend_script_path . 'credit-card-form' . $suffix . '.js', array( 'jquery', 'jquery-payment' ) );
@ -148,7 +148,7 @@ class WC_Frontend_Scripts {
self::enqueue_script( 'wc-lost-password', $frontend_script_path . 'lost-password' . $suffix . '.js', array( 'jquery', 'woocommerce' ) );
}
if ( $lightbox_en && ( is_product() || ( ! empty( $post->post_content ) && strstr( $post->post_content, '[product_page' ) ) ) ) {
self::enqueue_script( 'prettyPhoto', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto' . $suffix . '.js', array( 'jquery' ), '3.1.5', true );
self::enqueue_script( 'prettyPhoto', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto' . $suffix . '.js', array( 'jquery' ), '3.1.6', true );
self::enqueue_script( 'prettyPhoto-init', $assets_path . 'js/prettyPhoto/jquery.prettyPhoto.init' . $suffix . '.js', array( 'jquery','prettyPhoto' ) );
wp_enqueue_style( 'woocommerce_prettyPhoto_css', $assets_path . 'css/prettyPhoto.css' );
}
@ -214,7 +214,8 @@ class WC_Frontend_Scripts {
'option_guest_checkout' => get_option( 'woocommerce_enable_guest_checkout' ),
'checkout_url' => add_query_arg( 'action', 'woocommerce_checkout', WC()->ajax_url() ),
'is_checkout' => is_page( wc_get_page_id( 'checkout' ) ) && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) ? 1 : 0,
'debug_mode' => defined('WP_DEBUG') && WP_DEBUG
'debug_mode' => defined('WP_DEBUG') && WP_DEBUG,
'i18n_checkout_error' => esc_attr__( 'Error processing checkout. Please try again.', 'woocommerce' ),
);
break;
case 'wc-address-i18n' :

View File

@ -98,6 +98,7 @@ class WC_Install {
WC()->query->init_query_vars();
WC()->query->add_endpoints();
WC_API::add_endpoint();
WC_Auth::add_endpoint();
WC_AJAX::add_endpoint();
self::create_terms();
@ -324,6 +325,18 @@ class WC_Install {
}
return "
CREATE TABLE {$wpdb->prefix}woocommerce_api_keys (
key_id bigint(20) NOT NULL auto_increment,
user_id bigint(20) NOT NULL,
description longtext NULL,
permissions varchar(10) NOT NULL,
consumer_key varchar(200) NOT NULL,
consumer_secret varchar(200) NOT NULL,
nonces longtext NULL,
PRIMARY KEY (key_id),
KEY consumer_key (consumer_key),
KEY consumer_secret (consumer_secret)
) $collate;
CREATE TABLE {$wpdb->prefix}woocommerce_attribute_taxonomies (
attribute_id bigint(20) NOT NULL auto_increment,
attribute_name varchar(200) NOT NULL,

View File

@ -44,7 +44,7 @@ class WC_Order_Factory {
$classname = apply_filters( 'woocommerce_order_class', $classname, $post_type, $order_id, $the_order );
if ( ! class_exists( $classname ) ) {
$classname = 'WC_Order';
return false;
}
return new $classname( $the_order );

View File

@ -779,8 +779,8 @@ class WC_Shortcodes {
*/
public static function related_products( $atts ) {
$atts = shortcode_atts( array(
'posts_per_page' => '2',
'columns' => '2',
'posts_per_page' => '4',
'columns' => '4',
'orderby' => 'rand'
), $atts );

View File

@ -725,7 +725,7 @@ class WC_Webhook {
* @return string
*/
public function get_name() {
return apply_filters( 'woocommece_webhook_name', $this->get_post_data()->post_title, $this->id );
return apply_filters( 'woocommerce_webhook_name', $this->get_post_data()->post_title, $this->id );
}
/**

View File

@ -31,7 +31,7 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway {
$this->has_fields = false;
$this->order_button_text = __( 'Proceed to PayPal', 'woocommerce' );
$this->method_title = __( 'PayPal', 'woocommerce' );
$this->method_description = __( 'PayPal standard works by sending customers to PayPal where they can enter their payment information.', 'woocommerce' );
$this->method_description = sprintf( __( 'PayPal standard sends customers to PayPal to enter their payment information. PayPal IPN requires fsockopen/cURL support to update order statuses after payment. Check the %ssystem status%s page for more details.', 'woocommerce' ), '<a href="' . admin_url( 'admin.php?page=wc-status' ) . '">', '</a>' );
$this->supports = array(
'products',
'refunds'

View File

@ -62,5 +62,7 @@ abstract class WC_Gateway_Paypal_Response {
*/
protected function payment_on_hold( $order, $reason = '' ) {
$order->update_status( 'on-hold', $reason );
$order->reduce_order_stock();
WC()->cart->empty_cart();
}
}

View File

@ -10,7 +10,7 @@ if ( ! defined( 'ABSPATH' ) ) {
* A simple shipping method for free shipping
*
* @class WC_Shipping_Free_Shipping
* @version 2.3.0
* @version 2.4.0
* @package WooCommerce/Classes/Shipping
* @author WooThemes
*/
@ -23,11 +23,9 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
public $requires;
/**
* __construct function.
*
* @return void
* Constructor
*/
function __construct() {
public function __construct() {
$this->id = 'free_shipping';
$this->method_title = __( 'Free Shipping', 'woocommerce' );
$this->init();
@ -38,7 +36,7 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
*
* @return void
*/
function init() {
public function init() {
// Load the settings.
$this->init_form_fields();
@ -56,14 +54,10 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
/**
* Initialise Gateway Settings Form Fields
*
* @return void
*/
function init_form_fields() {
public function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'woocommerce' ),
@ -123,36 +117,12 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
);
}
/**
* Admin Panel Options
* - Options for bits like 'title' and availability on a country-by-country basis
*
* @since 1.0.0
* @return void
*/
public function admin_options() {
?>
<h3><?php _e( 'Free Shipping', 'woocommerce' ); ?></h3>
<table class="form-table">
<?php
// Generate the HTML For the settings form.
$this->generate_settings_html();
?>
</table><!--/.form-table-->
<?php
}
/**
* is_available function.
*
* @param mixed $package
* @param array $package
* @return bool
*/
function is_available( $package ) {
public function is_available( $package ) {
if ( 'no' == $this->enabled ) {
return false;
}
@ -184,7 +154,6 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
}
if ( in_array( $this->requires, array( 'min_amount', 'either', 'both' ) ) && isset( WC()->cart->cart_contents_total ) ) {
if ( WC()->cart->prices_include_tax ) {
$total = WC()->cart->cart_contents_total + array_sum( WC()->cart->taxes );
} else {
@ -225,13 +194,11 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $is_available, $package );
}
/**
* calculate_shipping function.
*
* @return array
*/
function calculate_shipping() {
public function calculate_shipping() {
$args = array(
'id' => $this->id,
'label' => $this->title,
@ -240,5 +207,4 @@ class WC_Shipping_Free_Shipping extends WC_Shipping_Method {
);
$this->add_rate( $args );
}
}

View File

@ -70,7 +70,7 @@ class WC_Shortcode_Cart {
// Calc totals
WC()->cart->calculate_totals();
if ( 0 === sizeof( WC()->cart->get_cart() ) ) {
if ( WC()->cart->is_empty() ) {
wc_get_template( 'cart/cart-empty.php' );
} else {
wc_get_template( 'cart/cart.php' );

View File

@ -205,7 +205,7 @@ class WC_Shortcode_Checkout {
wc_print_notices();
// Check cart has contents
if ( sizeof( WC()->cart->get_cart() ) == 0 ) {
if ( WC()->cart->is_empty() ) {
return;
}

View File

@ -12,5 +12,48 @@ if ( ! defined( 'ABSPATH' ) ) {
exit;
}
global $wpdb;
// Maintain the old coupon logic for upgrades
update_option( 'woocommerce_calc_discounts_sequentially', 'yes' );
/**
* Update the old user API keys to the new Apps keys
*/
$api_users = $wpdb->get_results( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = 'woocommerce_api_consumer_key'" );
$apps_keys = array();
// Get user data
foreach ( $api_users as $_user ) {
$user = get_userdata( $_user->user_id );
$apps_keys[] = array(
'user_id' => $user->ID,
'permission' => $user->woocommerce_api_key_permissions,
'consumer_key' => $user->woocommerce_api_consumer_key,
'consumer_secret' => $user->woocommerce_api_consumer_secret
);
}
if ( ! empty( $apps_keys ) ) {
// Create new apps
foreach ( $apps_keys as $app ) {
$wpdb->insert(
$wpdb->prefix . 'woocommerce_api_keys',
$app,
array(
'%d',
'%s',
'%s',
'%s'
)
);
}
// Delete old user keys from usermeta
foreach ( $api_users as $_user ) {
$user_id = intval( $_user->user_id );
delete_user_meta( $user_id, 'woocommerce_api_consumer_key' );
delete_user_meta( $user_id, 'woocommerce_api_consumer_secret' );
delete_user_meta( $user_id, 'woocommerce_api_key_permissions' );
}
}

View File

@ -29,7 +29,7 @@ function wc_template_redirect() {
}
// When on the checkout with an empty cart, redirect to cart page
elseif ( is_page( wc_get_page_id( 'checkout' ) ) && sizeof( WC()->cart->get_cart() ) == 0 && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) ) {
elseif ( is_page( wc_get_page_id( 'checkout' ) ) && WC()->cart->is_empty() && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) ) {
wp_redirect( wc_get_page_permalink( 'cart' ) );
exit;
}
@ -883,13 +883,14 @@ if ( ! function_exists( 'woocommerce_external_add_to_cart' ) ) {
function woocommerce_external_add_to_cart() {
global $product;
if ( ! $product->get_product_url() )
if ( ! $product->add_to_cart_url() ) {
return;
}
wc_get_template( 'single-product/add-to-cart/external.php', array(
'product_url' => $product->get_product_url(),
'button_text' => $product->single_add_to_cart_text()
) );
'product_url' => $product->add_to_cart_url(),
'button_text' => $product->single_add_to_cart_text()
) );
}
}
@ -1058,9 +1059,9 @@ if ( ! function_exists( 'woocommerce_output_related_products' ) ) {
function woocommerce_output_related_products() {
$args = array(
'posts_per_page' => 2,
'columns' => 2,
'orderby' => 'rand'
'posts_per_page' => 4,
'columns' => 4,
'orderby' => 'rand'
);
woocommerce_related_products( apply_filters( 'woocommerce_output_related_products_args', $args ) );
@ -1110,7 +1111,7 @@ if ( ! function_exists( 'woocommerce_upsell_display' ) ) {
* @param int $columns (default: 2)
* @param string $orderby (default: 'rand')
*/
function woocommerce_upsell_display( $posts_per_page = '-1', $columns = 2, $orderby = 'rand' ) {
function woocommerce_upsell_display( $posts_per_page = '-1', $columns = 4, $orderby = 'rand' ) {
wc_get_template( 'single-product/up-sells.php', array(
'posts_per_page' => $posts_per_page,
'orderby' => apply_filters( 'woocommerce_upsells_orderby', $orderby ),
@ -1491,9 +1492,9 @@ if ( ! function_exists( 'woocommerce_product_subcategories' ) ) {
}
echo $after;
}
return true;
return true;
}
}
}
@ -1944,3 +1945,23 @@ if ( ! function_exists( 'get_product_search_form' ) ) {
}
}
}
if ( ! function_exists( 'woocommerce_output_auth_header' ) ) {
/**
* Output the Auth header.
*/
function woocommerce_output_auth_header() {
wc_get_template( 'auth/header.php' );
}
}
if ( ! function_exists( 'woocommerce_output_auth_footer' ) ) {
/**
* Output the Auth footer.
*/
function woocommerce_output_auth_footer() {
wc_get_template( 'auth/footer.php' );
}
}

View File

@ -204,3 +204,12 @@ add_action( 'wp_footer', 'woocommerce_demo_store' );
add_action( 'woocommerce_view_order', 'woocommerce_order_details_table', 10 );
add_action( 'woocommerce_thankyou', 'woocommerce_order_details_table', 10 );
add_action( 'woocommerce_order_details_after_order_table', 'woocommerce_order_again_button' );
/**
* Auth
*
* @see woocommerce_output_auth_header()
* @see woocommerce_output_auth_footer()
*/
add_action( 'woocommerce_auth_page_header', 'woocommerce_output_auth_header', 10 );
add_action( 'woocommerce_auth_page_footer', 'woocommerce_output_auth_footer', 10 );

View File

@ -165,8 +165,8 @@ class WC_Widget_Price_Filter extends WC_Widget {
<div class="price_slider_wrapper">
<div class="price_slider" style="display:none;"></div>
<div class="price_slider_amount">
<input type="text" id="min_price" name="min_price" value="' . esc_attr( $min_price ) . '" data-min="' . esc_attr( apply_filters( 'woocommerce_price_filter_widget_amount', $min ) ) . '" placeholder="' . __('Min price', 'woocommerce' ) . '" />
<input type="text" id="max_price" name="max_price" value="' . esc_attr( $max_price ) . '" data-max="' . esc_attr( apply_filters( 'woocommerce_price_filter_widget_amount', $max ) ) . '" placeholder="' . __( 'Max price', 'woocommerce' ) . '" />
<input type="text" id="min_price" name="min_price" value="' . esc_attr( $min_price ) . '" data-min="' . esc_attr( apply_filters( 'woocommerce_price_filter_widget_min_amount', $min ) ) . '" placeholder="' . __('Min price', 'woocommerce' ) . '" />
<input type="text" id="max_price" name="max_price" value="' . esc_attr( $max_price ) . '" data-max="' . esc_attr( apply_filters( 'woocommerce_price_filter_widget_max_amount', $max ) ) . '" placeholder="' . __( 'Max price', 'woocommerce' ) . '" />
<button type="submit" class="button">' . __( 'Filter', 'woocommerce' ) . '</button>
<div class="price_label" style="display:none;">
' . __( 'Price:', 'woocommerce' ) . ' <span class="from"></span> &mdash; <span class="to"></span>

View File

@ -145,6 +145,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
* Tweak - Improve save_attributes ajax function to correctly save text attributes.
* Tweak - Base discounts on the undiscounted price. #5874
* Tweak - Added wc_product_cat_class functions.
* Tweak - Display related products and upsells in 4 columns.
= 2.3.8 - 20/04/2015 =
* Fix - Ensure coupon taxes are reset when calculating totals.

17
templates/auth/footer.php Normal file
View File

@ -0,0 +1,17 @@
<?php
/**
* Auth footer
*
* @author WooThemes
* @package WooCommerce/Templates/Auth
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
</div>
</body>
</html>

View File

@ -0,0 +1,38 @@
<?php
/**
* Auth form grant access
*
* @author WooThemes
* @package WooCommerce/Templates/Auth
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<?php do_action( 'woocommerce_auth_page_header' ); ?>
<h1><?php printf( __( '%s would like to connect to your store' , 'woocommerce' ), esc_html( $app_name ) ); ?></h1>
<?php wc_print_notices(); ?>
<p><?php printf( __( 'This will give "%s" <strong>%s</strong> access which will allow it to:' , 'woocommerce' ), esc_html( $app_name ), esc_html( $scope ) ); ?></p>
<ul class="wc-auth-permissions">
<?php foreach ( $permissions as $permission ) : ?>
<li><?php echo esc_html( $permission ); ?></li>
<?php endforeach; ?>
</ul>
<div class="wc-auth-logged-in-as">
<?php echo get_avatar( $user->ID, 70 ); ?>
<p><?php printf( __( 'Logged in as %s', 'woocommerce' ), esc_html( $user->display_name ) ); ?> <a href="<?php echo esc_url( $logout_url ); ?>" class="wc-auth-logout"><?php _e( 'Logout', 'woocommerce' ); ?></a>
</div>
<p class="wc-auth-actions">
<a href="<?php echo esc_url( $granted_url ); ?>" class="button button-primary wc-auth-approve"><?php _e( 'Approve', 'woocommerce' ); ?></a>
<a href="<?php echo esc_url( $return_url ); ?>" class="button wc-auth-deny"><?php _e( 'Deny', 'woocommerce' ); ?></a>
</p>
<?php do_action( 'woocommerce_auth_page_footer' ); ?>

View File

@ -0,0 +1,40 @@
<?php
/**
* Auth form login
*
* @author WooThemes
* @package WooCommerce/Templates/Auth
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<?php do_action( 'woocommerce_auth_page_header' ); ?>
<h1><?php printf( __( '%s would like to connect to your store' , 'woocommerce' ), esc_html( $app_name ) ); ?></h1>
<?php wc_print_notices(); ?>
<p><?php printf( __( 'To connect to %1$s you need to be logged in. Log in to your store below, or %2$scancel and return to %1$s%3$s', 'woocommerce' ), wc_clean( $app_name ), '<a href="' . esc_url( $return_url ) . '">', '</a>' ); ?></p>
<form method="post" class="wc-auth-login">
<p class="form-row form-row-wide">
<label for="username"><?php _e( 'Username or email address', 'woocommerce' ); ?> <span class="required">*</span></label>
<input type="text" class="input-text" name="username" id="username" value="<?php echo ( ! empty( $_POST['username'] ) ) ? esc_attr( $_POST['username'] ) : ''; ?>" />
</p>
<p class="form-row form-row-wide">
<label for="password"><?php _e( 'Password', 'woocommerce' ); ?> <span class="required">*</span></label>
<input class="input-text" type="password" name="password" id="password" />
</p>
<p class="wc-auth-actions">
<?php wp_nonce_field( 'woocommerce-login' ); ?>
<input type="submit" class="button button-large button-primary wc-auth-login-button" name="login" value="<?php _e( 'Login', 'woocommerce' ); ?>" />
<input type="hidden" name="redirect" value="<?php echo esc_url( $redirect_url ); ?>" />
</p>
</form>
<?php do_action( 'woocommerce_auth_page_footer' ); ?>

26
templates/auth/header.php Normal file
View File

@ -0,0 +1,26 @@
<?php
/**
* Auth header
*
* @author WooThemes
* @package WooCommerce/Templates/Auth
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?><!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="robots" content="noindex, nofollow" />
<title><?php _e( 'Application Authentication Request', 'woocommerce' ); ?></title>
<?php wp_admin_css( 'install', true ); ?>
<link rel="stylesheet" href="<?php echo esc_url( str_replace( array( 'http:', 'https:' ), '', WC()->plugin_url() ) . '/assets/css/auth.css' ); ?>" type="text/css" />
</head>
<body class="wc-auth wp-core-ui">
<h1 id="wc-logo"><img src="<?php echo WC()->plugin_url(); ?>/assets/images/woocommerce_logo.png" alt="WooCommerce" /></h1>
<div class="wc-auth-content">

View File

@ -56,7 +56,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<?php endforeach; ?>
<?php if ( WC()->cart->tax_display_cart == 'excl' ) : ?>
<?php if ( wc_tax_enabled() && WC()->cart->tax_display_cart == 'excl' ) : ?>
<?php if ( get_option( 'woocommerce_tax_total_display' ) == 'itemized' ) : ?>
<?php foreach ( WC()->cart->get_tax_totals() as $code => $tax ) : ?>
<tr class="tax-rate tax-rate-<?php echo sanitize_title( $code ); ?>">

View File

@ -2,9 +2,9 @@
/**
* Cart Page
*
* @author WooThemes
* @package WooCommerce/Templates
* @version 2.3.8
* @author WooThemes
* @package WooCommerce/Templates
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -52,26 +52,29 @@ do_action( 'woocommerce_before_cart' ); ?>
<?php
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
if ( ! $_product->is_visible() )
if ( ! $_product->is_visible() ) {
echo $thumbnail;
else
printf( '<a href="%s">%s</a>', $_product->get_permalink( $cart_item ), $thumbnail );
} else {
printf( '<a href="%s">%s</a>', esc_url( $_product->get_permalink( $cart_item ) ), $thumbnail );
}
?>
</td>
<td class="product-name">
<?php
if ( ! $_product->is_visible() )
echo apply_filters( 'woocommerce_cart_item_name', $_product->get_title(), $cart_item, $cart_item_key ) . '&nbsp;';
else
echo apply_filters( 'woocommerce_cart_item_name', sprintf( '<a href="%s">%s </a>', $_product->get_permalink( $cart_item ), $_product->get_title() ), $cart_item, $cart_item_key );
if ( ! $_product->is_visible() ) {
echo apply_filters( 'woocommerce_cart_item_name', esc_html( $_product->get_title() ), $cart_item, $cart_item_key ) . '&nbsp;';
} else {
echo apply_filters( 'woocommerce_cart_item_name', sprintf( '<a href="%s">%s </a>', esc_url( $_product->get_permalink( $cart_item ) ), esc_html( $_product->get_title() ) ), $cart_item, $cart_item_key );
}
// Meta data
echo WC()->cart->get_item_data( $cart_item );
// Backorder notification
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) )
echo '<p class="backorder_notification">' . __( 'Available on backorder', 'woocommerce' ) . '</p>';
// Backorder notification
if ( $_product->backorders_require_notification() && $_product->is_on_backorder( $cart_item['quantity'] ) ) {
echo '<p class="backorder_notification">' . esc_html__( 'Available on backorder', 'woocommerce' ) . '</p>';
}
?>
</td>
@ -119,7 +122,6 @@ do_action( 'woocommerce_before_cart' ); ?>
<label for="coupon_code"><?php _e( 'Coupon', 'woocommerce' ); ?>:</label> <input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="<?php _e( 'Coupon code', 'woocommerce' ); ?>" /> <input type="submit" class="button" name="apply_coupon" value="<?php _e( 'Apply Coupon', 'woocommerce' ); ?>" />
<?php do_action( 'woocommerce_cart_coupon' ); ?>
</div>
<?php } ?>

View File

@ -19,7 +19,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<ul class="cart_list product_list_widget <?php echo $args['list_class']; ?>">
<?php if ( sizeof( WC()->cart->get_cart() ) > 0 ) : ?>
<?php if ( ! WC()->cart->is_empty() ) : ?>
<?php
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
@ -58,7 +58,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</ul><!-- end product list -->
<?php if ( sizeof( WC()->cart->get_cart() ) > 0 ) : ?>
<?php if ( ! WC()->cart->is_empty() ) : ?>
<p class="total"><strong><?php _e( 'Subtotal', 'woocommerce' ); ?>:</strong> <?php echo WC()->cart->get_cart_subtotal(); ?></p>

View File

@ -75,7 +75,7 @@ if ( ! defined( 'ABSPATH' ) ) {
</tr>
<?php endforeach; ?>
<?php if ( WC()->cart->tax_display_cart === 'excl' ) : ?>
<?php if ( wc_tax_enabled() && WC()->cart->tax_display_cart === 'excl' ) : ?>
<?php if ( get_option( 'woocommerce_tax_total_display' ) === 'itemized' ) : ?>
<?php foreach ( WC()->cart->get_tax_totals() as $code => $tax ) : ?>
<tr class="tax-rate tax-rate-<?php echo sanitize_title( $code ); ?>">

View File

@ -4,9 +4,9 @@
*
* Override this template by copying it to yourtheme/woocommerce/content-product.php
*
* @author WooThemes
* @package WooCommerce/Templates
* @version 1.6.4
* @author WooThemes
* @package WooCommerce/Templates
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -16,26 +16,31 @@ if ( ! defined( 'ABSPATH' ) ) {
global $product, $woocommerce_loop;
// Store loop count we're currently on
if ( empty( $woocommerce_loop['loop'] ) )
if ( empty( $woocommerce_loop['loop'] ) ) {
$woocommerce_loop['loop'] = 0;
}
// Store column count for displaying the grid
if ( empty( $woocommerce_loop['columns'] ) )
if ( empty( $woocommerce_loop['columns'] ) ) {
$woocommerce_loop['columns'] = apply_filters( 'loop_shop_columns', 4 );
}
// Ensure visibility
if ( ! $product || ! $product->is_visible() )
if ( ! $product || ! $product->is_visible() ) {
return;
}
// Increase loop count
$woocommerce_loop['loop']++;
// Extra post classes
$classes = array();
if ( 0 == ( $woocommerce_loop['loop'] - 1 ) % $woocommerce_loop['columns'] || 1 == $woocommerce_loop['columns'] )
if ( 0 == ( $woocommerce_loop['loop'] - 1 ) % $woocommerce_loop['columns'] || 1 == $woocommerce_loop['columns'] ) {
$classes[] = 'first';
if ( 0 == $woocommerce_loop['loop'] % $woocommerce_loop['columns'] )
}
if ( 0 == $woocommerce_loop['loop'] % $woocommerce_loop['columns'] ) {
$classes[] = 'last';
}
?>
<li <?php post_class( $classes ); ?>>
@ -53,7 +58,7 @@ if ( 0 == $woocommerce_loop['loop'] % $woocommerce_loop['columns'] )
do_action( 'woocommerce_before_shop_loop_item_title' );
?>
<h3><?php the_title(); ?></h3>
<h3><?php echo esc_html( get_the_title() ); ?></h3>
<?php
/**

View File

@ -4,7 +4,7 @@
*
* @author WooThemes
* @package WooCommerce/Templates/Emails/HTML
* @version 2.0.0
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {

View File

@ -4,7 +4,7 @@
*
* @author WooThemes
* @package WooCommerce/Templates/Emails
* @version 1.6.4
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {

View File

@ -4,7 +4,7 @@
*
* @author WooThemes
* @package WooCommerce/Templates/Emails
* @version 1.6.4
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {

View File

@ -4,7 +4,7 @@
*
* @author WooThemes
* @package WooCommerce/Templates/Emails
* @version 1.6.4
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {

View File

@ -2,9 +2,9 @@
/**
* Email Header
*
* @author WooThemes
* @package WooCommerce/Templates/Emails
* @version 2.3.0
* @author WooThemes
* @package WooCommerce/Templates/Emails
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -13,13 +13,13 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
<!DOCTYPE html>
<html>
<html dir="<?php echo is_rtl() ? 'rtl' : 'ltr'?>">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title><?php echo get_bloginfo( 'name', 'display' ); ?></title>
</head>
<body <?php echo is_rtl() ? 'rightmargin' : 'leftmargin'; ?>="0" marginwidth="0" topmargin="0" marginheight="0" offset="0">
<div id="wrapper">
<div id="wrapper" dir="<?php echo is_rtl() ? 'rtl' : 'ltr'?>">
<table border="0" cellpadding="0" cellspacing="0" height="100%" width="100%">
<tr>
<td align="center" valign="top">

View File

@ -4,7 +4,7 @@
*
* @author WooThemes
* @package WooCommerce/Templates/Emails/Plain
* @version 2.0.0
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {

View File

@ -4,7 +4,7 @@
*
* @author WooThemes
* @package WooCommerce/Templates/Emails/Plain
* @version 2.0.0
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {

View File

@ -4,7 +4,7 @@
*
* @author WooThemes
* @package WooCommerce/Templates/Emails/Plain
* @version 2.0.0
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {

View File

@ -4,7 +4,7 @@
*
* @author WooThemes
* @package WooCommerce/Templates/Emails/Plain
* @version 2.2.0
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {

View File

@ -20,7 +20,7 @@ $rating = intval( get_comment_meta( $comment->comment_ID, 'rating', true ) );
<div id="comment-<?php comment_ID(); ?>" class="comment_container">
<?php echo get_avatar( $comment, apply_filters( 'woocommerce_review_gravatar_size', '60' ), '', get_comment_author_email( $comment->comment_ID ) ); ?>
<?php echo get_avatar( $comment, apply_filters( 'woocommerce_review_gravatar_size', '60' ), '' ); ?>
<div class="comment-text">

View File

@ -2,9 +2,9 @@
/**
* Single Product title
*
* @author WooThemes
* @package WooCommerce/Templates
* @version 1.6.4
* @author WooThemes
* @package WooCommerce/Templates
* @version 2.4.0
*/
if ( ! defined( 'ABSPATH' ) ) {
@ -12,4 +12,4 @@ if ( ! defined( 'ABSPATH' ) ) {
}
?>
<h1 itemprop="name" class="product_title entry-title"><?php the_title(); ?></h1>
<h1 itemprop="name" class="product_title entry-title"><?php echo esc_html( get_the_title() ); ?></h1>

View File

@ -35,11 +35,12 @@ if ( ! empty( $status_options['uninstall_data'] ) ) {
wp_trash_post( get_option( 'woocommerce_logout_page_id' ) );
// Tables
$wpdb->query( "DROP TABLE IF EXISTS " . $wpdb->prefix . "woocommerce_attribute_taxonomies" );
$wpdb->query( "DROP TABLE IF EXISTS " . $wpdb->prefix . "woocommerce_downloadable_product_permissions" );
$wpdb->query( "DROP TABLE IF EXISTS " . $wpdb->prefix . "woocommerce_termmeta" );
$wpdb->query( "DROP TABLE IF EXISTS " . $wpdb->prefix . "woocommerce_tax_rates" );
$wpdb->query( "DROP TABLE IF EXISTS " . $wpdb->prefix . "woocommerce_tax_rate_locations" );
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}woocommerce_api_keys" );
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}woocommerce_attribute_taxonomies" );
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}woocommerce_downloadable_product_permissions" );
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}woocommerce_termmeta" );
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}woocommerce_tax_rates" );
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}woocommerce_tax_rate_locations" );
// Delete options
$wpdb->query("DELETE FROM $wpdb->options WHERE option_name LIKE 'woocommerce_%';");
@ -47,6 +48,6 @@ if ( ! empty( $status_options['uninstall_data'] ) ) {
// Delete posts + data
$wpdb->query( "DELETE FROM {$wpdb->posts} WHERE post_type IN ( 'product', 'product_variation', 'shop_coupon', 'shop_order', 'shop_order_refund' );" );
$wpdb->query( "DELETE meta FROM {$wpdb->postmeta} meta LEFT JOIN {$wpdb->posts} posts ON posts.ID = meta.post_id WHERE posts.ID IS NULL;" );
$wpdb->query( "DROP TABLE IF EXISTS " . $wpdb->prefix . "woocommerce_order_items" );
$wpdb->query( "DROP TABLE IF EXISTS " . $wpdb->prefix . "woocommerce_order_itemmeta" );
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}woocommerce_order_items" );
$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}woocommerce_order_itemmeta" );
}

View File

@ -225,6 +225,7 @@ final class WooCommerce {
$this->query = include( 'includes/class-wc-query.php' ); // The main query class
$this->api = include( 'includes/class-wc-api.php' ); // API Class
include_once( 'includes/class-wc-auth.php' ); // Auth Class
include_once( 'includes/class-wc-post-types.php' ); // Registers post types
include_once( 'includes/abstracts/abstract-wc-product.php' ); // Products
include_once( 'includes/abstracts/abstract-wc-order.php' ); // Orders