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);

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

@ -2,11 +2,11 @@
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({
hook: 'rel', /* the attribute tag to use for prettyPhoto hooks. default: 'rel'. For HTML5, use "data-rel" or similar. */
@ -92,24 +92,24 @@
custom_markup: '',
social_tools: '<div class="twitter"><a href="http://twitter.com/share" class="twitter-share-button" data-count="none">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div><div class="facebook"><iframe src="//www.facebook.com/plugins/like.php?locale=en_US&href={location_href}&amp;layout=button_count&amp;show_faces=true&amp;width=500&amp;action=like&amp;font&amp;colorscheme=light&amp;height=23" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:500px; height:23px;" allowTransparency="true"></iframe></div>' /* html or false to disable */
}, pp_settings);
// Global variables accessible only by prettyPhoto
var matchedObjects = this, percentBased = false, pp_dimensions, pp_open,
// prettyPhoto container specific
pp_contentHeight, pp_contentWidth, pp_containerHeight, pp_containerWidth,
// Window size
windowHeight = $(window).height(), windowWidth = $(window).width(),
// Global elements
pp_slideshow;
doresize = true, scroll_pos = _get_scroll();
// Window/Keyboard events
$(window).unbind('resize.prettyphoto').bind('resize.prettyphoto',function(){ _center_overlay(); _resize_overlay(); });
if(pp_settings.keyboard_shortcuts) {
$(document).unbind('keydown.prettyphoto').bind('keydown.prettyphoto',function(e){
if(typeof $pp_pic_holder != 'undefined'){
@ -134,39 +134,39 @@
};
});
};
/**
* Initialize prettyPhoto.
*/
$.prettyPhoto.initialize = function() {
settings = pp_settings;
if(settings.theme == 'pp_default') settings.horizontal_padding = 16;
// Find out if the picture is part of a set
theRel = $(this).attr(settings.hook);
galleryRegExp = /\[(?:.*)\]/;
isSet = (galleryRegExp.exec(theRel)) ? true : false;
// Put the SRCs, TITLEs, ALTs into an array.
pp_images = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return $(n).attr('href'); }) : $.makeArray($(this).attr('href'));
pp_titles = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return ($(n).find('img').attr('alt')) ? $(n).find('img').attr('alt') : ""; }) : $.makeArray($(this).find('img').attr('alt'));
pp_descriptions = (isSet) ? jQuery.map(matchedObjects, function(n, i){ if($(n).attr(settings.hook).indexOf(theRel) != -1) return ($(n).attr('title')) ? $(n).attr('title') : ""; }) : $.makeArray($(this).attr('title'));
if(pp_images.length > settings.overlay_gallery_max) settings.overlay_gallery = false;
set_position = jQuery.inArray($(this).attr('href'), pp_images); // Define where in the array the clicked item is positionned
rel_index = (isSet) ? set_position : $("a["+settings.hook+"^='"+theRel+"']").index($(this));
_build_overlay(this); // Build the overlay {this} being the caller
if(settings.allow_resize)
$(window).bind('scroll.prettyphoto',function(){ _center_overlay(); });
$.prettyPhoto.open();
return false;
}
@ -187,22 +187,22 @@
set_position = (arguments[3])? arguments[3]: 0;
_build_overlay(event.target); // Build the overlay {this} being the caller
}
if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','hidden'); // Hide the flash
_checkPosition($(pp_images).size()); // Hide the next/previous links if on first or last images.
$('.pp_loaderIcon').show();
if(settings.deeplinking)
setHashtag();
// Rebuild Facebook Like Button with updated href
if(settings.social_tools){
facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
$pp_pic_holder.find('.pp_social').html(facebook_like_link);
}
// Fade the content in
if($ppt.is(':hidden')) $ppt.css('opacity',0).show();
$pp_overlay.show().fadeTo(settings.animation_speed,settings.opacity);
@ -216,24 +216,24 @@
}else{
$pp_pic_holder.find('.pp_description').hide();
}
// Get the dimensions
movie_width = ( parseFloat(getParam('width',pp_images[set_position])) ) ? getParam('width',pp_images[set_position]) : settings.default_width.toString();
movie_height = ( parseFloat(getParam('height',pp_images[set_position])) ) ? getParam('height',pp_images[set_position]) : settings.default_height.toString();
// If the size is % based, calculate according to window dimensions
percentBased=false;
if(movie_height.indexOf('%') != -1) { movie_height = parseFloat(($(window).height() * parseFloat(movie_height) / 100) - 150); percentBased = true; }
if(movie_width.indexOf('%') != -1) { movie_width = parseFloat(($(window).width() * parseFloat(movie_width) / 100) - 150); percentBased = true; }
// Fade the holder
$pp_pic_holder.fadeIn(function(){
// Set the title
(settings.show_title && pp_titles[set_position] != "" && typeof pp_titles[set_position] != "undefined") ? $ppt.html(unescape(pp_titles[set_position])) : $ppt.html('&nbsp;');
imgPreloader = "";
skipInjection = false;
// Inject the proper content
switch(_getFileType(pp_images[set_position])){
case 'image':
@ -258,16 +258,16 @@
alert('Image cannot be loaded. Make sure the path is correct and image exist.');
$.prettyPhoto.close();
};
imgPreloader.src = pp_images[set_position];
break;
case 'youtube':
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
// Regular youtube link
movie_id = getParam('v',pp_images[set_position]);
// youtu.be link
if(movie_id == ""){
movie_id = pp_images[set_position].split('youtu.be/');
@ -281,75 +281,75 @@
movie = 'http://www.youtube.com/embed/'+movie_id;
(getParam('rel',pp_images[set_position])) ? movie+="?rel="+getParam('rel',pp_images[set_position]) : movie+="?rel=1";
if(settings.autoplay) movie += "&autoplay=1";
toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);
break;
case 'vimeo':
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
movie_id = pp_images[set_position];
var regExp = /http(s?):\/\/(www\.)?vimeo.com\/(\d+)/;
var match = movie_id.match(regExp);
movie = 'http://player.vimeo.com/video/'+ match[3] +'?title=0&amp;byline=0&amp;portrait=0';
if(settings.autoplay) movie += "&autoplay=1;";
vimeo_width = pp_dimensions['width'] + '/embed/?moog_width='+ pp_dimensions['width'];
toInject = settings.iframe_markup.replace(/{width}/g,vimeo_width).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,movie);
break;
case 'quicktime':
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
pp_dimensions['height']+=15; pp_dimensions['contentHeight']+=15; pp_dimensions['containerHeight']+=15; // Add space for the control bar
toInject = settings.quicktime_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,pp_images[set_position]).replace(/{autoplay}/g,settings.autoplay);
break;
case 'flash':
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
flash_vars = pp_images[set_position];
flash_vars = flash_vars.substring(pp_images[set_position].indexOf('flashvars') + 10,pp_images[set_position].length);
filename = pp_images[set_position];
filename = filename.substring(0,filename.indexOf('?'));
toInject = settings.flash_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,filename+'?'+flash_vars);
break;
case 'iframe':
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
frame_url = pp_images[set_position];
frame_url = frame_url.substr(0,frame_url.indexOf('iframe')-1);
toInject = settings.iframe_markup.replace(/{width}/g,pp_dimensions['width']).replace(/{height}/g,pp_dimensions['height']).replace(/{path}/g,frame_url);
break;
case 'ajax':
doresize = false; // Make sure the dimensions are not resized.
pp_dimensions = _fitToViewport(movie_width,movie_height);
doresize = true; // Reset the dimensions
skipInjection = true;
$.get(pp_images[set_position],function(responseHTML){
toInject = settings.inline_markup.replace(/{content}/g,responseHTML);
$pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
_showContent();
});
break;
case 'custom':
pp_dimensions = _fitToViewport(movie_width,movie_height); // Fit item to viewport
toInject = settings.custom_markup;
break;
case 'inline':
// to get the item height clone it, apply default width, wrap it in the prettyPhoto containers , then delete
myClone = $(pp_images[set_position]).clone().append('<br clear="all" />').css({'width':settings.default_width}).wrapInner('<div id="pp_full_res"><div class="pp_inline"></div></div>').appendTo($('body')).show();
@ -363,7 +363,7 @@
if(!imgPreloader && !skipInjection){
$pp_pic_holder.find('#pp_full_res')[0].innerHTML = toInject;
// Show content
_showContent();
};
@ -372,14 +372,14 @@
return false;
};
/**
* Change page in the prettyPhoto modal box
* @param direction {String} Direction of the paging, previous or next.
*/
$.prettyPhoto.changePage = function(direction){
currentGalleryPage = 0;
if(direction == 'previous') {
set_position--;
if (set_position < 0) set_position = $(pp_images).size()-1;
@ -389,7 +389,7 @@
}else{
set_position=direction;
};
rel_index = set_position;
if(!doresize) doresize = true; // Allow the resizing of the images
@ -417,7 +417,7 @@
}else{
currentGalleryPage = direction;
};
slide_speed = (direction == 'next' || direction == 'previous') ? settings.animation_speed : 0;
slide_to = currentGalleryPage * (itemsPerPage * itemWidth);
@ -437,7 +437,7 @@
});
pp_slideshow = setInterval($.prettyPhoto.startSlideshow,settings.slideshow);
}else{
$.prettyPhoto.changePage('next');
$.prettyPhoto.changePage('next');
};
}
@ -460,33 +460,33 @@
*/
$.prettyPhoto.close = function(){
if($pp_overlay.is(":animated")) return;
$.prettyPhoto.stopSlideshow();
$pp_pic_holder.stop().find('object,embed').css('visibility','hidden');
$('div.pp_pic_holder,div.ppt,.pp_fade').fadeOut(settings.animation_speed,function(){ $(this).remove(); });
$pp_overlay.fadeOut(settings.animation_speed, function(){
if(settings.hideflash) $('object,embed,iframe[src*=youtube],iframe[src*=vimeo]').css('visibility','visible'); // Show the flash
$(this).remove(); // No more need for the prettyPhoto markup
$(window).unbind('scroll.prettyphoto');
clearHashtag();
settings.callback();
doresize = true;
pp_open = false;
delete settings;
});
};
/**
* Set the proper sizes on the containers and animate the content in.
*/
@ -505,7 +505,7 @@
height:pp_dimensions['contentHeight'],
width:pp_dimensions['contentWidth']
},settings.animation_speed);
// Resize picture the holder
$pp_pic_holder.animate({
'top': projectedTop,
@ -518,7 +518,7 @@
// Show the nav
if(isSet && _getFileType(pp_images[set_position])=="image") { $pp_pic_holder.find('.pp_hoverContainer').show(); }else{ $pp_pic_holder.find('.pp_hoverContainer').hide(); }
if(settings.allow_expand) {
if(pp_dimensions['resized']){ // Fade the resizing link if the image is resized
$('a.pp_expand,a.pp_contract').show();
@ -526,18 +526,18 @@
$('a.pp_expand').hide();
}
}
if(settings.autoplay_slideshow && !pp_slideshow && !pp_open) $.prettyPhoto.startSlideshow();
settings.changepicturecallback(); // Callback!
pp_open = true;
});
_insert_gallery();
pp_settings.ajaxcallback();
};
/**
* Hide the content...DUH!
*/
@ -546,11 +546,11 @@
$pp_pic_holder.find('#pp_full_res object,#pp_full_res embed').css('visibility','hidden');
$pp_pic_holder.find('.pp_fade').fadeOut(settings.animation_speed,function(){
$('.pp_loaderIcon').show();
callback();
});
};
/**
* Check the item position in the gallery array, hide or show the navigation links
* @param setCount {integer} The total number of items in the set
@ -558,7 +558,7 @@
function _checkPosition(setCount){
(setCount > 1) ? $('.pp_nav').show() : $('.pp_nav').hide(); // Hide the bottom nav if it's not a set.
};
/**
* Resize the item dimensions if it's bigger than the viewport
* @param width {integer} Width of the item to be opened
@ -569,13 +569,13 @@
resized = false;
_getDimensions(width,height);
// Define them in case there's no resize needed
imageWidth = width, imageHeight = height;
if( ((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)) && doresize && settings.allow_resize && !percentBased) {
resized = true, fitting = false;
while (!fitting){
if((pp_containerWidth > windowWidth)){
imageWidth = (windowWidth - 200);
@ -589,16 +589,16 @@
pp_containerHeight = imageHeight, pp_containerWidth = imageWidth;
};
if((pp_containerWidth > windowWidth) || (pp_containerHeight > windowHeight)){
_fitToViewport(pp_containerWidth,pp_containerHeight)
};
_getDimensions(imageWidth,imageHeight);
};
return {
width:Math.floor(imageWidth),
height:Math.floor(imageHeight),
@ -609,7 +609,7 @@
resized:resized
};
};
/**
* Get the containers dimensions according to the item size
* @param width {integer} Width of the item to be opened
@ -618,12 +618,12 @@
function _getDimensions(width,height){
width = parseFloat(width);
height = parseFloat(height);
// Get the details height, to do so, I need to clone it since it's invisible
$pp_details = $pp_pic_holder.find('.pp_details');
$pp_details.width(width);
detailsHeight = parseFloat($pp_details.css('marginTop')) + parseFloat($pp_details.css('marginBottom'));
$pp_details = $pp_details.clone().addClass(settings.theme).width(width).appendTo($('body')).css({
'position':'absolute',
'top':-10000
@ -631,7 +631,7 @@
detailsHeight += $pp_details.height();
detailsHeight = (detailsHeight <= 34) ? 36 : detailsHeight; // Min-height for the details
$pp_details.remove();
// Get the titles height, to do so, I need to clone it since it's invisible
$pp_title = $pp_pic_holder.find('.ppt');
$pp_title.width(width);
@ -642,20 +642,20 @@
});
titleHeight += $pp_title.height();
$pp_title.remove();
// Get the container size, to resize the holder to the right dimensions
pp_contentHeight = height + detailsHeight;
pp_contentWidth = width;
pp_containerHeight = pp_contentHeight + titleHeight + $pp_pic_holder.find('.pp_top').height() + $pp_pic_holder.find('.pp_bottom').height();
pp_containerWidth = width;
}
function _getFileType(itemSrc){
if (itemSrc.match(/youtube\.com\/watch/i) || itemSrc.match(/youtu\.be/i)) {
return 'youtube';
}else if (itemSrc.match(/vimeo\.com/i)) {
return 'vimeo';
}else if(itemSrc.match(/\b.mov\b/i)){
}else if(itemSrc.match(/\b.mov\b/i)){
return 'quicktime';
}else if(itemSrc.match(/\b.swf\b/i)){
return 'flash';
@ -671,7 +671,7 @@
return 'image';
};
};
function _center_overlay(){
if(doresize && typeof $pp_pic_holder != 'undefined') {
scroll_pos = _get_scroll();
@ -679,7 +679,7 @@
projectedTop = (windowHeight/2) + scroll_pos['scrollTop'] - (contentHeight/2);
if(projectedTop < 0) projectedTop = 0;
if(contentHeight > windowHeight)
return;
@ -689,7 +689,7 @@
});
};
};
function _get_scroll(){
if (self.pageYOffset) {
return {scrollTop:self.pageYOffset,scrollLeft:self.pageXOffset};
@ -699,18 +699,18 @@
return {scrollTop:document.body.scrollTop,scrollLeft:document.body.scrollLeft};
};
};
function _resize_overlay() {
windowHeight = $(window).height(), windowWidth = $(window).width();
if(typeof $pp_overlay != "undefined") $pp_overlay.height($(document).height()).width(windowWidth);
};
function _insert_gallery(){
if(isSet && settings.overlay_gallery && _getFileType(pp_images[set_position])=="image") {
itemWidth = 52+5; // 52 beign the thumb width, 5 being the right margin.
navWidth = (settings.theme == "facebook" || settings.theme == "pp_default") ? 50 : 30; // Define the arrow width depending on the theme
itemsPerPage = Math.floor((pp_dimensions['containerWidth'] - 100 - navWidth) / itemWidth);
itemsPerPage = (itemsPerPage < pp_images.length) ? itemsPerPage : pp_images.length;
totalPage = Math.ceil(pp_images.length / itemsPerPage) - 1;
@ -725,36 +725,36 @@
galleryWidth = itemsPerPage * itemWidth;
fullGalleryWidth = pp_images.length * itemWidth;
// Set the proper width to the gallery items
$pp_gallery
.css('margin-left',-((galleryWidth/2) + (navWidth/2)))
.find('div:first').width(galleryWidth+5)
.find('ul').width(fullGalleryWidth)
.find('li.selected').removeClass('selected');
goToPage = (Math.floor(set_position/itemsPerPage) < totalPage) ? Math.floor(set_position/itemsPerPage) : totalPage;
$.prettyPhoto.changeGalleryPage(goToPage);
$pp_gallery_li.filter(':eq('+set_position+')').addClass('selected');
}else{
$pp_pic_holder.find('.pp_content').unbind('mouseenter mouseleave');
// $pp_gallery.hide();
}
}
function _build_overlay(caller){
// Inject Social Tool markup into General markup
if(settings.social_tools)
facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
settings.markup = settings.markup.replace('{pp_social}','');
$(document.body).append(settings.markup); // Inject the markup
facebook_like_link = settings.social_tools.replace('{location_href}', encodeURIComponent(location.href));
settings.markup = settings.markup.replace('{pp_social}','');
$('body').append(settings.markup); // Inject the markup
$pp_pic_holder = $('.pp_pic_holder') , $ppt = $('.ppt'), $pp_overlay = $('div.pp_overlay'); // Set my global selectors
// Inject the inline gallery!
if(isSet && settings.overlay_gallery) {
currentGalleryPage = 0;
@ -769,25 +769,25 @@
}
toInject += "<li class='"+classname+"'><a href='#'><img src='" + img_src + "' width='50' alt='' /></a></li>";
};
toInject = settings.gallery_markup.replace(/{gallery}/g,toInject);
$pp_pic_holder.find('#pp_full_res').after(toInject);
$pp_gallery = $('.pp_pic_holder .pp_gallery'), $pp_gallery_li = $pp_gallery.find('li'); // Set the gallery selectors
$pp_gallery.find('.pp_arrow_next').click(function(){
$.prettyPhoto.changeGalleryPage('next');
$.prettyPhoto.stopSlideshow();
return false;
});
$pp_gallery.find('.pp_arrow_previous').click(function(){
$.prettyPhoto.changeGalleryPage('previous');
$.prettyPhoto.stopSlideshow();
return false;
});
$pp_pic_holder.find('.pp_content').hover(
function(){
$pp_pic_holder.find('.pp_gallery:not(.disabled)').fadeIn();
@ -807,8 +807,8 @@
});
});
};
// Inject the play/pause if it's a slideshow
if(settings.slideshow){
$pp_pic_holder.find('.pp_nav').prepend('<a href="#" class="pp_play">Play</a>')
@ -817,9 +817,9 @@
return false;
});
}
$pp_pic_holder.attr('class','pp_pic_holder ' + settings.theme); // Set the proper theme
$pp_overlay
.css({
'opacity':0,
@ -843,31 +843,31 @@
$(this).removeClass('pp_contract').addClass('pp_expand');
doresize = true;
};
_hideContent(function(){ $.prettyPhoto.open(); });
return false;
});
}
$pp_pic_holder.find('.pp_previous, .pp_nav .pp_arrow_previous').bind('click',function(){
$.prettyPhoto.changePage('previous');
$.prettyPhoto.stopSlideshow();
return false;
});
$pp_pic_holder.find('.pp_next, .pp_nav .pp_arrow_next').bind('click',function(){
$.prettyPhoto.changePage('next');
$.prettyPhoto.stopSlideshow();
return false;
});
_center_overlay(); // Center it
};
if(!pp_alreadyInitialized && getHashtag()){
pp_alreadyInitialized = true;
// Grab the rel index to trigger the click on the correct element
hashIndex = getHashtag();
hashRel = hashIndex;
@ -878,26 +878,26 @@
// Useful in the event the page contain several init scripts.
setTimeout(function(){ $("a["+pp_settings.hook+"^='"+hashRel+"']:eq("+hashIndex+")").trigger('click'); },50);
}
return this.unbind('click.prettyphoto').bind('click.prettyphoto',$.prettyPhoto.initialize); // Return the jQuery object for chaining. The unbind method is used to avoid click conflict when the plugin is called more than once
};
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;
};
function setHashtag(){
if(typeof theRel == 'undefined') return; // theRel is set on normal calls, it's impossible to deeplink using the API
location.hash = theRel + '/'+rel_index+'/';
};
function clearHashtag(){
if ( location.href.indexOf('#prettyPhoto') !== -1 ) location.hash = "prettyPhoto";
}
function getParam(name,url){
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
@ -905,7 +905,7 @@
var results = regex.exec( url );
return ( results == null ) ? "" : results[1];
}
})(jQuery);
var pp_alreadyInitialized = false; // Used for the deep linking to make sure not to call the same function several times.
var pp_alreadyInitialized = false; // Used for the deep linking to make sure not to call the same function several times.

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_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
/**
@ -74,7 +79,7 @@ if ( 0 == $woocommerce_loop['loop'] % $woocommerce_loop['columns'] )
*
* @hooked woocommerce_template_loop_add_to_cart - 10
*/
do_action( 'woocommerce_after_shop_loop_item' );
do_action( 'woocommerce_after_shop_loop_item' );
?>

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