Merge remote-tracking branch 'upstream/master'

This commit is contained in:
boohoogal 2014-12-17 18:46:35 +00:00
commit 1987830730
57 changed files with 1138 additions and 218 deletions

View File

@ -1 +1 @@
.woocommerce-message{position:relative;border-left-color:#cc99c2!important;overflow:hidden}.woocommerce-message a.button-primary,p.woocommerce-actions a.button-primary{background:#cc99c2;border-color:#b366a4;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 rgba(0,0,0,.15);color:#fff;text-decoration:none!important}.woocommerce-message a.button-primary:hover,p.woocommerce-actions a.button-primary:hover{background:#bb77ae;border-color:#aa559a;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 rgba(0,0,0,.15)}.woocommerce-message a.button-primary:active,p.woocommerce-actions a.button-primary:active{background:#aa559a;border-color:#aa559a}.woocommerce-message a.docs,.woocommerce-message a.skip,p.woocommerce-actions a.docs,p.woocommerce-actions a.skip{opacity:.7}.woocommerce-message .twitter-share-button,p.woocommerce-actions .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}.woocommerce-about-text,p.woocommerce-actions{margin-bottom:1em!important}
.woocommerce-message{position:relative;border-left-color:#cc99c2!important;overflow:hidden}.woocommerce-message a.button-primary,p.woocommerce-actions a.button-primary{background:#cc99c2;border-color:#b366a4;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 rgba(0,0,0,.15);color:#fff;text-decoration:none!important}.woocommerce-message a.button-primary:hover,p.woocommerce-actions a.button-primary:hover{background:#bb77ae;border-color:#aa559a;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 rgba(0,0,0,.15);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 rgba(0,0,0,.15)}.woocommerce-message a.button-primary:active,p.woocommerce-actions a.button-primary:active{background:#aa559a;border-color:#aa559a}.woocommerce-message a.docs,.woocommerce-message a.skip,p.woocommerce-actions a.docs,p.woocommerce-actions a.skip{opacity:.5}.woocommerce-message a.docs:focus,.woocommerce-message a.docs:hover,.woocommerce-message a.skip:focus,.woocommerce-message a.skip:hover,p.woocommerce-actions a.docs:focus,p.woocommerce-actions a.docs:hover,p.woocommerce-actions a.skip:focus,p.woocommerce-actions a.skip:hover{opacity:1}.woocommerce-message .twitter-share-button,p.woocommerce-actions .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}.woocommerce-about-text,p.woocommerce-actions{margin-bottom:1em!important}

View File

@ -48,7 +48,11 @@ p.woocommerce-actions,
a.skip,
a.docs {
opacity: 0.7;
opacity: 0.5;
&:hover, &:focus {
opacity: 1;
}
}
.twitter-share-button {

File diff suppressed because one or more lines are too long

View File

@ -83,6 +83,26 @@
}
}
}
.storefront {
background: url(../images/storefront-bg.jpg) bottom right #f6f6f6;
border: 1px solid #ddd;
padding: 20px;
overflow: hidden;
zoom: 1;
img {
width: 278px;
height: auto;
float: left;
margin: 0 20px 0 0;
box-shadow: 0 1px 6px rgba(0,0,0,0.1);
}
p {
max-width: 750px;
}
}
}
.woocommerce-message {

File diff suppressed because one or more lines are too long

View File

@ -899,6 +899,7 @@ p.demo_store {
text-indent: -9999px;
position: relative;
border-bottom: 0 !important;
outline: 0;
&:last-child {
border-right: 0;

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,16 @@
jQuery( function ( $ ) {
$( '#webhook-options #topic' ).on( 'change', function() {
var current = $( this ).val(),
action_event_field = $( '#webhook-options .action_event_field' ),
custom_topic_field = $( '#webhook-options .custom_topic_field' );
action_event_field.hide();
custom_topic_field.hide();
if ( 'action' === current ) {
action_event_field.show();
} else if ( 'custom' === current ) {
custom_topic_field.show();
}
}).change();
});

View File

@ -0,0 +1 @@
jQuery(function(a){a("#webhook-options #topic").on("change",function(){var b=a(this).val(),c=a("#webhook-options .action_event_field"),d=a("#webhook-options .custom_topic_field");c.hide(),d.hide(),"action"===b?c.show():"custom"===b&&d.show()}).change()});

View File

@ -83,18 +83,59 @@ jQuery( function( $ ) {
url: wc_checkout_params.ajax_url,
data: data,
success: function( data ) {
// console.log( data );
if ( data && data.fragments ) {
$.each( data.fragments, function( key, value ) {
$( key ).replaceWith( value );
$( key ).unblock();
});
// Remove old errors
$( '.woocommerce-error, .woocommerce-message' ).remove();
// Always update the fragements
if ( data ) {
if ( data.fragments ) {
$.each( data.fragments, function ( key, value ) {
$( key ).replaceWith( value );
$( key ).unblock();
} );
}
$( '.woocommerce-checkout' ).find( 'input[name=payment_method]:checked' ).trigger('click');
$( 'body' ).trigger('updated_checkout' );
}
// Check for error
if ( 'failure' == data.result ) {
var $form = $( 'form.checkout' );
if ( 'true' === data.reload ) {
window.location.reload();
return;
}
// Add new errors
if ( data.messages ) {
$form.prepend( data.messages );
} else {
$form.prepend( data );
}
// 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 click event on selected payment method
$( '.woocommerce-checkout' ).find( 'input[name=payment_method]:checked' ).trigger( 'click' );
// Fire updated_checkout event
$( 'body' ).trigger( 'updated_checkout' );
}
});
}

File diff suppressed because one or more lines are too long

View File

@ -57,31 +57,30 @@ class WC_Product {
* @return mixed
*/
public function __get( $key ) {
$this->$key = get_post_meta( $this->id, '_' . $key, true );
// Get values or default if not set
if ( in_array( $key, array( 'downloadable', 'virtual', 'backorders', 'manage_stock', 'featured', 'sold_individually' ) ) ) {
$value = ( $value = get_post_meta( $this->id, '_' . $key, true ) ) ? $value : 'no';
$this->$key = $this->$key ? $this->$key : 'no';
} elseif ( in_array( $key, array( 'product_attributes', 'crosssell_ids', 'upsell_ids' ) ) ) {
$value = ( $value = get_post_meta( $this->id, '_' . $key, true ) ) ? $value : array();
$this->$key = $this->$key ? $this->$key : array();
} elseif ( 'visibility' == $key ) {
$value = ( $value = get_post_meta( $this->id, '_visibility', true ) ) ? $value : 'hidden';
} elseif ( 'visibility' === $key ) {
$this->$key = $this->$key ? $this->$key : 'hidden';
} elseif ( 'stock' == $key ) {
$value = ( $value = get_post_meta( $this->id, '_stock', true ) ) ? $value : 0;
} elseif ( 'stock' === $key ) {
$this->$key = $this->$key ? $this->$key : 0;
} elseif ( 'stock_status' == $key ) {
$value = ( $value = get_post_meta( $this->id, '_stock_status', true ) ) ? $value : 'instock';
} elseif ( 'stock_status' === $key ) {
$this->$key = $this->$key ? $this->$key : 'instock';
} elseif ( 'tax_status' == $key ) {
$value = ( $value = get_post_meta( $this->id, '_tax_status', true ) ) ? $value : 'taxable';
} elseif ( 'tax_status' === $key ) {
$this->$key = $this->$key ? $this->$key : 'taxable';
} else {
$value = get_post_meta( $this->id, '_' . $key, true );
}
return $value;
return $this->$key;
}
/**

View File

@ -10,7 +10,7 @@ if ( ! defined( 'ABSPATH' ) ) {
* Extended by shipping methods to handle shipping calculations etc.
*
* @class WC_Shipping_Method
* @version 1.6.4
* @version 2.3.0
* @package WooCommerce/Abstracts
* @category Abstract Class
* @author WooThemes
@ -18,43 +18,43 @@ if ( ! defined( 'ABSPATH' ) ) {
abstract class WC_Shipping_Method extends WC_Settings_API {
/** @var string Unique ID for the shipping method - must be set. */
var $id;
public $id;
/** @var int Optional instance ID. */
var $number;
public $number;
/** @var string Method title */
var $method_title;
public $method_title;
/** @var string User set title */
var $title;
public $title;
/** @var bool True if the method is available. */
var $availability;
public $availability;
/** @var array Array of countries this method is enabled for. */
var $countries = array();
public $countries = array();
/** @var string If 'taxable' tax will be charged for this method (if applicable) */
var $tax_status = 'taxable';
public $tax_status = 'taxable';
/** @var mixed Fees for the method */
var $fee = 0;
public $fee = 0;
/** @var float Minimum fee for the method */
var $minimum_fee = null;
public $minimum_fee = null;
/** @var bool Enabled for disabled */
var $enabled = false;
public $enabled = false;
/** @var bool Whether the method has settings or not (In WooCommerce > Settings > Shipping) */
var $has_settings = true;
public $has_settings = true;
/** @var array Features this method supports. */
var $supports = array();
public $supports = array();
/** @var array This is an array of rates - methods must populate this array to register shipping costs */
var $rates = array();
public $rates = array();
/**
* Whether or not we need to calculate tax on top of the shipping rate

View File

@ -196,6 +196,9 @@ class WC_Admin_Assets {
if ( in_array( $screen->id, array( 'shop_coupon', 'edit-shop_coupon' ) ) ) {
wp_enqueue_script( 'wc-admin-coupon-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-coupon' . $suffix . '.js', array( 'wc-admin-meta-boxes' ), WC_VERSION );
}
if ( 'shop_webhook' == $screen->id ) {
wp_enqueue_script( 'wc-admin-webhook-meta-boxes', WC()->plugin_url() . '/assets/js/admin/meta-boxes-webhook' . $suffix . '.js', array( 'jquery' ), WC_VERSION, true );
}
if ( in_array( str_replace( 'edit-', '', $screen->id ), array_merge( array( 'shop_coupon', 'product' ), wc_get_order_types( 'order-meta-boxes' ) ) ) ) {
$params = array(
'remove_item_notice' => __( 'Are you sure you want to remove the selected items? If you have previously reduced this item\'s stock, or this order was submitted by a customer, you will need to manually restore the item\'s stock.', 'woocommerce' ),
@ -224,16 +227,16 @@ class WC_Admin_Assets {
'no_customer_selected' => __( 'No customer selected', 'woocommerce' ),
'plugin_url' => WC()->plugin_url(),
'ajax_url' => admin_url( 'admin-ajax.php' ),
'order_item_nonce' => wp_create_nonce("order-item"),
'add_attribute_nonce' => wp_create_nonce("add-attribute"),
'save_attributes_nonce' => wp_create_nonce("save-attributes"),
'calc_totals_nonce' => wp_create_nonce("calc-totals"),
'get_customer_details_nonce' => wp_create_nonce("get-customer-details"),
'search_products_nonce' => wp_create_nonce("search-products"),
'grant_access_nonce' => wp_create_nonce("grant-access"),
'revoke_access_nonce' => wp_create_nonce("revoke-access"),
'add_order_note_nonce' => wp_create_nonce("add-order-note"),
'delete_order_note_nonce' => wp_create_nonce("delete-order-note"),
'order_item_nonce' => wp_create_nonce( 'order-item' ),
'add_attribute_nonce' => wp_create_nonce( 'add-attribute' ),
'save_attributes_nonce' => wp_create_nonce( 'save-attributes' ),
'calc_totals_nonce' => wp_create_nonce( 'calc-totals' ),
'get_customer_details_nonce' => wp_create_nonce( 'get-customer-details' ),
'search_products_nonce' => wp_create_nonce( 'search-products' ),
'grant_access_nonce' => wp_create_nonce( 'grant-access' ),
'revoke_access_nonce' => wp_create_nonce( 'revoke-access' ),
'add_order_note_nonce' => wp_create_nonce( 'add-order-note' ),
'delete_order_note_nonce' => wp_create_nonce( 'delete-order-note' ),
'calendar_image' => WC()->plugin_url().'/assets/images/calendar.png',
'post_id' => isset( $post->ID ) ? $post->ID : '',
'base_country' => WC()->countries->get_base_country(),

View File

@ -27,6 +27,7 @@ class WC_Admin_Menus {
add_action( 'admin_menu', array( $this, 'admin_menu' ), 9 );
add_action( 'admin_menu', array( $this, 'reports_menu' ), 20 );
add_action( 'admin_menu', array( $this, 'settings_menu' ), 50 );
add_action( 'admin_menu', array( $this, 'webhooks_menu' ), 55 );
add_action( 'admin_menu', array( $this, 'status_menu' ), 60 );
if ( apply_filters( 'woocommerce_show_addons_page', true ) ) {
@ -74,6 +75,15 @@ class WC_Admin_Menus {
add_action( 'load-' . $settings_page, array( $this, 'settings_page_init' ) );
}
/**
* Add webhook item
*/
public function webhooks_menu() {
if ( apply_filters( 'woocommerce_show_webhooks_menu', 'yes' == get_option( 'woocommerce_api_enabled' ) ) ) {
add_submenu_page( 'woocommerce', __( 'Webhooks', 'woocommerce' ), __( 'Webhooks', 'woocommerce' ), 'manage_woocommerce', 'edit.php?post_type=shop_webhook' );
}
}
/**
* Loads gateways and shipping methods into memory for use within settings.
*/
@ -103,7 +113,7 @@ class WC_Admin_Menus {
public function menu_highlight() {
global $menu, $submenu, $parent_file, $submenu_file, $self, $post_type, $taxonomy;
$to_highlight_types = array( 'shop_order', 'shop_coupon' );
$to_highlight_types = array( 'shop_order', 'shop_coupon', 'shop_webhook' );
if ( isset( $post_type ) ) {
if ( in_array( $post_type, $to_highlight_types ) ) {

View File

@ -53,7 +53,10 @@ class WC_Admin_Meta_Boxes {
add_action( 'woocommerce_process_shop_coupon_meta', 'WC_Meta_Box_Coupon_Data::save', 10, 2 );
// Save Rating Meta Boxes
add_action( 'comment_edit_redirect', 'WC_Meta_Box_Order_Reviews::save', 1, 2 );
add_action( 'comment_edit_redirect', 'WC_Meta_Box_Order_Reviews::save', 1, 2 );
// Save Webhook Meta Boxes
add_action( 'woocommerce_process_shop_webhook_meta', 'WC_Meta_Box_Webhook_Data::save', 10 );
// Error handling (for showing errors from meta boxes on next page load)
add_action( 'admin_notices', array( $this, 'output_errors' ) );
@ -107,11 +110,12 @@ class WC_Admin_Meta_Boxes {
// Orders
foreach ( wc_get_order_types( 'order-meta-boxes' ) as $type ) {
add_meta_box( 'woocommerce-order-data', __( 'Order Data', 'woocommerce' ), 'WC_Meta_Box_Order_Data::output', $type, 'normal', 'high' );
add_meta_box( 'woocommerce-order-items', __( 'Order Items', 'woocommerce' ), 'WC_Meta_Box_Order_Items::output', $type, 'normal', 'high' );
add_meta_box( 'woocommerce-order-notes', __( 'Order Notes', 'woocommerce' ), 'WC_Meta_Box_Order_Notes::output', $type, 'side', 'default' );
$order_type_object = get_post_type_object( $type );
add_meta_box( 'woocommerce-order-data', sprintf( __( '%s Data', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Data::output', $type, 'normal', 'high' );
add_meta_box( 'woocommerce-order-items', sprintf( __( '%s Items', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Items::output', $type, 'normal', 'high' );
add_meta_box( 'woocommerce-order-notes', sprintf( __( '%s Notes', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Notes::output', $type, 'side', 'default' );
add_meta_box( 'woocommerce-order-downloads', __( 'Downloadable Product Permissions', 'woocommerce' ) . ' <span class="tips" data-tip="' . __( 'Note: Permissions for order items will automatically be granted when the order status changes to processing/completed.', 'woocommerce' ) . '">[?]</span>', 'WC_Meta_Box_Order_Downloads::output', $type, 'normal', 'default' );
add_meta_box( 'woocommerce-order-actions', __( 'Order Actions', 'woocommerce' ), 'WC_Meta_Box_Order_Actions::output', $type, 'side', 'high' );
add_meta_box( 'woocommerce-order-actions', sprintf( __( '%s Actions', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Actions::output', $type, 'side', 'high' );
}
// Coupons
@ -123,6 +127,11 @@ class WC_Admin_Meta_Boxes {
add_meta_box( 'woocommerce-rating', __( 'Rating', 'woocommerce' ), 'WC_Meta_Box_Order_Reviews::output', 'comment', 'normal', 'high' );
}
}
// Webhook
add_meta_box( 'woocommerce-webhook-data', __( 'Webhook Data', 'woocommerce' ), 'WC_Meta_Box_Webhook_Data::output', 'shop_webhook', 'normal', 'high' );
add_meta_box( 'woocommerce-webhook-actions', __( 'Webhook Actions', 'woocommerce' ), 'WC_Meta_Box_Webhook_Actions::output', 'shop_webhook', 'side', 'high' );
add_meta_box( 'woocommerce-webhook-logs', __( 'Webhook Logs', 'woocommerce' ), 'WC_Meta_Box_Webhook_Logs::output', 'shop_webhook', 'normal', 'low' );
}
/**
@ -137,6 +146,9 @@ class WC_Admin_Meta_Boxes {
remove_meta_box( 'woothemes-settings', 'shop_coupon' , 'normal' );
remove_meta_box( 'commentstatusdiv', 'shop_coupon' , 'normal' );
remove_meta_box( 'slugdiv', 'shop_coupon' , 'normal' );
remove_meta_box( 'submitdiv', 'shop_webhook' , 'side' );
remove_meta_box( 'slugdiv', 'shop_webhook' , 'normal' );
remove_meta_box( 'commentstatusdiv', 'shop_webhook' , 'normal' );
foreach ( wc_get_order_types( 'order-meta-boxes' ) as $type ) {
remove_meta_box( 'commentsdiv', $type, 'normal' );
@ -195,7 +207,7 @@ class WC_Admin_Meta_Boxes {
// Check the post type
if ( in_array( $post->post_type, wc_get_order_types( 'order-meta-boxes' ) ) ) {
do_action( 'woocommerce_process_shop_order_meta', $post_id, $post );
} elseif ( in_array( $post->post_type, array( 'product', 'shop_coupon' ) ) ) {
} elseif ( in_array( $post->post_type, array( 'product', 'shop_coupon', 'shop_webhook' ) ) ) {
do_action( 'woocommerce_process_' . $post->post_type . '_meta', $post_id, $post );
}
}

View File

@ -32,18 +32,23 @@ class WC_Admin_Post_Types {
add_filter( 'manage_edit-product_columns', array( $this, 'product_columns' ) );
add_filter( 'manage_edit-shop_coupon_columns', array( $this, 'shop_coupon_columns' ) );
add_filter( 'manage_edit-shop_order_columns', array( $this, 'shop_order_columns' ) );
add_filter( 'manage_edit-shop_webhook_columns', array( $this, 'shop_webhook_columns' ) );
add_action( 'manage_product_posts_custom_column', array( $this, 'render_product_columns' ), 2 );
add_action( 'manage_shop_coupon_posts_custom_column', array( $this, 'render_shop_coupon_columns' ), 2 );
add_action( 'manage_shop_order_posts_custom_column', array( $this, 'render_shop_order_columns' ), 2 );
add_action( 'manage_shop_webhook_posts_custom_column', array( $this, 'render_shop_webhook_columns' ), 2 );
add_filter( 'manage_edit-product_sortable_columns', array( $this, 'product_sortable_columns' ) );
add_filter( 'manage_edit-shop_coupon_sortable_columns', array( $this, 'shop_coupon_sortable_columns' ) );
add_filter( 'manage_edit-shop_order_sortable_columns', array( $this, 'shop_order_sortable_columns' ) );
add_filter( 'manage_edit-shop_webhook_sortable_columns', array( $this, 'shop_webhook_sortable_columns' ) );
add_filter( 'bulk_actions-edit-shop_order', array( $this, 'shop_order_bulk_actions' ) );
// Views
add_filter( 'views_edit-product', array( $this, 'product_sorting_link' ) );
add_filter( 'views_edit-shop_webhook', array( $this, 'shop_webhook_links' ) );
// Bulk / quick edit
add_action( 'bulk_edit_custom_box', array( $this, 'bulk_edit' ), 10, 2 );
@ -166,6 +171,22 @@ class WC_Admin_Post_Types {
return $columns;
}
/**
* Define custom columns for webhooks
* @param array $existing_columns
* @return array
*/
public function shop_webhook_columns( $existing_columns ) {
$columns = array();
$columns['cb'] = $existing_columns['cb'];
$columns['webhook_name'] = __( 'Name', 'woocommerce' );
$columns['webhook_status'] = __( 'Status', 'woocommerce' );
$columns['webhook_topic'] = __( 'Topic', 'woocommerce' );
$columns['webhook_delivery_url'] = __( 'Delivery URL', 'woocommerce' );
return $columns;
}
/**
* Ouput custom columns for products
* @param string $column
@ -500,7 +521,11 @@ class WC_Admin_Post_Types {
<tr class="<?php echo apply_filters( 'woocommerce_admin_order_item_class', '', $item ); ?>">
<td class="qty"><?php echo absint( $item['qty'] ); ?></td>
<td class="name">
<?php if ( wc_product_sku_enabled() && $_product && $_product->get_sku() ) echo $_product->get_sku() . ' - '; ?><a href="<?php echo get_edit_post_link( $_product->product_id ); ?>" title="<?php echo apply_filters( 'woocommerce_order_item_name', $item['name'], $item ); ?>"><?php echo apply_filters( 'woocommerce_order_item_name', $item['name'], $item ); ?></a>
<?php if ( $_product ) : ?>
<?php echo ( wc_product_sku_enabled() && $_product->get_sku() ) ? $_product->get_sku() . ' - ' : ''; ?><a href="<?php echo get_edit_post_link( $_product->product_id ); ?>" title="<?php echo apply_filters( 'woocommerce_order_item_name', $item['name'], $item ); ?>"><?php echo apply_filters( 'woocommerce_order_item_name', $item['name'], $item ); ?></a>
<?php else : ?>
<?php echo apply_filters( 'woocommerce_order_item_name', $item['name'], $item ); ?>
<?php endif; ?>
<?php if ( $item_meta_html ) : ?>
<a class="tips" href="#" data-tip="<?php echo esc_attr( $item_meta_html ); ?>">[?]</a>
<?php endif; ?>
@ -656,6 +681,75 @@ class WC_Admin_Post_Types {
}
}
/**
* Output custom columns for webhooks
* @param string $column
*/
public function render_shop_webhook_columns( $column ) {
global $post, $the_webhook;
if ( empty( $the_webhook ) || $the_webhook->id != $post->ID ) {
$the_webhook = new WC_Webhook( $post->ID );
}
switch ( $column ) {
case 'webhook_name' :
$edit_link = get_edit_post_link( $the_webhook->id );
$title = _draft_or_post_title();
$post_type_object = get_post_type_object( $post->post_type );
echo '<strong><a href="' . esc_attr( $edit_link ) . '">' . esc_html( $title ) . '</a></strong>';
// Get actions
$actions = array();
if ( current_user_can( $post_type_object->cap->edit_post, $the_webhook->id ) ) {
$actions['edit'] = '<a href="' . admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=edit', $the_webhook->id ) ) . '">' . __( 'Edit', 'woocommerce' ) . '</a>';
}
if ( current_user_can( $post_type_object->cap->delete_post, $the_webhook->id ) ) {
if ( 'trash' == $post->post_status ) {
$actions['untrash'] = "<a title='" . esc_attr( __( 'Restore this item from the Trash', 'woocommerce' ) ) . "' href='" . wp_nonce_url( admin_url( sprintf( $post_type_object->_edit_link . '&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>";
}
if ( 'trash' == $post->post_status || ! EMPTY_TRASH_DAYS ) {
$actions['delete'] = "<a class='submitdelete' title='" . esc_attr( __( 'Delete this item permanently', 'woocommerce' ) ) . "' href='" . get_delete_post_link( $the_webhook->id, '', true ) . "'>" . __( 'Delete Permanently', 'woocommerce' ) . "</a>";
}
}
$actions = apply_filters( 'post_row_actions', $actions, $post );
echo '<div class="row-actions">';
$i = 0;
$action_count = sizeof( $actions );
foreach ( $actions as $action => $link ) {
++$i;
( $i == $action_count ) ? $sep = '' : $sep = ' | ';
echo "<span class='$action'>$link$sep</span>";
}
echo '</div>';
break;
case 'webhook_status' :
echo $the_webhook->get_i18n_status();
break;
case 'webhook_topic' :
echo $the_webhook->get_topic();
break;
case 'webhook_delivery_url' :
echo $the_webhook->get_delivery_url();
break;
default :
break;
}
}
/**
* Make columns sortable - https://gist.github.com/906872
*
@ -699,6 +793,20 @@ class WC_Admin_Post_Types {
return wp_parse_args( $custom, $columns );
}
/**
* Make columns sortable - https://gist.github.com/906872
*
* @param array $columns
* @return array
*/
public function shop_webhook_sortable_columns( $columns ) {
$custom = array(
'webhook_name' => 'title'
);
return $custom;
}
/**
* Remove edit from the bulk actions.
*
@ -738,6 +846,29 @@ class WC_Admin_Post_Types {
return $views;
}
/**
* Webhooks links
*
* @param array $views
* @return array
*/
public function shop_webhook_links( $views ) {
$pattern = '/(shop_webhook\'>| class="current">)(.*?)(<span)/s';
if ( isset( $views['publish'] ) ) {
$views['publish'] = preg_replace( $pattern, '${1}' . __( 'Actived', 'woocommerce' ) . ' ${3}', $views['publish'] );
}
if ( isset( $views['draft'] ) ) {
$views['draft'] = preg_replace( $pattern, '${1}' . __( 'Paused', 'woocommerce' ) . ' ${3}', $views['draft'] );
}
if ( isset( $views['pending'] ) ) {
$views['pending'] = preg_replace( $pattern, '${1}' . __( 'Disabled', 'woocommerce' ) . ' ${3}', $views['pending'] );
}
return $views;
}
/**
* Custom bulk edit - form
@ -944,7 +1075,7 @@ class WC_Admin_Post_Types {
if ( isset( $_REQUEST['_stock_status'] ) ) {
$stock_status = wc_clean( $_REQUEST['_stock_status'] );
if ( ! $product->is_type('variable') ) {
if ( $product->is_type( 'variable' ) ) {
foreach ( $product->get_children() as $child_id ) {
if ( 'yes' !== get_post_meta( $child_id, '_manage_stock', true ) ) {
wc_update_product_stock_status( $child_id, $stock_status );
@ -953,7 +1084,7 @@ class WC_Admin_Post_Types {
WC_Product_Variable::sync_stock_status( $post_id );
} else {
wc_update_product_stock_status( $post_id,$stock_status );
wc_update_product_stock_status( $post_id, $stock_status );
}
}
@ -1016,7 +1147,7 @@ class WC_Admin_Post_Types {
if ( ! empty( $_REQUEST['_stock_status'] ) ) {
$stock_status = wc_clean( $_REQUEST['_stock_status'] );
if ( ! $product->is_type('variable') ) {
if ( $product->is_type( 'variable' ) ) {
foreach ( $product->get_children() as $child_id ) {
if ( 'yes' !== get_post_meta( $child_id, '_manage_stock', true ) ) {
wc_update_product_stock_status( $child_id, $stock_status );
@ -1025,7 +1156,7 @@ class WC_Admin_Post_Types {
WC_Product_Variable::sync_stock_status( $post_id );
} else {
wc_update_product_stock_status( $post_id,$stock_status );
wc_update_product_stock_status( $post_id, $stock_status );
}
}
@ -1282,7 +1413,6 @@ class WC_Admin_Post_Types {
}
}
/**
* Search custom fields as well as content.
* @param WP_Query $wp
@ -1400,18 +1530,12 @@ class WC_Admin_Post_Types {
public function restrict_manage_posts() {
global $typenow, $wp_query;
switch ( $typenow ) {
case 'product' :
$this->product_filters();
break;
case 'shop_coupon' :
$this->shop_coupon_filters();
break;
case 'shop_order' :
$this->shop_order_filters();
break;
default :
break;
if ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ) ) ) {
$this->shop_order_filters();
} elseif ( 'product' == $typenow ) {
$this->product_filters();
} elseif( 'shop_coupon' == $typenow ) {
$this->shop_coupon_filters();
}
}
@ -1594,7 +1718,7 @@ class WC_Admin_Post_Types {
$vars['meta_value'] = wc_clean( $_GET['coupon_type'] );
}
} elseif ( 'shop_order' === $typenow ) {
} elseif ( in_array( $typenow, wc_get_order_types( 'order-meta-boxes' ) ) ) {
// Filter the orders by the posted customer.
if ( isset( $_GET['_customer_user'] ) && $_GET['_customer_user'] > 0 ) {
@ -1748,13 +1872,27 @@ class WC_Admin_Post_Types {
10 => __( 'Coupon draft updated.', 'woocommerce' )
);
$messages['shop_webhook'] = array(
0 => '', // Unused. Messages start at index 1.
1 => __( 'Webhook saved.', 'woocommerce' ),
2 => __( 'Custom field updated.', 'woocommerce' ),
3 => __( 'Custom field deleted.', 'woocommerce' ),
4 => __( 'Webhook saved.', 'woocommerce' ),
5 => '',
6 => __( 'Webhook saved.', 'woocommerce' ),
7 => __( 'Webhook saved.', 'woocommerce' ),
8 => __( 'Webhook saved.', 'woocommerce' ),
9 => '',
10 => __( 'Webhook saved.', 'woocommerce' )
);
return $messages;
}
/**
* Disable the auto-save functionality for Orders.
*/
public function disable_autosave(){
public function disable_autosave() {
global $post;
if ( $post && in_array( get_post_type( $post->ID ), wc_get_order_types( 'order-meta-boxes' ) ) ) {
@ -1831,7 +1969,7 @@ class WC_Admin_Post_Types {
$post_type = get_post_type( $id );
if ( 'shop_order' == $post_type ) {
if ( in_array( $post_type, wc_get_order_types( 'order-count' ) ) ) {
// Delete count - meta doesn't work on trashed posts
$user_id = get_post_meta( $id, '_customer_user', true );
@ -1865,7 +2003,7 @@ class WC_Admin_Post_Types {
$post_type = get_post_type( $id );
if ( 'shop_order' == $post_type ) {
if ( in_array( $post_type, wc_get_order_types( 'order-count' ) ) ) {
// Delete count - meta doesn't work on trashed posts
$user_id = get_post_meta( $id, '_customer_user', true );
@ -1892,7 +2030,7 @@ class WC_Admin_Post_Types {
public function delete_order_items( $postid ) {
global $wpdb;
if ( get_post_type( $postid ) == 'shop_order' ) {
if ( in_array( get_post_type( $postid ), wc_get_order_types() ) ) {
do_action( 'woocommerce_delete_order_items', $postid );
$wpdb->query( "
@ -1948,7 +2086,7 @@ class WC_Admin_Post_Types {
public function change_insert_into_post( $strings ) {
global $post_type;
if ( in_array( $post_type, array( 'product', 'shop_order', 'shop_coupon' ) ) ) {
if ( in_array( $post_type, array( 'product', 'shop_coupon' ) ) || in_array( $post_type, wc_get_order_types() ) ) {
$obj = get_post_type_object( $post_type );
$strings['insertIntoPost'] = sprintf( __( 'Insert into %s', 'woocommerce' ), $obj->labels->singular_name );

View File

@ -23,6 +23,7 @@ class WC_Meta_Box_Order_Actions {
* Output the metabox
*/
public static function output( $post ) {
$order_type_object = get_post_type_object( $post->post_type );
?>
<ul class="order_actions submitbox">
@ -71,7 +72,7 @@ class WC_Meta_Box_Order_Actions {
}
?></div>
<input type="submit" class="button save_order button-primary tips" name="save" value="<?php _e( 'Save Order', 'woocommerce' ); ?>" data-tip="<?php _e( 'Save/update the order', 'woocommerce' ); ?>" />
<input type="submit" class="button save_order button-primary tips" name="save" value="<?php printf( __( 'Save %s', 'woocommerce' ), $order_type_object->labels->singular_name ); ?>" data-tip="<?php printf( __( 'Save/update the %s', 'woocommerce' ), $order_type_object->labels->singular_name ); ?>" />
</li>
<?php do_action( 'woocommerce_order_actions_end', $post->ID ); ?>

View File

@ -24,14 +24,14 @@ class WC_Meta_Box_Order_Data {
*
* @var array
*/
private static $billing_fields = array();
protected static $billing_fields = array();
/**
* Shipping fields
*
* @var array
*/
private static $shipping_fields = array();
protected static $shipping_fields = array();
/**
* Init billing and shipping fields we display + save

View File

@ -58,7 +58,7 @@ class WC_Meta_Box_Order_Notes {
}
} else {
echo '<li>' . __( 'There are no notes for this order yet.', 'woocommerce' ) . '</li>';
echo '<li>' . __( 'There are no notes yet.', 'woocommerce' ) . '</li>';
}
echo '</ul>';

View File

@ -0,0 +1,75 @@
<?php
/**
* Webhook Actions
*
* Display the webhook actions meta box.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Meta Boxes
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* WC_Meta_Box_Webhook_Actions Class
*/
class WC_Meta_Box_Webhook_Actions {
/**
* Get date i18n.
*
* @param string $date
*
* @return string
*/
protected static function get_date_i18n( $date ) {
return date_i18n( __( 'M j, Y @ G:i', 'woocommerce' ), strtotime( $date ) );
}
/**
* Output the metabox
*/
public static function output( $post ) {
?>
<style>
#poststuff #woocommerce-webhook-actions .inside { padding: 0; margin: 0; }
</style>
<?php if ( '0000-00-00 00:00:00' != $post->post_modified_gmt ) : ?>
<ul class="order_actions submitbox">
<?php if ( '0000-00-00 00:00:00' == $post->post_date_gmt ) : ?>
<li class="wide">
<strong><?php _e( 'Created at' ); ?>:</strong> <?php echo self::get_date_i18n( $post->post_modified_gmt ); ?>
</li>
<?php else : ?>
<li class="wide">
<strong><?php _e( 'Created at' ); ?>:</strong> <?php echo self::get_date_i18n( $post->post_date_gmt ); ?>
</li>
<li class="wide">
<strong><?php _e( 'Updated at' ); ?>:</strong> <?php echo self::get_date_i18n( $post->post_modified_gmt ); ?>
</li>
<?php endif; ?>
</ul>
<?php endif; ?>
<div class="submitbox" id="submitpost">
<div id="major-publishing-actions">
<?php if ( current_user_can( 'delete_post', $post->ID ) ) : ?>
<div id="delete-action">
<a class="submitdelete deletion" href="<?php echo esc_url( get_delete_post_link( $post->ID ) ); ?>"><?php echo ( ! EMPTY_TRASH_DAYS ) ? __( 'Delete Permanently', 'woocommerce' ) : __( 'Move to Trash', 'woocommerce' ); ?></a></div>
<?php endif; ?>
<div id="publishing-action">
<span class="spinner"></span>
<input type="submit" class="button button-primary button-large" name="save" id="publish" accesskey="p" value="<?php _e( 'Save Webhook', 'woocommerce' ); ?>" data-tip="<?php _e( 'Save/update the Webhook', 'woocommerce' ); ?>" />
</div>
<div class="clear"></div>
</div>
</div>
<?php
}
}

View File

@ -0,0 +1,297 @@
<?php
/**
* Webhook Data
*
* Display the webhook data meta box.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Meta Boxes
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* WC_Meta_Box_Webhook_Data Class
*/
class WC_Meta_Box_Webhook_Data {
/**
* Get the webhook topic data
*
* @return array
*/
private 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
);
}
/**
* Output the metabox
*/
public static function output( $post ) {
wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
$webhook = new WC_Webhook( $post->ID );
?>
<style>
#post-body-content { display: none; }
</style>
<div id="webhook-options" class="panel woocommerce_options_panel">
<div class="options_group">
<?php
// Name
woocommerce_wp_text_input( array(
'id' => 'name',
'label' => __( 'Name', 'woocommerce' ),
'description' => sprintf( __( 'Friendly name for identifying this webhook, defaults to Webhook created on %s.', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) ),
'desc_tip' => true,
'value' => ( 'auto-draft' == $post->post_status ) ? '' : $webhook->get_name()
) );
?>
</div>
<div class="options_group">
<?php
// Status
woocommerce_wp_select( array(
'id' => 'status',
'label' => __( 'Status', 'woocommerce' ),
'description' => __( 'The options are "Active" (delivers payload), "Paused" (does not deliver), or "Disabled" (does not deliver due delivery failures).', 'woocommerce' ),
'desc_tip' => true,
'options' => wc_get_webhook_statuses(),
'value' => $webhook->get_status()
) );
?>
</div>
<div class="options_group">
<?php
// Topic
$topic_data = self::get_topic_data( $webhook );
woocommerce_wp_select( array(
'id' => 'topic',
'label' => __( 'Topic', 'woocommerce' ),
'description' => __( 'Select when the webhook will fire.', 'woocommerce' ),
'desc_tip' => true,
'options' => array(
'' => __( 'Select an option&hellip;', 'woocommerce' ),
'coupon.created' => __( 'Coupon Created', 'woocommerce' ),
'coupon.updated' => __( 'Coupon Updated', 'woocommerce' ),
'coupon.deleted' => __( 'Coupon Deleted', 'woocommerce' ),
'customer.created' => __( 'Customer Created', 'woocommerce' ),
'customer.updated' => __( 'Customer Updated', 'woocommerce' ),
'customer.deleted' => __( 'Customer Deleted', 'woocommerce' ),
'order.created' => __( 'Order Created', 'woocommerce' ),
'order.updated' => __( 'Order Updated', 'woocommerce' ),
'order.deleted' => __( 'Order Deleted', 'woocommerce' ),
'product.created' => __( 'Product Created', 'woocommerce' ),
'product.updated' => __( 'Product Updated', 'woocommerce' ),
'product.deleted' => __( 'Product Deleted', 'woocommerce' ),
'action' => __( 'Action', 'woocommerce' ),
'custom' => __( 'Custom', 'woocommerce' )
),
'value' => $topic_data['topic']
) );
// Action
woocommerce_wp_text_input( array(
'id' => 'action_event',
'label' => __( 'Action Event', 'woocommerce' ),
'description' => __( 'Enter the Action that will trigger this webhook.', 'woocommerce' ),
'desc_tip' => true,
'value' => $topic_data['event']
) );
// Custom Topic
woocommerce_wp_text_input( array(
'id' => 'custom_topic',
'label' => __( 'Custom Topic', 'woocommerce' ),
'description' => __( 'Enter the Custom Topic that will trigger this webhook.', 'woocommerce' ),
'desc_tip' => true,
'value' => $webhook->get_topic()
) );
?>
</div>
<div class="options_group">
<?php
// Delivery url
woocommerce_wp_text_input( array(
'id' => 'delivery_url',
'label' => __( 'Delivery URL', 'woocommerce' ),
'description' => __( 'URL where the webhook payload is delivered.', 'woocommerce' ),
'data_type' => 'url',
'desc_tip' => true,
'value' => $webhook->get_delivery_url()
) );
?>
</div>
<div class="options_group">
<?php
// Secret
woocommerce_wp_text_input( array(
'id' => 'secret',
'label' => __( 'Secret', 'woocommerce' ),
'description' => __( 'The a Secret Key is used to generate a hash of the delivered webhook and provided in the request headers. This will default to the current API user\'s consumer secret if not provided.', 'woocommerce' ),
'desc_tip' => true,
'value' => $webhook->get_secret()
) );
?>
</div>
<?php do_action( 'woocommerce_webhook_options' ); ?>
<div class="clear"></div>
</div>
<?php
}
/**
* Updated the Webhook name
*
* @param int $post_id
*/
private static function update_name( $post_id ) {
global $wpdb;
$name = ! empty( $_POST['name'] ) ? $_POST['name'] : sprintf( __( 'Webhook created on %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Webhook created on date parsed by strftime', 'woocommerce' ) ) );
$wpdb->update( $wpdb->posts, array( 'post_title' => $name ), array( 'ID' => $post_id ) );
}
/**
* Updated the Webhook status
*
* @param WC_Webhook $webhook
*/
private static function update_status( $webhook ) {
$status = ! empty( $_POST['status'] ) ? wc_clean( $_POST['status'] ) : '';
$webhook->update_status( $status );
}
/**
* Updated the Webhook delivery URL
*
* @param WC_Webhook $webhook
*/
private static function update_delivery_url( $webhook ) {
$delivery_url = ! empty( $_POST['delivery_url'] ) ? $_POST['delivery_url'] : '';
if ( wc_is_valid_url( $delivery_url ) ) {
$webhook->set_delivery_url( $delivery_url );
}
}
/**
* Updated the Webhook secret
*
* @param WC_Webhook $webhook
*/
private static function update_secret( $webhook ) {
$secret = ! empty( $_POST['secret'] ) ? $_POST['secret'] : get_user_meta( get_current_user_id(), 'woocommerce_api_consumer_secret', true );
$webhook->set_secret( $secret );
}
/**
* Updated the Webhook topic
*
* @param WC_Webhook $webhook
*/
private static function update_topic( $webhook ) {
if ( ! empty( $_POST['topic'] ) ) {
list( $resource, $event ) = explode( '.', wc_clean( $_POST['topic'] ) );
if ( 'action' === $resource ) {
$event = ! empty( $_POST['action_event'] ) ? wc_clean( $_POST['action_event'] ) : '';
} else if ( ! in_array( $resource, array( 'coupon', 'customer', 'order', 'product' ) ) && ! empty( $_POST['custom_topic'] ) ) {
list( $resource, $event ) = explode( '.', wc_clean( $_POST['custom_topic'] ) );
}
$topic = $resource . '.' . $event;
if ( wc_is_webhook_valid_topic( $topic ) ) {
$webhook->set_topic( $topic );
}
}
}
/**
* Set Webhook post data.
*
* @param int $post_id
*/
private static function set_post_data( $post_id ) {
global $wpdb;
$password = uniqid( 'webhook_' );
$password = strlen( $password ) > 20 ? substr( $password, 0, 20 ) : $password;
$wpdb->update(
$wpdb->posts,
array(
'post_password' => $password,
'ping_status' => 'closed',
'comment_status' => 'open'
),
array( 'ID' => $post_id )
);
}
/**
* Save meta box data
*/
public static function save( $post_id ) {
$webhook = new WC_Webhook( $post_id );
// Name
self::update_name( $post_id );
// Status
self::update_status( $webhook );
// Delivery URL
self::update_delivery_url( $webhook );
// Secret
self::update_secret( $webhook );
// Topic
self::update_topic( $webhook );
// Webhook Created
if ( isset( $_POST['original_post_status'] ) && 'auto-draft' === $_POST['original_post_status'] ) {
// Set Post data like ping status and password
self::set_post_data( $post_id );
// Ping webhook
$webhook->deliver_ping();
}
do_action( 'woocommerce_webhook_options_save', $post_id );
}
}

View File

@ -0,0 +1,97 @@
<?php
/**
* Webhook Logs
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Meta Boxes
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* WC_Meta_Box_Webhook_Logs Class
*/
class WC_Meta_Box_Webhook_Logs {
/**
* Log quantity
*
* @var int
*/
public static $quantity = 10;
/**
* Output the metabox
*/
public static function output( $post ) {
$webhook = new WC_Webhook( $post->ID );
$current = isset( $_GET['log_page'] ) ? absint( $_GET['log_page'] ) : 1;
$args = array(
'post_id' => $webhook->id,
'status' => 'approve',
'type' => 'webhook_delivery',
'number' => self::$quantity
);
if ( 1 < $current ) {
$args['offset'] = ( $current - 1 ) * self::$quantity;
}
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>';
}
}
/**
* Get the logs navigation.
*
* @param int $total
*
* @return string
*/
public static function get_navigation( $total ) {
global $post;
$pages = ceil( $total / self::$quantity );
$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( 'post.php?post=' . $post->ID . '&action=edit&log_page=' . ( $current - 1 ) ) . '">' . __( '&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( 'post.php?post=' . $post->ID . '&action=edit&log_page=' . ( $current + 1 ) ) . '">' . __( 'Next &rsaquo;', 'woocommerce' ) . '</a>';
}
$html .= '</p>';
}
$html .= '<div class="clear"></div></div>';
return $html;
}
}

View File

@ -52,9 +52,7 @@ if ( ! defined( 'ABSPATH' ) ) {
foreach ( $order_taxes as $tax_item ) :
$tax_item_id = $tax_item['rate_id'];
$tax_item_total = isset( $tax_data['total'][ $tax_item_id ] ) ? $tax_data['total'][ $tax_item_id ] : '';
?>
<td class="line_tax" width="1%">
<div class="view">
<?php
@ -66,10 +64,10 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
</div>
<div class="edit" style="display: none;">
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo absint( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" />
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" />
</div>
<div class="refund" style="display: none;">
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo absint( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo absint( $tax_item_id ); ?>" />
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
</div>
</td>

View File

@ -248,14 +248,14 @@ if ( ! defined( 'ABSPATH' ) ) {
<div class="edit" style="display: none;">
<div class="split-input">
<?php $item_total_tax = ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo absint( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo $item_total_tax; ?>" class="line_tax wc_input_price tips" data-tip="<?php _e( 'After pre-tax discounts.', 'woocommerce' ); ?>" data-total_tax="<?php echo $item_total_tax; ?>" />
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo $item_total_tax; ?>" class="line_tax wc_input_price tips" data-tip="<?php _e( 'After pre-tax discounts.', 'woocommerce' ); ?>" data-total_tax="<?php echo $item_total_tax; ?>" />
<?php $item_subtotal_tax = ( isset( $tax_item_subtotal ) ) ? esc_attr( wc_format_localized_price( $tax_item_subtotal ) ) : ''; ?>
<input type="text" name="line_subtotal_tax[<?php echo absint( $item_id ); ?>][<?php echo absint( $tax_item_id ); ?>]" value="<?php echo $item_subtotal_tax; ?>" class="line_subtotal_tax wc_input_price tips" data-tip="<?php _e( 'Before pre-tax discounts.', 'woocommerce' ); ?>"data-subtotal_tax="<?php echo $item_subtotal_tax; ?>" />
<input type="text" name="line_subtotal_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" value="<?php echo $item_subtotal_tax; ?>" class="line_subtotal_tax wc_input_price tips" data-tip="<?php _e( 'Before pre-tax discounts.', 'woocommerce' ); ?>"data-subtotal_tax="<?php echo $item_subtotal_tax; ?>" />
</div>
</div>
<div class="refund" style="display: none;">
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo absint( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo absint( $tax_item_id ); ?>" />
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
</div>
</td>
<?php

View File

@ -76,9 +76,7 @@ if ( ! defined( 'ABSPATH' ) ) {
foreach ( $order_taxes as $tax_item ) :
$tax_item_id = $tax_item['rate_id'];
$tax_item_total = isset( $tax_data[ $tax_item_id ] ) ? $tax_data[ $tax_item_id ] : '';
?>
<td class="line_tax" width="1%">
<div class="view">
<?php
@ -90,10 +88,10 @@ if ( ! defined( 'ABSPATH' ) ) {
?>
</div>
<div class="edit" style="display: none;">
<input type="text" name="shipping_taxes[<?php echo absint( $item_id ); ?>][<?php echo absint( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" />
<input type="text" name="shipping_taxes[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" value="<?php echo ( isset( $tax_item_total ) ) ? esc_attr( wc_format_localized_price( $tax_item_total ) ) : ''; ?>" class="line_tax wc_input_price" />
</div>
<div class="refund" style="display: none;">
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo absint( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo absint( $tax_item_id ); ?>" />
<input type="text" name="refund_line_tax[<?php echo absint( $item_id ); ?>][<?php echo esc_attr( $tax_item_id ); ?>]" placeholder="<?php echo wc_format_localized_price( 0 ); ?>" class="refund_line_tax wc_input_price" data-tax_id="<?php echo esc_attr( $tax_item_id ); ?>" />
</div>
</td>

View File

@ -0,0 +1,37 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
?>
<tr>
<td><?php echo date_i18n( __( 'M j, Y @ G:i', 'woocommerce' ), strtotime( $log['comment']->comment_date_gmt ), true ); ?></td>
<td><?php echo esc_attr( $log['duration'] ); ?></td>
<td>
<p><strong><?php _e( 'Method', 'woocommerce' ); ?>: </strong><?php echo esc_html( $log['request_method'] ); ?></p>
<p><strong><?php _e( 'Duration', 'woocommerce' ); ?>: </strong><?php echo esc_html( $log['request_url'] ); ?></p>
<p><strong><?php _e( 'Headers', 'woocommerce' ); ?>:</strong></p>
<ul>
<?php foreach ( $log['request_headers'] as $key => $value ) : ?>
<li><strong><em><?php echo strtolower( esc_html( $key ) ); ?>: </em></strong><code><?php echo esc_html( $value ); ?></code></li>
<?php endforeach ?>
</ul>
<p><strong><?php _e( 'Content', 'woocommerce' ); ?>: </strong></p>
<pre><code><?php echo esc_html( $log['request_body'] ); ?></code></pre>
</td>
<td>
<p><strong><?php _e( 'Status', 'woocommerce' ); ?>: </strong><?php echo esc_html( $log['summary'] ); ?></p>
<p><strong><?php _e( 'Headers', 'woocommerce' ); ?>:</strong></p>
<ul>
<?php foreach ( $log['response_headers'] as $key => $value ) : ?>
<li><strong><em><?php echo strtolower( esc_html( $key ) ); ?>: </em></strong><code><?php echo esc_html( $value ); ?></code></li>
<?php endforeach ?>
</ul>
<?php if ( ! empty( $log['response_body'] ) ) : ?>
<h4><?php _e( 'Content', 'woocommerce' ); ?>:</h4>
<p><?php echo esc_html( $log['response_body'] ); ?></p>
<?php endif; ?>
</td>
</tr>

View File

@ -0,0 +1,42 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
$count_comments = wp_count_comments( $webhook->id );
$total = $count_comments->approved;
?>
<?php echo WC_Meta_Box_Webhook_Logs::get_navigation( $total ); ?>
<table id="webhook-logs" class="widefat">
<thead>
<tr>
<th><?php _e( 'Date', 'woocommerce' ); ?></th>
<th><?php _e( 'URL', 'woocommerce' ); ?></th>
<th><?php _e( 'Request', 'woocommerce' ); ?></th>
<th><?php _e( 'Response', 'woocommerce' ); ?></th>
</tr>
</thead>
<tfoot>
<tr>
<th><?php _e( 'Date', 'woocommerce' ); ?></th>
<th><?php _e( 'URL', 'woocommerce' ); ?></th>
<th><?php _e( 'Request', 'woocommerce' ); ?></th>
<th><?php _e( 'Response', 'woocommerce' ); ?></th>
</tr>
</tfoot>
<tbody>
<?php
foreach ( $logs as $log ) {
$log = $webhook->get_delivery_log( $log->comment_ID );
include( 'html-webhook-log.php' );
}
?>
</tbody>
</table>
<?php echo WC_Meta_Box_Webhook_Logs::get_navigation( $total ); ?>

View File

@ -201,11 +201,13 @@ class WC_Settings_Emails extends WC_Settings_Page {
WC_Admin_Settings::save_fields( $settings );
} else {
// Init email classes
WC()->mailer()->init();
if ( class_exists( $current_section ) ) {
$current_section_class = new $current_section();
do_action( 'woocommerce_update_options_' . $this->id . '_' . $current_section_class->id );
WC()->mailer()->init();
} else {
do_action( 'woocommerce_update_options_' . $this->id . '_' . $current_section );
}

View File

@ -8,7 +8,8 @@ if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
$view = isset( $_GET['view'] ) ? sanitize_text_field( $_GET['view'] ) : '';
$view = isset( $_GET['view'] ) ? sanitize_text_field( $_GET['view'] ) : '';
$theme = wp_get_theme();
?>
@ -17,7 +18,6 @@ $view = isset( $_GET['view'] ) ? sanitize_text_field( $_GET['view'] ) : '';
<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/product-category/themes/woocommerce/" class="add-new-h2"><?php _e( 'Browse themes', 'woocommerce' ); ?></a>
</h2>
<?php if ( $addons ) : ?>
<ul class="subsubsub">
@ -93,4 +93,27 @@ $view = isset( $_GET['view'] ) ? sanitize_text_field( $_GET['view'] ) : '';
<?php else : ?>
<p><?php printf( __( 'Our catalog of WooCommerce Extensions can be found on WooThemes.com here: <a href="%s">WooCommerce Extensions Catalog</a>', 'woocommerce' ), 'http://www.woothemes.com/product-category/woocommerce-extensions/' ); ?></p>
<?php endif; ?>
<?php if ( 'Storefront' != $theme['Name'] ) : ?>
<div class="storefront">
<img src="<?php echo WC()->plugin_url(); ?>/assets/images/storefront.jpg" alt="Storefront" />
<h3><?php _e( 'Looking for a WooCommerce theme?', 'woocommerce' ); ?></h3>
<p>
<?php printf( __( 'We recommend Storefront, the %sofficial%s WooCommerce theme.', 'woocommerce' ), '<em>', '</em>' ); ?>
</p>
<p>
<?php printf( __( 'Storefront is an intuitive &amp; flexible, %sfree%s WordPress theme offering deep integration with WooCommerce and many of the most popular customer-facing extensions.', 'woocommerce' ), '<strong>', '</strong>' ); ?>
</p>
<p>
<a href="<?php echo esc_url( 'http://www.woothemes.com/storefront/' ); ?>" class="button">Read all about it</a>
<a href="<?php echo esc_url( wp_nonce_url( self_admin_url( 'update.php?action=install-theme&theme=storefront' ), 'install-theme_storefront' ) ); ?>" class="button button-primary"><?php _e( 'Download & install', 'woocommerce' ); ?></a>
</p>
</div>
<?php endif; ?>
</div>

View File

@ -11,5 +11,5 @@ if ( ! defined( 'ABSPATH' ) ) {
<div id="message" class="updated woocommerce-message wc-connect">
<p><?php _e( '<strong>Welcome to WooCommerce</strong> &#8211; You\'re almost ready to start selling :)', 'woocommerce' ); ?></p>
<p class="submit"><a href="<?php echo add_query_arg( 'install_woocommerce_pages', 'true', admin_url( 'admin.php?page=wc-settings' ) ); ?>" class="button-primary"><?php _e( 'Install WooCommerce Pages', 'woocommerce' ); ?></a> <a class="skip button-primary" href="<?php echo add_query_arg( 'skip_install_woocommerce_pages', 'true', admin_url( 'admin.php?page=wc-settings' ) ); ?>"><?php _e( 'Skip setup', 'woocommerce' ); ?></a></p>
<p class="submit"><a href="<?php echo add_query_arg( 'install_woocommerce_pages', 'true', admin_url( 'admin.php?page=wc-settings' ) ); ?>" class="button-primary"><?php _e( 'Install WooCommerce Pages', 'woocommerce' ); ?></a> <a class="skip button" href="<?php echo add_query_arg( 'skip_install_woocommerce_pages', 'true', admin_url( 'admin.php?page=wc-settings' ) ); ?>"><?php _e( 'Skip setup', 'woocommerce' ); ?></a></p>
</div>

View File

@ -35,6 +35,8 @@ function wc_get_screen_ids() {
'edit-product_tag',
'edit-product_shipping_class',
'profile',
'shop_webhook',
'edit-shop_webhook'
);
foreach ( wc_get_order_types() as $type ) {

View File

@ -42,6 +42,10 @@ function woocommerce_wp_text_input( $field ) {
$field['class'] .= ' wc_input_stock';
$field['value'] = wc_stock_amount( $field['value'] );
break;
case 'url' :
$field['class'] .= ' wc_input_url';
$field['value'] = esc_url( $field['value'] );
break;
default :
break;

View File

@ -201,9 +201,17 @@ class WC_API_Orders extends WC_API_Resource {
);
// add line items
foreach( $order->get_items() as $item_id => $item ) {
foreach ( $order->get_items() as $item_id => $item ) {
$product = $order->get_product_from_item( $item );
$product = $order->get_product_from_item( $item );
$product_id = null;
$product_sku = null;
// Check if the product exists.
if ( is_object( $product ) ) {
$product_id = ( isset( $product->variation_id ) ) ? $product->variation_id : $product->id;
$product_sku = $product->get_sku();
}
$meta = new WC_Order_Item_Meta( $item['item_meta'], $product );
@ -229,8 +237,8 @@ class WC_API_Orders extends WC_API_Resource {
'quantity' => (int) $item['qty'],
'tax_class' => ( ! empty( $item['tax_class'] ) ) ? $item['tax_class'] : null,
'name' => $item['name'],
'product_id' => ( isset( $product->variation_id ) ) ? $product->variation_id : $product->id,
'sku' => is_object( $product ) ? $product->get_sku() : null,
'product_id' => $product_id,
'sku' => $product_sku,
'meta' => $item_meta,
);
}
@ -440,7 +448,7 @@ class WC_API_Orders extends WC_API_Resource {
wc_delete_shop_order_transients( $order->id );
do_action( 'woocommerce_api_create_order', $order->id, $data );
do_action( 'woocommerce_api_create_order', $order->id, $data, $this );
return $this->get_order( $order->id );
@ -592,7 +600,7 @@ class WC_API_Orders extends WC_API_Resource {
wc_delete_shop_order_transients( $order->id );
do_action( 'woocommerce_api_edit_order', $order->id, $data );
do_action( 'woocommerce_api_edit_order', $order->id, $data, $this );
return $this->get_order( $id );

View File

@ -173,12 +173,12 @@ class WC_API_Webhooks extends WC_API_Resource {
$data = apply_filters( 'woocommerce_api_create_webhook_data', $data, $this );
// validate topic
if ( empty( $data['topic'] ) || ! $this->is_valid_topic( strtolower( $data['topic'] ) ) ) {
if ( empty( $data['topic'] ) || ! wc_is_webhook_valid_topic( strtolower( $data['topic'] ) ) ) {
throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_topic', __( 'Webhook topic is required and must be valid', 'woocommerce' ), 400 );
}
// validate delivery URL
if ( empty( $data['delivery_url'] ) || ! $this->is_valid_url( $data['delivery_url'] ) ) {
if ( empty( $data['delivery_url'] ) || ! wc_is_valid_url( $data['delivery_url'] ) ) {
throw new WC_API_Exception( 'woocommerce_api_invalid_webhook_delivery_url', __( 'Webhook delivery URL must be a valid URL starting with http:// or https://', 'woocommerce' ), 400 );
}
@ -249,7 +249,7 @@ class WC_API_Webhooks extends WC_API_Resource {
// update topic
if ( ! empty( $data['topic'] ) ) {
if ( $this->is_valid_topic( strtolower( $data['topic'] ) ) ) {
if ( wc_is_webhook_valid_topic( strtolower( $data['topic'] ) ) ) {
$webhook->set_topic( $data['topic'] );
@ -260,7 +260,7 @@ class WC_API_Webhooks extends WC_API_Resource {
// update delivery URL
if ( ! empty( $data['delivery_url'] ) ) {
if ( $this->is_valid_url( $data['delivery_url'] ) ) {
if ( wc_is_valid_url( $data['delivery_url'] ) ) {
$webhook->set_delivery_url( $data['delivery_url'] );
@ -303,63 +303,6 @@ class WC_API_Webhooks extends WC_API_Resource {
}
}
/**
* Check if the given topic is a valid webhook topic, a topic is valid if:
*
* + starts with `action.woocommerce_` or `action.wc_`
* + it has a valid resource & event
*
* @since 2.2
* @param string $topic webhook topic
* @return bool true if valid, false otherwise
*/
private function is_valid_topic( $topic ) {
// custom topics are prefixed with woocommerce_ or wc_ are valid
if ( 0 === strpos( $topic, 'action.woocommerce_' ) || 0 === strpos( $topic, 'action.wc_' ) ) {
return true;
}
@list( $resource, $event ) = explode( '.', $topic );
if ( ! isset( $resource ) || ! isset( $event ) ) {
return false;
}
$valid_resources = apply_filters( 'woocommerce_valid_webhook_resources', array( 'coupon', 'customer', 'order', 'product' ) );
$valid_events = apply_filters( 'woocommerce_valid_webhook_events', array( 'created', 'updated', 'deleted' ) );
if ( in_array( $resource, $valid_resources ) && in_array( $event, $valid_events ) ) {
return true;
}
return false;
}
/**
* Simple check for validating a URL, it must start with http:// or https://
* and pass FILTER_VALIDATE_URL validation
*
* @since 2.2
* @param string $url delivery URL for the webhook
* @return bool true if valid, false otherwise
*/
private function is_valid_url( $url ) {
// must start with http:// or https://
if ( 0 !== strpos( $url, 'http://' ) && 0 !== strpos( $url, 'https://' ) ) {
return false;
}
// must pass validation
if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
return false;
}
return true;
}
/**
* Delete a webhook
*

View File

@ -286,15 +286,28 @@ class WC_AJAX {
WC()->cart->calculate_totals();
// Get order review fragment
ob_start();
woocommerce_order_review();
$woocommerce_order_review = ob_get_clean();
// Get checkout payment fragement
ob_start();
woocommerce_checkout_payment();
$woocommerce_checkout_payment = ob_get_clean();
// Get messages if reload checkout is not true
$messages = '';
if ( ! isset( WC()->session->reload_checkout ) ) {
ob_start();
wc_print_notices();
$messages = ob_get_clean();
}
$data = array(
'result' => empty( $messages ) ? 'success' : 'failure',
'messages' => $messages,
'reload' => isset( WC()->session->reload_checkout ) ? 'true' : 'false',
'fragments' => apply_filters( 'woocommerce_update_order_review_fragments', array(
'.woocommerce-checkout-review-order-table' => $woocommerce_order_review,
'.woocommerce-checkout-payment' => $woocommerce_checkout_payment
@ -1063,7 +1076,7 @@ class WC_AJAX {
$order_id = absint( $_POST['order_id'] );
$rate_id = absint( $_POST['rate_id'] );
$order = new WC_Order( $order_id );
$order = wc_get_order( $order_id );
$data = get_post_meta( $order_id );
// Add new tax
@ -1109,7 +1122,7 @@ class WC_AJAX {
wc_delete_order_item( $rate_id );
// Return HTML items
$order = new WC_Order( $order_id );
$order = wc_get_order( $order_id );
$data = get_post_meta( $order_id );
include( 'admin/meta-boxes/views/html-order-items.php' );
@ -1375,7 +1388,7 @@ class WC_AJAX {
wc_save_order_items( $order_id, $items );
// Return HTML items
$order = new WC_Order( $order_id );
$order = wc_get_order( $order_id );
$data = get_post_meta( $order_id );
include( 'admin/meta-boxes/views/html-order-items.php' );
@ -1399,7 +1412,7 @@ class WC_AJAX {
wc_save_order_items( $order_id, $items );
// Return HTML items
$order = new WC_Order( $order_id );
$order = wc_get_order( $order_id );
$data = get_post_meta( $order_id );
include( 'admin/meta-boxes/views/html-order-items.php' );
}
@ -1415,7 +1428,7 @@ class WC_AJAX {
// Return HTML items
$order_id = absint( $_POST['order_id'] );
$order = new WC_Order( $order_id );
$order = wc_get_order( $order_id );
$data = get_post_meta( $order_id );
include( 'admin/meta-boxes/views/html-order-items.php' );

View File

@ -121,6 +121,9 @@ class WC_Cart {
_deprecated_argument( 'WC_Cart->tax', '2.3', 'Use WC_Tax:: directly' );
$this->tax = new WC_Tax();
return $this->tax;
case 'discount_total':
_deprecated_argument( 'WC_Cart->discount_total', '2.3', 'After tax coupons are no longer supported. For more information see: http://develop.woothemes.com/woocommerce/2014/12/upcoming-coupon-changes-in-woocommerce-2-3/' );
return 0;
}
}
@ -1310,7 +1313,7 @@ class WC_Cart {
// Allow plugins to hook and alter totals before final total is calculated
do_action( 'woocommerce_calculate_totals', $this );
// Grand Total - Discounted product prices, discounted tax, shipping cost + tax, and any discounts to be added after tax (e.g. store credit)
// Grand Total - Discounted product prices, discounted tax, shipping cost + tax
$this->total = max( 0, apply_filters( 'woocommerce_calculated_total', round( $this->cart_contents_total + $this->tax_total + $this->shipping_tax_total + $this->shipping_total + $this->fee_total, $this->dp ), $this ) );
} else {

View File

@ -43,7 +43,7 @@ class WC_HTTPS {
add_filter( 'page_link', array( __CLASS__, 'force_https_page_link' ), 10, 2 );
add_action( 'template_redirect', array( __CLASS__, 'force_https_template_redirect' ) );
if ( 'yes' == get_option('woocommerce_unforce_ssl_checkout') ) {
if ( 'yes' == get_option( 'woocommerce_unforce_ssl_checkout' ) ) {
add_action( 'template_redirect', array( __CLASS__, 'unforce_https_template_redirect' ) );
}
}
@ -75,7 +75,7 @@ class WC_HTTPS {
public static function force_https_page_link( $link, $page_id ) {
if ( in_array( $page_id, array( get_option( 'woocommerce_checkout_page_id' ), get_option( 'woocommerce_myaccount_page_id' ) ) ) ) {
$link = str_replace( 'http:', 'https:', $link );
} elseif ( get_option('woocommerce_unforce_ssl_checkout') == 'yes' ) {
} elseif ( 'yes' == get_option( 'woocommerce_unforce_ssl_checkout' ) ) {
$link = str_replace( 'https:', 'http:', $link );
}
return $link;
@ -101,6 +101,10 @@ class WC_HTTPS {
* Template redirect - if we end up on a page ensure it has the correct http/https url
*/
public static function unforce_https_template_redirect() {
if ( function_exists( 'is_customize_preview' ) && is_customize_preview() ) {
return;
}
if ( is_ssl() && $_SERVER['REQUEST_URI'] && ! is_checkout() && ! is_ajax() && ! is_account_page() && apply_filters( 'woocommerce_unforce_ssl_checkout', true ) ) {
if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) {

View File

@ -5,15 +5,15 @@
* Loads Integrations into WooCommerce.
*
* @class WC_Integrations
* @version 2.0.0
* @version 2.3.0
* @package WooCommerce/Classes/Integrations
* @category Class
* @author WooThemes
*/
class WC_Integrations {
/** @var array Array of integration classes */
var $integrations = array();
/** Array of integration classes */
public $integrations = array();
/**
* __construct function.

View File

@ -366,9 +366,24 @@ class WC_Post_types {
register_post_type( 'shop_webhook',
apply_filters( 'woocommerce_register_post_type_shop_webhook',
array(
'label' => __( 'Webhooks', 'woocommerce' ),
'labels' => array(
'name' => __( 'Webhooks', 'woocommerce' ),
'singular_name' => __( 'Webhook', 'woocommerce' ),
'menu_name' => _x( 'Webhooks', 'Admin menu name', 'woocommerce' ),
'add_new' => __( 'Add Webhook', 'woocommerce' ),
'add_new_item' => __( 'Add New Webhook', 'woocommerce' ),
'edit' => __( 'Edit', 'woocommerce' ),
'edit_item' => __( 'Edit Webhook', 'woocommerce' ),
'new_item' => __( 'New Webhook', 'woocommerce' ),
'view' => __( 'View Webhooks', 'woocommerce' ),
'view_item' => __( 'View Webhook', 'woocommerce' ),
'search_items' => __( 'Search Webhooks', 'woocommerce' ),
'not_found' => __( 'No Webhooks found', 'woocommerce' ),
'not_found_in_trash' => __( 'No Webhooks found in trash', 'woocommerce' ),
'parent' => __( 'Parent Webhook', 'woocommerce' )
),
'public' => false,
'show_ui' => false,
'show_ui' => true,
'capability_type' => 'shop_webhook',
'map_meta_cap' => true,
'publicly_queryable' => false,
@ -379,7 +394,7 @@ class WC_Post_types {
'query_var' => false,
'supports' => false,
'show_in_nav_menus' => false,
'show_in_admin_bar' => false,
'show_in_admin_bar' => false
)
)
);

View File

@ -5,7 +5,7 @@
* Handles shipping and loads shipping methods via hooks.
*
* @class WC_Shipping
* @version 1.6.4
* @version 2.3.0
* @package WooCommerce/Classes/Shipping
* @category Class
* @author WooThemes
@ -18,22 +18,22 @@ if ( ! defined( 'ABSPATH' ) ) {
class WC_Shipping {
/** @var bool True if shipping is enabled. */
var $enabled = false;
public $enabled = false;
/** @var array Stores methods loaded into woocommerce. */
var $shipping_methods = array();
public $shipping_methods = array();
/** @var float Stores the cost of shipping */
var $shipping_total = 0;
public $shipping_total = 0;
/** @var array Stores an array of shipping taxes. */
var $shipping_taxes = array();
public $shipping_taxes = array();
/** @var array Stores the shipping classes. */
var $shipping_classes = array();
public $shipping_classes = array();
/** @var array Stores packages to ship and to get quotes for. */
var $packages = array();
public $packages = array();
/**
* @var WC_Shipping The single instance of the class

View File

@ -83,9 +83,13 @@ class WC_Webhook {
* @since 2.2
*/
public function enqueue() {
$hooks = $this->get_hooks();
$url = $this->get_delivery_url();
foreach ( $this->get_hooks() as $hook ) {
add_action( $hook, array( $this, 'process' ) );
if ( is_array( $hooks ) && ! empty( $url ) ) {
foreach ( $hooks as $hook ) {
add_action( $hook, array( $this, 'process' ) );
}
}
}
@ -629,6 +633,18 @@ class WC_Webhook {
return apply_filters( 'woocommerce_webhook_status', $status, $this->id );
}
/**
* Get the webhook i18n status
*
* @return string
*/
public function get_i18n_status() {
$status = $this->get_status();
$statuses = wc_get_webhook_statuses();
return isset( $statuses[ $status ] ) ? $statuses[ $status ] : $status;
}
/**
* Update the webhook status, see get_status() for valid statuses
*
@ -636,26 +652,28 @@ class WC_Webhook {
* @param $status
*/
public function update_status( $status ) {
global $wpdb;
switch ( $status ) {
case 'active':
case 'active' :
$post_status = 'publish';
break;
case 'paused':
case 'paused' :
$post_status = 'draft';
break;
case 'disabled':
case 'disabled' :
$post_status = 'pending';
break;
default:
default :
$post_status = 'draft';
break;
}
wp_update_post( array( 'ID' => $this->id, 'post_status' => $post_status ) );
$wpdb->update( $wpdb->posts, array( 'post_status' => $post_status ), array( 'ID' => $this->id ) );
}
/**

View File

@ -12,15 +12,15 @@ if ( ! class_exists( 'WC_Email_Customer_Invoice' ) ) :
* An email sent to the customer via admin.
*
* @class WC_Email_Customer_Invoice
* @version 2.0.0
* @version 2.3.0
* @package WooCommerce/Classes/Emails
* @author WooThemes
* @extends WC_Email
*/
class WC_Email_Customer_Invoice extends WC_Email {
var $find;
var $replace;
public $find;
public $replace;
/**
* Constructor

View File

@ -12,16 +12,16 @@ if ( ! class_exists( 'WC_Email_Customer_New_Account' ) ) :
* An email sent to the customer when they create an account.
*
* @class WC_Email_Customer_New_Account
* @version 2.0.0
* @version 2.3.0
* @package WooCommerce/Classes/Emails
* @author WooThemes
* @extends WC_Email
*/
class WC_Email_Customer_New_Account extends WC_Email {
var $user_login;
var $user_email;
var $user_pass;
public $user_login;
public $user_email;
public $user_pass;
/**
* Constructor

View File

@ -12,14 +12,14 @@ if ( ! class_exists( 'WC_Email_Customer_Note' ) ) :
* Customer note emails are sent when you add a note to an order.
*
* @class WC_Email_Customer_Note
* @version 2.0.0
* @version 2.3.0
* @package WooCommerce/Classes/Emails
* @author WooThemes
* @extends WC_Email
*/
class WC_Email_Customer_Note extends WC_Email {
var $customer_note;
public $customer_note;
/**
* Constructor

View File

@ -12,7 +12,7 @@ if ( ! class_exists( 'WC_Email_Customer_Reset_Password' ) ) :
* An email sent to the customer when they reset their password.
*
* @class WC_Email_Customer_Reset_Password
* @version 2.0.0
* @version 2.3.0
* @package WooCommerce/Classes/Emails
* @author WooThemes
* @extends WC_Email
@ -20,13 +20,13 @@ if ( ! class_exists( 'WC_Email_Customer_Reset_Password' ) ) :
class WC_Email_Customer_Reset_Password extends WC_Email {
/** @var string */
var $user_login;
public $user_login;
/** @var string */
var $user_email;
public $user_email;
/** @var string */
var $reset_key;
public $reset_key;
/**
* Constructor

View File

@ -4,19 +4,20 @@ if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( ! class_exists( 'WC_Shipping_International_Delivery' ) ) :
/**
* International Shipping Method based on Flat Rate shipping
*
* A simple shipping method for a flat fee per item or per order.
*
* @class WC_Shipping_International_Delivery
* @version 2.0.0
* @version 2.3.0
* @package WooCommerce/Classes/Shipping
* @author WooThemes
*/
class WC_Shipping_International_Delivery extends WC_Shipping_Flat_Rate {
var $id = 'international_delivery';
public $id = 'international_delivery';
/**
* __construct function.
@ -211,3 +212,5 @@ class WC_Shipping_International_Delivery extends WC_Shipping_Flat_Rate {
}
}
endif;

View File

@ -280,7 +280,7 @@ class WC_Shortcode_My_Account {
$wpdb->update( $wpdb->users, array( 'user_activation_key' => $hashed ), array( 'user_login' => $user_login ) );
// Send email notification
$mailer = WC()->mailer();
WC()->mailer(); // load email classes
do_action( 'woocommerce_reset_password_notification', $user_login, $key );
wc_add_notice( __( 'Check your e-mail for the confirmation link.', 'woocommerce' ) );

View File

@ -13,10 +13,12 @@ if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( ! class_exists( 'WC_Product_Cat_Dropdown_Walker' ) ) :
class WC_Product_Cat_Dropdown_Walker extends Walker {
var $tree_type = 'category';
var $db_fields = array ('parent' => 'parent', 'id' => 'term_id', 'slug' => 'slug' );
public $tree_type = 'category';
public $db_fields = array ('parent' => 'parent', 'id' => 'term_id', 'slug' => 'slug' );
/**
* @see Walker::start_el()
@ -79,3 +81,5 @@ class WC_Product_Cat_Dropdown_Walker extends Walker {
parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
}
endif;

View File

@ -4,7 +4,7 @@
*
* @extends Walker
* @class WC_Product_Cat_Dropdown_Walker
* @version 1.6.4
* @version 2.3.0
* @package WooCommerce/Classes/Walkers
* @author WooThemes
*/
@ -13,10 +13,12 @@ if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( ! class_exists( 'WC_Product_Cat_List_Walker' ) ) :
class WC_Product_Cat_List_Walker extends Walker {
var $tree_type = 'product_cat';
var $db_fields = array ( 'parent' => 'parent', 'id' => 'term_id', 'slug' => 'slug' );
public $tree_type = 'product_cat';
public $db_fields = array ( 'parent' => 'parent', 'id' => 'term_id', 'slug' => 'slug' );
/**
* @see Walker::start_lvl()
@ -119,3 +121,5 @@ class WC_Product_Cat_List_Walker extends Walker {
parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
}
endif;

View File

@ -326,3 +326,58 @@ if ( ! function_exists( 'wc_prices_include_tax' ) ) {
return get_option( 'woocommerce_prices_include_tax' ) === 'yes';
}
}
/**
* Check if the given topic is a valid webhook topic, a topic is valid if:
*
* + starts with `action.woocommerce_` or `action.wc_`
* + it has a valid resource & event
*
* @param string $topic webhook topic
* @return bool true if valid, false otherwise
*/
function wc_is_webhook_valid_topic( $topic ) {
// custom topics are prefixed with woocommerce_ or wc_ are valid
if ( 0 === strpos( $topic, 'action.woocommerce_' ) || 0 === strpos( $topic, 'action.wc_' ) ) {
return true;
}
@list( $resource, $event ) = explode( '.', $topic );
if ( ! isset( $resource ) || ! isset( $event ) ) {
return false;
}
$valid_resources = apply_filters( 'woocommerce_valid_webhook_resources', array( 'coupon', 'customer', 'order', 'product' ) );
$valid_events = apply_filters( 'woocommerce_valid_webhook_events', array( 'created', 'updated', 'deleted' ) );
if ( in_array( $resource, $valid_resources ) && in_array( $event, $valid_events ) ) {
return true;
}
return false;
}
/**
* Simple check for validating a URL, it must start with http:// or https://
* and pass FILTER_VALIDATE_URL validation
*
* @param string $url
* @return bool
*/
function wc_is_valid_url( $url ) {
// must start with http:// or https://
if ( 0 !== strpos( $url, 'http://' ) && 0 !== strpos( $url, 'https://' ) ) {
return false;
}
// must pass validation
if ( ! filter_var( $url, FILTER_VALIDATE_URL ) ) {
return false;
}
return true;
}

View File

@ -661,7 +661,7 @@ add_filter( 'mod_rewrite_rules', 'wc_ms_protect_download_rewite_rules' );
* @return array
*/
function wc_get_core_supported_themes() {
return array( 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' );
return array( 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' );
}
/**

View File

@ -0,0 +1,27 @@
<?php
/**
* WooCommerce Webhook functions.
*
* @author WooThemes
* @category Core
* @package WooCommerce/Functions
* @version 2.3.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Get Webhook statuses
*
* @since 2.3.0
* @return array
*/
function wc_get_webhook_statuses() {
return apply_filters( 'woocommerce_webhook_statuses', array(
'active' => __( 'Active', 'woocommerce' ),
'paused' => __( 'Paused', 'woocommerce' ),
'disabled' => __( 'Disabled', 'woocommerce' ),
) );
}

View File

@ -147,6 +147,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
* Refactor - Improved the Shipping Class field in products quick edit and bulk edit.
* Refactor - Removed style settings in favour of separate plugin.
* Refactor - Removed quantity increment/decrement buttons in favour of separate plugin.
* Feature - Added link on purchased products list on orders screen.
* Fix - When 'hide out of stock products' is disabled, out of stock variations / attributes are now visible.
* Tweak - Double the default product image dimensions.
* Tweak - Added refunds to Sales by Date report.

View File

@ -118,7 +118,7 @@ class WC_Tests_Core_Functions extends WC_Unit_Test_Case {
*/
public function test_wc_get_core_supported_themes() {
$expected_themes = array( 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' );
$expected_themes = array( 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' );
$this->assertEquals( $expected_themes, wc_get_core_supported_themes() );
}

View File

@ -200,6 +200,7 @@ final class WooCommerce {
include_once( 'includes/class-wc-autoloader.php' );
include_once( 'includes/wc-core-functions.php' );
include_once( 'includes/wc-widget-functions.php' );
include_once( 'includes/wc-webhook-functions.php' );
include_once( 'includes/class-wc-install.php' );
include_once( 'includes/class-wc-download-handler.php' );
include_once( 'includes/class-wc-comments.php' );